Moin,
Vorab: Jeder der programmieren kann, wird zurecht den Kopf schütteln. Darauf soll es bitte nicht ankommen.
Es ist etwas ausführlicher geworden als erwartet. Zum verstehen was passiert hilft es mir jedoch immer, das Programm möglichst weit zu zerlegen.
Abkürzen überlass ich lieber Denjenigen, die es können.
das macht meist nix, denn der prinzipielle Aufbau ist nahezu immer gleich.
Daher keinen Kopf machen, wie das exakt aussehen muss, das kann man googlen.
Den Rest versteht man imo auch, wenn man mit Excel arbeitet und ein paar Formeln erstellt hat.
Man muss sich dabei nur klar werden, dass man sich in keiner Zelle mehr befindet.
Frei wie man also ist, muss du dir klar sein, dass du keinen Ausgangspunkt hast. Keine Zelle, nicht mal ein Arbeitsblatt.
Nur eine Arbeitsanweisung die abgearbeitet wird.
Und (ganz wichtig) der Arbeiter ist stur und dumm. Es wird exakt das gemacht, was im Programm steht und sei es noch so dämlich.
Dim
überspringen wir, das fällt unter lästige Pflicht und ist nur dazu da um alt
, b
und i
als Variablen nutzen zu dürfen.
Hier eine kurze Theorie: 1 ist nicht die erste Zahl beim Zählen, sondern 0.
Ebenso sollte man im Hinterkopf behalten, dass 0 damit eine Zahl ist die einen Wert hat - der eben 0 ist.
Dann der Objektmist. Im Grunde kennst du das auch aus Excel. Wir fangen bei der Zeile hinten an:
ThisComponent.Sheets(0).getCellByPosition(0,0).value
also .value
Da holst du dir mit A1 den Wert der Zelle.
In der Tabelle selbst genügt es, die Zelle mit A1 anzusprechen und es wird direkt der Wert zurück gegeben (weil mehr eben nicht geht).
In VBA reicht das nicht. Hier muss explizit angegeben werden, dass man den Wert möchte. Daneben gibt es zB. noch .formula was die Formel der Zelle liefert und auch die Farben und Schriftarten, -größen müssen irgendwie ansprechbar sein.
Das nur zum groben Verständnis, warum .value
nötig ist…
Zurück zum Wert der Zelle. Davor muss die Zelle also ausgewählt werden.
.getCellByPosition(0,0)
Erklärung erübrigt sich vermutlich. Zelle bei der Position 0,0. Wie gesagt: A ist nicht 1 sondern 0. Daraus folgt dann leider auch, dass Zeile 1 an der Position 0 liegt.
Gewöhnt man sich irgendwann dran.
Will man das umgehen, könnte man die Zelle auch anders ansprechen, etwa mit .getCellByName("A1")
Wäre bei dem Problem jetzt egal, sieht aber nicht so schön aus und wir würden das Thema noch um den Umgang mit Text erweitern.
.Sheet(0)
erklärt sich vermutlich auch von selbst. 0 ist wieder das erste Blatt.
ThisComponent
ist eben das aktuelle Dokument.
Daraus ergibt sich dann: alt = in dem Dokument, im Blatt 1, in Zelle 0,0 den Wert
Nun haben wir das Datum (als Zahl 44562) in der Variablen alt hinterlegt.
For
- gibt es immer und überall. Lernt man schnell, weil man es braucht.
for i = 1 to 400
kann man auch normal lesen: von 1 bis 400 mach das…
b = ThisComponent.Sheets(0).getCellByPosition(0,i).value
Nächste Zeile kennen wir schon, b bekommt also den Wert von A2 (weil i = 1 ist, und damit 0,1 der Zelle A2 entspricht)
if b<>0 then
Schönes Beispiel dafür, dass es kein Problem ist, wenn man VBA nicht kann.
ich durfte hier lernen, dass VBA mit != nicht klar kommt, und dass mit end if
abgeschlossen wird.
Excelangelehnt ist das nichts weiter als wenn(das, dann, sonst)
Es wird also nur geprüft, ob b nicht 0 ist, was einer leeren Zelle entsprechen würde.
Was bei WENN() die Klammer, ist bei IF-Then-Else das End If
Wir befinden uns also weiterhin innerhalb.
(Das kann je nach Programmiersprache anders aussehen, das Prinzip bleibt aber gleich.)
if alt+1<b then
Es wird geprüft, ob das erste Datum was in alt
abgelegt ist plus einen Tag kleiner ist, als das Datum der aktuellen Zelle in b
.
Wenn das so wäre, fehlt mindestens Tag.
Fehlt mindestens ein Tag, muss also eine leere Zeile rein.
ThisComponent.Sheets(0).Rows.insertByIndex(Position, Anzahl)
ich denke, das erklärt sich auch fast von selbst.
Die Position der Zeile kennen wir, das ist gleich der Variablen i.
Die Anzahl kennen wir auch, die ermittelt sich auch der Differenz beider Datumsangaben abzüglich 1 - logisch, um 1 muss das Datum ja steigen.
Übersichtlicher weise mal nur die Tage:
Zwischen dem 22. aus Zelle A2 und dem 20. aus A1 fehlt also 1 Tag. (22-20-1)
Dann das erste End if
zum schließen der IF-Anweisung
Damit sind wir wieder innerhalb der Ersten und soweit fertig.
Wir weisen das aktuell geprüfte Datum nun der Variablen alt
zu, um den nächsten Durchlauf vorzubereiten.
Der Inhalt von A2 steht nun in alt
Else
anders als bei Wenn(Bedingung,then,else) ist das optional und bezieht sich auf die Prüfung ob b<>0 ist.
wenn b also 0 war und kein Datum enthält, zählen wir eben in Kopf weiter.
Der Wert von alt wird um eins erhöht.
alt ist also alt + 1
Danach ist auch diese IF-Geschichte zu Ende und es wurde erfolgreich eine Zeile, oder mehrere wenn nötig, eingefügt.
Next i
wir springen wieder hoch in die For-Schleife. Dabei erhöht sich i um 1
i ist nun also 2.
Ausgelesen und in b abgelegt wird daher der Wert der Zelle an Position 0,2 - Was A3 entspricht. alt haben wir bereits angepasst und den Wert aus A2 zugewiesen.
Und so läuft das nun die 400 oder 800 mal durch.
(Hat mich jedoch selbst gestört, bevor ich es wieder gelöscht hab, ist das noch ne hübschere while-Schleife geworden.)
Wenn das Prinzip klar ist, ist es imo egal, ob man VBA oder C++ kann oder eben nicht.
Es dauert nur länger, es wird sicher auch komplizierter als nötig und man muss Google öfter bemühen.
Hat man aber eine grobe Ahnung was man sucht, dann findet man auch eine Lösung - nur vielleicht nicht die Optimale.
Bei sowas ist dann oft der Weg das Ziel.
grüße
lipi