Fortlaufende Nummerierung neuer Dateien

  • Hallo Leute,

    ich beschäftige mich seit ein paar Tagen mit dem Programmieren (AutoIt). Habe mich schon durch zahlreiche Threads und Youtube-Videos gestöbert und konnte auch schon erste Probleme eigenständig lösen.
    Ich möchte gerne für den privaten Gebrauch sowie für die Arbeit, gewisse Prozesse automatisieren.

    So, jetzt ist Schluss mit Off-Topic und ab zum eigentlichen Problem.

    Im Prinzip möchte ich mit einer Variable die Anzahl der Vorgänge bei fortlaufender Nummerierung realisieren.

    Die Anzahl der Vorgänge klappt schon mal, jedoch spuckt es jedesmal eine 0 als Wert heraus.

    MfG Andy

  • Hallo AK-IT !

    "Willkommen im Forum" ;)

    Zu Deinem Skript :

    Es ist schon etwas spät um eine 'überarbeitete' Version zu posten, vorab aber schon mal soviel :

    Die Func ZaehlerDateien() ist in der akt. Form 'nutzlos' (-> auskommentiert). Die automatisch deklarierte Laufvariable $i sollte im globalen Gültigkeitsbereich besser vermieden werden.

    Mache es mal so :

    Gruß Musashi

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

    2 Mal editiert, zuletzt von Musashi (29. April 2019 um 08:06)

  • Hallo Musashi,

    ohne auf deine Lösung zurückzugreifen, habe ich heute morgen das Problem tatsächslich selber gelöst.:party1:

    Und welchen Hintergrund hat es eigentlich, auf die Laufvariable $i zu verzichten?

    MfG

    Andy

  • Und welchen Hintergrund hat es eigentlich, auf die Laufvariable $i zu verzichten?

    Du zählst bereits in der Schleife von $i = 1 bis $iAnzahlSeiten, wozu dann noch eine zweite Variable einführen die genau dasselbe zählt? Verwende doch lieber die die schon existiert.

    Deine Funktion würde in ZaehlerDateien $i von 1 bis $iAnzahlSeiten hochzählen und 0 zurückgeben (weil du nichts returnst).

    Du rufst also eine Funktion aus die 10x eine Schleife hochzählt und 0 zurückgibt, mehr nicht. Außerdem ist $i in deiner Funktion in einem lokalen Scope, d.h. wenn du dort $i beschreibst, hat das keine Auswirkungen auf das $i das außerhalb der Funktion existiert.

    Wenn du innerhalb einer Funktion den Zähler haben möchtest muss deine Funktion den Zähler zurückgeben und bei jedem Aufruf um eins erhöhen.

    So etwa:

    Code
    ConsoleWrite(ZaehlerDateien() & @CRLF)
    ConsoleWrite(ZaehlerDateien() & @CRLF)
    
    Func ZaehlerDateien()
        Local Static $iCounter = 0 ;Static bedeutet, initialisiere $iCounter innerhalb der Funktion einmal und behalte den Wert für den nächsten Aufruf der Funktion bei.
    
        $iCounter += 1
        Return $iCounter
    EndFunc
  • ohne auf deine Lösung zurückzugreifen, habe ich heute morgen das Problem tatsächlich selber gelöst. :party1:

    Die ersten Erfolge sind immer die Besten :P

    Und welchen Hintergrund hat es eigentlich, auf die Laufvariable $i zu verzichten?

    Das wurde bereits häufiger diskutiert - hier mal eine schöne Erläuterung (mit Beispiel) von Bitnugger :

    BitOperations64

    Stichwort :

    Eine Sache sollte man sich unbedingt abgewöhnen... For...Next-Schleifen im globalen Kontext!

    Gruß Musashi

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Eine Sache sollte man sich unbedingt abgewöhnen... For...Next-Schleifen im globalen Kontext!

    Das kann ich so nicht stehen lassen.

    Ich verwende die sehr häufig wenn es bspw. darum geht Events zu setzen.

    Code
    Global $aSettingsGUI_Settings[11]
    Global $hSettingsGUI_SettingsTV = GUICtrlCreateTreeView(8, 8, 137, 369, -1, $WS_EX_CLIENTEDGE)
    $aSettingsGUI_Settings[0] = GUICtrlCreateTreeViewItem("Users", $hSettingsGUI_SettingsTV)
    $aSettingsGUI_Settings[1] = GUICtrlCreateTreeViewItem("General", $hSettingsGUI_SettingsTV)
    ;...
    
    For $i = 0 To UBound($aSettingsGUI_Settings) - 1
        GUICtrlSetOnEvent($aSettingsGUI_Settings[$i], _SettingsGUI_LoadPage)
    Next

    Schreibt man kleinere Skripte die keine wirklichen Programme sind (Makros oder dergleichen) ist das ebenfalls gut nutzbar.

    Den Fehler den Bitnugger anspricht ist einfach selbst geschuldet, da man nicht Variablen referenzieren darf die vorher nicht explizit auf dem aktuellen Pfad deklariert wurden.

    Ich schreibe bei jeder Deklaration immer das Scope davor um ganz sicher zu gehen, dass ich auch die Variable anspreche die ich möchte.

    Setze ich im If- und Else-Zweig eine Variable, so definiere ich sie vorher mit Local $vVar und setze sie nachträglich mit $vVar = 1337.42.

    Niemals definiere ich sie im If-Zweig und verwende sie im Scope darüber (was bei Ifs in AutoIt ambivalent wäre, "Level" trifft es eher).

    Des Weiteren sollten UDF-interne Variablen immer mit einem Präfix versehen sein wenn sie global verwendet werden.

  • Zu : Zitat Musashi

    "Eine Sache sollte man sich unbedingt abgewöhnen... For...Next-Schleifen im globalen Kontext!"

    Das kann ich so nicht stehen lassen.

    Die Aussage bezog sich auf den o.a. Link und wurde von mir wohl etwas stark verkürzt ;).

    An For...Next-Schleifen im globalen Kontext gibt es grundsätzlich natürlich nichts auszusetzen. Im Folgebeitrag hatte ich den Punkt ausführlicher beschrieben, Auszug :

    Zitat von Musashi

    Die Laufvariable $i in einer For...Next-Schleife ist ja nicht deklarationspflichtig bzw. gilt automatisch als deklariert, selbst bei Opt('MustDeclareVars', 1) .

    (ich vermute mal, das war ursprünglich ein Bequemlichkeitsfeature)

    Man könnte die angesprochene Gefahr bannen, indem man eine passende Notation wählt, also z.B. : Global $__g_Counter

    Gruß Musashi

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Die Aussage bezog sich auf den o.a. Link und wurde von mir wohl etwas stark verkürzt ;) .

    Den Fehler den Bitnugger anspricht ist einfach selbst geschuldet, da man nicht Variablen referenzieren darf die vorher nicht explizit auf dem aktuellen Pfad deklariert wurden.

    Ich schreibe bei jeder Deklaration immer das Scope davor um ganz sicher zu gehen, dass ich auch die Variable anspreche die ich möchte.


    Setze ich im If- und Else-Zweig eine Variable, so definiere ich sie vorher mit Local $vVar und setze sie nachträglich mit $vVar = 1337.42.

    Niemals definiere ich sie im If-Zweig und verwende sie im Scope darüber (was bei Ifs in AutoIt ambivalent wäre, "Level" trifft es eher).

    Das ist mir schon klar, allerdings ist sowas sehr leicht umgehbar wenn man nicht mit inkonsistenten Deklarationen um sich wirft.

    Antrainierbar ist das ganze, verzichtet man gänzlich darauf Variablen ohne explizite Deklaration zu nutzen tritt das Problem überhaupt nicht auf.

    Wenn ich auf eine Variable zugreife schaue ich erstmal nach ob sie existiert (global/lokal) und deklariere sie wenn nötig vorher.

    • Offizieller Beitrag
    Zitat von Muashi

    Die Laufvariable $i in einer For...Next-Schleife ist ja nicht deklarationspflichtig bzw. gilt automatisch als deklariert, selbst bei Opt('MustDeclareVars', 1) .

    (ich vermute mal, das war ursprünglich ein Bequemlichkeitsfeature)

    Nein, keine Bequemlichkeit. Zählervariablen werden üblicherweise durch Verwendung deklariert, da sie unabdingbarer Bestandteil der Schleife sind. In anderen Sprachen existiert i.A. die Zählervariable aber auch nur innerhalb der Schleife, in AutoIt lebt sie weiter. Das erscheint manchmal ganz praktisch, da ich z.B. bei Verlassen der Schleife durch bestimmte Bedingung, den Wert des Zählers bei Gültigkeit dieser Bedingung sofort greifbar habe ohne ihn einer vorab deklarierten Variablen zuweisen zu müssen. Das kann aber durchaus auch zu Fehlern führen (bedingte Ausführung von Schleifen in einem Level).

  • Ich denke, wir sind alle der gleichen Meinung - daher möchte ich das Thema nicht überstrapazieren.

    Den Knackpunkt bzgl. Zählervariablen hat BugFix ja beschrieben (Auszug) :

    Zählervariablen werden üblicherweise durch Verwendung deklariert, da sie unabdingbarer Bestandteil der Schleife sind. In anderen Sprachen existiert i.A. die Zählervariable aber auch nur innerhalb der Schleife, in AutoIt lebt sie weiter. ...

    Das kann zu Fehlern führen (bedingte Ausführung von Schleifen in einem Level).

    AK-IT :

    Wie alpines bereits schrieb, lassen sich viele Probleme durch saubere Deklarationen minimieren.

    Dabei hilft es, z.B. Opt('MustDeclareVars', 1) an den Anfang eines Skriptes zu setzen.

    Lesenswert ist auch : Best_coding_practices

    Je früher man sich das angewöhnt/antrainiert, desto schneller wird es zu einem Automatismus ;).

    Gruß Musashi

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Hier mal ein "auf die Schnelle geschriebenes" Beispiel, das zeigt, warum ich dazu rate, Laufvariablen nicht im globalen Kontext zu benutzen.

    Code: _Laufvariablen.au3
    #include-once
    
    For $iCount = 1 To Random(1, 256, 1) Step 1
    Next

    Der Fehler kann nur in einem der Includes stecken... aber in welchem der ca. 50 Includes wurde $iCount als globale Variable deklariert?

    Einmal editiert, zuletzt von Bitnugger (29. April 2019 um 15:45)

  • Hier mal ein "auf die Schnelle geschriebenes" Beispiel, das zeigt, warum ich dazu rate, Laufvariablen nicht im globalen Kontext zu benutzen.

    Dazu schrieb ich bereits:

    Den Fehler den Bitnugger anspricht ist einfach selbst geschuldet, da man nicht Variablen referenzieren darf die vorher nicht explizit auf dem aktuellen Pfad deklariert wurden.

    Ich schreibe bei jeder Deklaration immer das Scope davor um ganz sicher zu gehen, dass ich auch die Variable anspreche die ich möchte.

    Des Weiteren sollten UDF-interne Variablen immer mit einem Präfix versehen sein wenn sie global verwendet werden.

    Dein Beispiel ist auch nicht ganz sauber, du implizierst, ohne es zu sagen, dass $iCount > 0 sein muss.

    If UBound($aFiles) Then $iCount = $aFiles[0]

    Das ist aber Quatsch. Wenn ich in einen Codepfad laufe indem UBound($aFiles) > 0 ist, so ist $iCount von mir gesetzt worden - alles ok.

    Laufe ich allerdings in einen Codepfad in wo UBound($aFiles) = 0 ist, so stehen mir nur zwei Optionen zur Verfügung:

    1. Ich verzichte komplett auf $iCount und füge überall manuell 0 ein, bzw. spucke eine Fehlermeldung aus, dass es nicht geklappt hat weil keine Daten selektiert worden sind.
    2. Ich nutze $iCount so ähnlich wie im Pfad als ob Daten da wären. Allerdings würde ich hier nicht wie du $iCount nur setzen wenn UBound($aFiles) > 0 ist, sondern würde lieber das ganze mit dem ternären Operatoren vorher lösen, sprich $iCount = UBound($aFiles) ? $aFiles[0] : 0.

    Deine Prämisse $iCount nur zu setzen wenn UBound($aFiles) > 0 ist, ist schlecht, da du den anderen Codezweig nicht abdeckst.

    Außerdem kann man bei dem Beispiel direkt anders argumentieren:

    Ich bin mir bewusst, dass du hier nur einen Punkt illustrieren möchtest und auf die schnelle ein Beispiel gesucht hast, jedoch ist der Zugriff auf den 0-Index nicht von Nöten (das Thema hatten wir ja schon oft genug hier) wenn man direkt mit UBound arbeitet. Dann kann dieser Fehler überhaupt nicht auftreten.

  • Das hat Ak bestimmt alles verstanden :rofl:

    Hinweise auf Suchmaschinen finde ich überflüssig - wer fragt hat es nicht gefunden oder nicht verstanden. Die Antwort gibt sich oftmals schneller als der Hinweis auf Dr. Goggle & Co.

    Ab 19-10-22 ergänzt um:

    Die Welt wird nicht bedroht von den Menschen, die böse sind, sondern von denen, die das Böse zulassen. (Albert Einstein)

  • Das hat Ak bestimmt alles verstanden :rofl:

    Momentan vermutlich (noch) nicht ;).

    Aus der Einleitung :

    ich beschäftige mich seit ein paar Tagen mit dem Programmieren (AutoIt). Habe mich schon durch zahlreiche Threads und Youtube-Videos gestöbert und konnte auch schon erste Probleme eigenständig lösen. Ich möchte gerne für den privaten Gebrauch sowie für die Arbeit, gewisse Prozesse automatisieren.

    lese ich aber den ernsthaften Wunsch heraus, seinen Horizont zu erweitern. User, die lediglich ein TK-Fertiggericht wollen, fragen sicher anders.

    Daher auch der Hinweis :

    Wie alpines bereits schrieb, lassen sich viele Probleme durch saubere Deklarationen minimieren.

    Dabei hilft es, z.B. Opt('MustDeclareVars', 1) an den Anfang eines Skriptes zu setzen.

    Lesenswert ist auch : Best_coding_practices

    Je früher man sich das angewöhnt/antrainiert, desto schneller wird es zum Automatismus ;) .

    Gerade in der Einstiegsphase schleichen sich ja häufig die Unsitten ein, die man später nur schwer wieder los wird :P.

    Gruß Musashi

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Wer noch einen drauf legen will, fügt anstelle Opt('MustDeclareVars', 1) folgende Zeile ein:

    #AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7

  • Wer noch einen drauf legen will, fügt anstelle Opt('MustDeclareVars', 1) folgende Zeile ein:

    #AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7

    Auf diese 'Hardcore-Variante' hast Du ja schon häufiger hingewiesen. Ich habe Deinen Vorschlag nun beherzigt und setze sie bei größeren Skripten ein ;).

    Auf Opt('MustDeclareVars', 1) kann man dann, wie Du geschrieben hast, verzichten, dass erledigt das Flag : -d : setzt die "MustDeclareVars"-Option auf True

    Den Parameter :

    -w 5 : Warnung, falls eine lokale Variable deklariert aber nicht verwendet wird

    lasse ich in der Entwicklungsphase allerdings weg. Gerade bei größeren Projekten ist es nicht unüblich, benötigte Variablen zu deklarieren ohne sie auch gleich zu verwenden.

    Es werden zwar nur Warnungen - keine Errors - ausgegeben, aber das kann etwas nerven. Zum Ende eines Projektes kann man mit -w 5 dann die 'Leichen' entfernen :P.

    Gruß Musashi

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Das hat Ak bestimmt alles verstanden :rofl:

    Mit Sicherheit nicht. :)

    So sieht es aus. Ich denke für den Einsteig ist AutoIT das richtige für mich.

    @All Danke für eure schnelle Hilfe. :)

  • Ich hau dir jetzt schon mal auf die Finger damit sich das nicht wiederholt, es heißt AutoIt, nicht "AutoIT" ;)

    Verdammt, jetzt bin ich selber drauf reingefallen. :D

    Dabei habe ich das so oft in den anderen Threads gelesen, wie es richtig heißt.

  • Verdammt, jetzt bin ich selber drauf reingefallen. :D

    Dabei habe ich das so oft in den anderen Threads gelesen, wie es richtig heißt.

    Wenn man sich AK-IT nennt und zudem im IT-Bereich bewegt, ist der Lapsus sicher entschuldbar;).

    Was mir fehlt, ist der berühmte Hinweis von alpines "den Haken zu setzen", also das Thema als 'Erledigt' zu kennzeichnen :P. AK-IT : Das kannst Du als Threadersteller übrigens selbst machen.

    Gruß Musashi

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."