Optimierung Umbenennungstool

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

User avatar
Meister Lampe
Posts: 228
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

28 May 2020, 16:48

Hallo just me!

Also ich hatte das schon einmal getestet und die Variablen auch jetzt nochmal mithilfe des Codes, den Du mir gegeben hast, verglichen. Die eine bleibt zuerst leer, da es sich bei "ZaehlArt" und "ZahlArtAuswahl" um zwei unterschiedliche Variablen für dieselbe Sache handelt. Die erste wird intern benutzt und zum Abspeichern in der Tabelle. Die zweite ist die Auswahl in der DropDownList. In der Subroutine VorlagenDefinieren werden die beiden dann synchronisiert und auf die interne Variable gleichgesetzt. Ich habe in den Vergleich bei der Eingabe jetzt also ZahlArtAuswahl hineingesetzt:

Code: Select all

; Neue Vorlage abspeichern
Neuerstellen:
Gui, Submit, NoHide  ; Speichert die Benutzereingaben für eine neue Vorlage
; AktSignEingabe darf nicht leer sein
AktSignEingabe := Trim(AktSignEingabe)
If (StrLen(AktSignEingabe) = 0)
{
   MsgBox, 16, Fehler!, Der Bestandsname darf nicht leer sein!
   GuiControl, Focus, AktSignEingabe
   Return
}
; AktSignEingabe darf nicht bereits vergeben sein
Loop, % LV_GetCount()
{
   LV_GetText(AktSignLV, A_Index, 1)
   LV_GetText(ZaehlArtLV, A_Index, 4)
   ;~ MsgBox, "%AktSignEingabe%" <-> "%AktSignLV%"`n"%ZaehlArtAuswahl%" <-> "%ZaehlArtLV%" " / " "Neu Erstellen"
   If (AktSignEingabe = AktSignLV and ZaehlArtAuswahl = ZaehlArtLV)
   {
      MsgBox, 16, Fehler!, Die Vorlage ist bereits vergeben!
      GuiControl, Focus, AktSignEingabe
      Return
   }
}
; SignEingabe darf nicht leer sein
SignEingabe := Trim(SignEingabe)
If (StrLen(SignEingabe) = 0)
{
   MsgBox, 16, Fehler!, Die Signaturvorgabe darf nicht leer sein!
   GuiControl, Focus, SignEingabe
   Return
}
; IndexEingabe darf nicht leer sein
IndexEingabe := Trim(IndexEingabe)
If (StrLen(IndexEingabe) = 0 and ZaehlArtAuswahl <> "ohne Indizes")
{
   MsgBox, 16, Fehler!, Die Indexvorgabe darf nur bei der Auswahl "ohne Indizes" leer sein!`nWählen Sie eine andere Auswahl oder füllen Sie das Indexfeld!
   GuiControl, Focus, IndexEingabe
   Return
}

; Alles OK, verarbeiten
AktSignNeu := AktSignEingabe
StellenSignNeu := StrLen(SignEingabe)
StellenIndexNeu := StrLen(IndexEingabe)

Gosub, VorlagenDefinieren
   
FileAppend , `n%AktSignNeu%`t%SignVorlage%`t%IndexVorlage%`t%ZaehlArt%, %VorgabenDatei%

; Auswahldatei updaten
;~ AuswahlNeu = %AktSignNeu%`t%ZaehlArtauswahl%
;~ If !(AuswahlNeu = Auswahl)
;~ {
   ;~ Auswahl := AuswahlNeu
   ;~ File := FileOpen(AuswahlDatei, "w")
   ;~ File.Write(AuswahlNeu)
   ;~ File.Close()
;~ }

If (AktSignNeu <> AuswahlSP1 or ZaehlArt <> AuswahlSP4)
{
   AuswahlSP1 := AktSignNeu
   AuswahlSP4 := ZaehlArt
   File := FileOpen(AuswahlDateiSP1, "w")
   File.Write(AuswahlSP1)
   File.Close()
   File := FileOpen(AuswahlDateiSP4, "w")
   File.Write(AuswahlSP4)
   File.Close()   
}
; Abschluß-Message
Gui, Destroy
VorschauMsgNeu = %AktSignNeu%_%SignVorlage%%ZaehlArtZeichen%%IndexVorlage%
MsgAnzeige = 
(
Ihre neu erstellte Vorlage %VorschauMsgNeu% wurde abgespeichert.
Möchten Sie zurück zur Vorlagenauswahl?
)
MsgBox, 68, , %MsgAnzeige%
   IfMsgBox Yes
      gosub, Auswahlfenster
   else
      gosub, Anzeige
Return

;------------------------------------------------------------------------
; Auswahl abbrechen -> Programm beenden
Abbrechen:
GuiClose:
Gui, Destroy
return

;------------------------------------------------------------------------
; Vorschau mit Progresselement statt MsgBox, damit Schrift formatierbar ist
^F7::
Anzeige:

If (AktSign = "")
{
   LeerAnzeige = Es ist keine Bestandsvorlage ausgewählt! 
   Progress, m2 fs12 zh0 ct0000ff CWffffff B, %LeerAnzeige%, , Vorschau, Verdana
}
else
{
   Gosub, VorlagenDefinieren

   VorschauMsg = %AktSign%_%SignVorlage%%ZaehlArtZeichen%%IndexVorlage%
   Progress, m2 fs12 zh0 ct0000ff CWffffff B, %VorschauMsg%, , Vorschau, Verdana
}
SetTimer, ProgressOff, 1500
Return

ProgressOff:
Progress, Off
Return
Gebracht hat das aber nichts. Das Script läßt immernoch alle neuen Vorlagen durchgehen - auch wenn sie genauso bereits in der Tabelle stehen.
Irgendwie muß das wohl doch an der logischen Formulierung des If-Ausdrucks liegen. Doch ich habe keine Ahnung, wie ich das richtig machen soll.

Viele Grüße von Meister Lampe
User avatar
haichen
Posts: 631
Joined: 09 Feb 2014, 08:24

Re: Optimierung Umbenennungstool

29 May 2020, 00:52

Mit MsgBox, % "|" AktSignEingabe "|" könntest du vor dem If mal schauen was in der Variablen steht. Ein bei mir üblicher Verdächtiger wäre ein Absatzzeichen `n.
Das müsstest du mal mit allen Ifs machen.
Du kannst das auch als Else hinter dem If-Zweig machen.

Code: Select all

if()
{
	...
}
else
  	MsgBox, % A_LineNumber " Varname|" Varname"|"
just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Optimierung Umbenennungstool

29 May 2020, 04:55

... Die zweite ist die Auswahl in der DropDownList. In der Subroutine VorlagenDefinieren werden die beiden dann synchronisiert und auf die interne Variable gleichgesetzt. Ich habe in den Vergleich bei der Eingabe jetzt also ZahlArtAuswahl hineingesetzt: ...
Interessant, beim Neuerstellen einer Vorlage werden Felder über die Auswahl aus der DDL gefüllt? Was sagt denn die MsgBox für die LV-Zeile, die einen Treffer liefern soll?
User avatar
Meister Lampe
Posts: 228
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

10 Nov 2020, 14:09

Hallo zusammen!

Endlich habe ich wieder Zeit, mich um dieses Projekt zu kümmern.

just me fragt:
Interessant, beim Neuerstellen einer Vorlage werden Felder über die Auswahl aus der DDL gefüllt? Was sagt denn die MsgBox für die LV-Zeile, die einen Treffer liefern soll?
Nein, das ist nicht so gemeint. Die DDL bietet unterschiedliche Strukturen an, wie die Durchnumerierung nachher stattfinden soll: beginnend mit 0 im Index oder 1, davon abhängig wird auch der Index mit Unterstrich oder Bindestrich abgesetzt, ganz ohne Index etc. In der 4. Spalte der LV werden diese Vorlagen (ich habe sie "Zählarten" genannt) unter einem Namen abgespeichert. Das ist nötig, da jetzt die Variable AktSign mehrmals vorkommen kann und deshalb kein eindeutiges Kriterium mehr ist. Deshalb muß die Variable Zaehlart dann später auch in der externen AuswahlDatei zur letzten Auswahl mit abgespeichert werden.
In einem Abschnitt des Scripts soll das dann entsprechend deklariert werden:

Code: Select all

If (ZaehlArtAuswahl = vollständige Akte)
   {
   SignVorlageNeu := Format("{:0" . StellenSignNeu . "}", 0) 
   ZaehlArtZeichen := "-"
   SignTyp := "vollst. Akte"
   }
If (ZaehlArtAuswahl = Faszikel ohne Deckblatt)
   {
   SignVorlageNeu := Format("{:0" . StellenSignNeu . "}", 1) 
   ZaehlArtZeichenn := "-"  
   ZaehlArt := "ohne Deckblatt"
   }
If (ZaehlArtAuswahl = abweichende Dokumentationsformate)
   {
   SignVorlageNeu := Format("{:0" . StellenSignNeu . "}", 1) 
   ZaehlArtZeichen := "_"
   ZaehlArt := "Einlagen"
   }
Else If (ZaehlArtAuswahl = ohne Indizes)
   {
   SignVorlageNeu := Format("{:0" . StellenSignNeu . "}", 1)
   ZaehlArt := "ohne Index"
   }
Ich weiß nicht, an welche Stelle im Script ich das am besten setzen soll, wahrscheinlich sogar an mehreren, dann sollte ich das als Subroutine auslagern und von diesen Stellen aufrufen. Wenn ich mich nicht irre, ist das letztlich das, was man in anderen Sprachen "Klassen" nennt. Gibt es dazu noch bessere Möglichkeiten in AHK?

Viele Grüße von Meister Lampe
just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Optimierung Umbenennungstool

11 Nov 2020, 04:18

Moin,

Meister Lampe wrote:... Wenn ich mich nicht irre, ist das letztlich das, was man in anderen Sprachen "Klassen" nennt. ...
Eine Subroutine ist und bleibt auch in anderen Sprachen eine Subroutine, soweit Subroutinen unterstützt werden.

Code: Select all

If (ZaehlArtAuswahl = vollständige Akte)
Hier ist etwas falsch. Mittlerweile solltest Du den Fehler selbst korrigieren können.

Code: Select all

...
   SignTyp := "vollst. Akte"
...
   ZaehlArt := "ohne Deckblatt"
Hier steckt möglicherweise auch ein Fehler. Das kannst nur Du wissen.

Du hast übrigens bisher nur eine von zwei meiner Fragen beantwortet.
User avatar
Meister Lampe
Posts: 228
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

15 Nov 2020, 17:42

Hallo just me!
Eine Subroutine ist und bleibt auch in anderen Sprachen eine Subroutine, soweit Subroutinen unterstützt werden.
Das hatte ich wohl etwas ungeschick formuliert. Natürlich meinte ich nicht die Suroutine selbst, sondern das, was sie produzieren soll. Oder noch etwas präziser: Die Möglichkeit, in der einen Variablen ZaehlArt gleich ein Bündel von mehreren Eigenschaften eines Elementes zusammenzufassen, um sie später als Charakteristika abrufen zu können, ohne sie einzeln abfragen zu müssen.
Hier ist etwas falsch. Mittlerweile solltest Du den Fehler selbst korrigieren können.
Hier muß ich mich bei Dir entschuldigen, denn ich hatte in meinem letzten Post leider versehentlich aus einer älteren Version meines Scripts zitiert. In der aktuellen sieht das dann so aus:

Code: Select all

VorlagenDefinieren:
If (ZaehlArtAuswahl = "vollständige Akte" or ZaehlArt = "vollst. Akte")
   {
   SignVorlage := Format("{:0" . StellenSignNeu . "}", 1) 
   ZaehlArtZeichen := "-"
   IndexVorlage := Format("{:0" . StellenIndexNeu . "}", 0)
   ZaehlArt := "vollst. Akte"
   }
If (ZaehlArtAuswahl = "Faszikel ohne Deckblatt" or ZaehlArt = "ohne Deckblatt")
   {
   SignVorlage := Format("{:0" . StellenSignNeu . "}", 1) 
   ZaehlArtZeichenn := "-" 
   IndexVorlage := Format("{:0" . StellenIndexNeu . "}", 1)
   ZaehlArt := "ohne Deckblatt"
   }
If (ZaehlArtAuswahl = "abweichende Dokumentationsformate" or ZaehlArt = "Einlagen")
   {
   SignVorlage := Format("{:0" . StellenSignNeu . "}", 1) 
   ZaehlArtZeichen := "_"
   IndexVorlage := Format("{:0" . StellenIndexNeu . "}", 1)
   ZaehlArt := "Einlagen"
   }
Else If (ZaehlArtAuswahl = "ohne Indizes" or ZaehlArt = "ohne Index")
   {
   SignVorlage := Format("{:0" . StellenSignNeu . "}", 1)
   ZaehlArtZeichen := ""
   IndexVorlage := ""
   ZaehlArt := "ohne Index"
   }
 return
Und hier noch zur Erläuterung, denn ich glaube, daß es das war, was Dich noch irritiert hat:
Mit der DDl werden keine Felder aus der Gui ausgefüllt. Die für die Definition von Bestand, Signatur und ggf. Index müssen weiterhin über die Tastatur gefüllt werden. Es dreht sich darum, wie die nachher miteinander verbunden werden sollen.
Die Variable ZaehlArt ist der Name für die ausgewählte Differenzierung von unterschiedlichen Startindizes und Trennzeichen bei gleicher AktSign. Diese wird in der Tabelle abgespeicher, in der ListBox angezeigt und soll auch in die Erinnerungsdatei zu letzten Auswahl mit aufgenommen werden.
Die Variable ZaehlArtAuswahl beinhaltet die - ausführlichere - Beschreibung, die als Inhalt der DDL zur Auswahl steht.
Beides steht aber letztlich für dieselbe Sache und wird in der Subroutine VorlagenDefinieren: dann sychronisiert.

Ich hoffe, Dir das jetzt etwas verständlicher beschrieben zu haben, als letztes Mal.

Viele Grüße von Meister Lampe
just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Optimierung Umbenennungstool

16 Nov 2020, 04:14

Moin,

die von Dir zitierte Bemerkung bezog sich auf diesen Beitrag. Und meine Frage nach der MsgBox auf die hier auskommentierte Zeile:

Code: Select all

; AktSignEingabe darf nicht bereits vergeben sein
Loop, % LV_GetCount()
{
   LV_GetText(AktSignLV, A_Index, 1)
   LV_GetText(ZaehlArtLV, A_Index, 4)
   ;~ MsgBox, "%AktSignEingabe%" <-> "%AktSignLV%"`n"%ZaehlArtAuswahl%" <-> "%ZaehlArtLV%" " / " "Neu Erstellen" ; <<<<<<<<<<
   If (AktSignEingabe = AktSignLV and ZaehlArtAuswahl = ZaehlArtLV)
   {
      MsgBox, 16, Fehler!, Die Vorlage ist bereits vergeben!
      GuiControl, Focus, AktSignEingabe
      Return
   }
}
Du hast bisher nichts dazu gesagt, ob der Fehler inzwischen behoben ist.

Wenn man in einer Variablen mehrere Werte speichern will, die direkt abgerufen werden können, benutzt man dafür i.d.R. ein AHK-Objekt. Man braucht aber immer einen eindeutigen Bezeichner, um an die einzelnen Werte zu kommen.

Wenn Du nur die Werte aus ZaehlArt und ZaehlArtAuswahl zusammenführen willst, solltest Du erst noch einmal darüber nachdenken, ob Du wirklich beide Werte benötigst.
User avatar
Meister Lampe
Posts: 228
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

17 Nov 2020, 13:13

Hallo just me!

Wohl wieder derselbe Fehler - nur andersrum. :?
Ich habe jetzt beide MsgBox mal versucht, die die haichen empfohlen hatte und die von dir (Natürlich nicht gleichzeitig.) Ich habe jetzt außerdem noch - wie in den anderen Fällen auch - bei dem LV_GetText die Spaltennummer mit eingefügt.

Code: Select all

; AktSignEingabe darf nicht bereits vergeben sein
Loop, % LV_GetCount()
{
   LV_GetText(AktSignLV, A_Index, 1)
   LV_GetText(ZaehlArtLV, A_Index, 4)
   ;~ MsgBox, % "|" AktSignEingabe "|"
   ;~ MsgBox, %AktSignEingabe% <-> %AktSignLV%`n%ZaehlArtAuswahl% <-> %ZaehlArtLV% " / " Neu Erstellen
   If (AktSignEingabe = AktSignLV and ZaehlArtAuswahl = ZaehlArtLV)
   {
      MsgBox, 16, Fehler!, Die Vorlage ist bereits vergeben!
      GuiControl, Focus, AktSignEingabe
      Return
   }
}
Das Ergebnis:
Mit der Schleife wird brav die Tabelle Zeile für Zeile durchgegangen und anschließend der neue Datensatz abgespeichert. Allerdings meldet sich keine Warnung bzw. Fehlermeldung, falls die eingegebenen neuen Werte für AktSign und die ZaehlArt identisch sind mit denen in einem bereits vorhandenen Datensatz. Ich kann den also mehrmals abspeichern, da die If-Abfrage ignoriert wird. Anscheinend ist der Ausdruck darin logisch nicht korrekt. Ich wüßte aber nicht, wie man das anders schreiben soll.

Viele Grüße von Meister Lampe
BoBo
Posts: 6564
Joined: 13 May 2014, 17:15

Re: Optimierung Umbenennungstool

17 Nov 2020, 13:36

Falls ich nicht irre, wird in einer Bedingung wie folgt verglichen "==", wohingegen bei Variablenzuweisung ein einfaches "=" verwendet wird?!
If (AktSignEingabe == AktSignLV) && (ZaehlArtAuswahl == ZaehlArtLV) btw, sind die Variablen alle "gefüllt"?
gregster
Posts: 8989
Joined: 30 Sep 2013, 06:48

Re: Optimierung Umbenennungstool

17 Nov 2020, 14:32

BoBo wrote:
17 Nov 2020, 13:36
Falls ich nicht irre, wird in einer Bedingung wie folgt verglichen "==", wohingegen bei Variablenzuweisung ein einfaches "=" verwendet wird?!
Wie, bist du neu? :)

= ist doch der "normale" Gleichheits-Operator in AHK-Ausdrücken, == ist zusätzlich case-sensitive (achtet zusätzlich auf Groß-/Kleinschreibung, falls vorhanden) - aber k. A., ob hier relevant; bin nicht im Topic eingearbeitet.
Klar gibts (leider immer noch) das legacy-assignment via = (jedoch unter anderen Voraussetzungen), aber der Walross-Operator := wurde ja nicht umsonst eingeführt.
just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Optimierung Umbenennungstool

18 Nov 2020, 05:20

Moin Meister,

das ist immer noch sehr zäh. Wenn Du keine Meldung für mehrfach vergebene Werte bekommst, wird die Bedingung der If-Abfrage nicht erfüllt. Warum das so ist, kann niemand prüfen, der nicht Dein komplettes Skript und auch Deine Daten/Dateien hat.

Die von mir gemeinte MsgBox sollte Dir die Prüfung erleichtern, weil sie alle relevanten Werte anzeigt. Wenn Du beim Testen auf eine Kombination triffst, die Deiner Meinung nach abgewiesen werden sollte aber nicht abgewiesen wird, musst Du Dir den Inhalt der betroffenen Variablen etwas genauer anschauen.

... Ich habe jetzt außerdem noch - wie in den anderen Fällen auch - bei dem LV_GetText die Spaltennummer mit eingefügt. ...
Das hatten wir doch schon vor längerer Zeit abgehakt. :roll:
User avatar
Meister Lampe
Posts: 228
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

25 Nov 2020, 17:24

Hallo just me!

Ich habe das jetzt noch mehrmals durchprobiert und genau verglichen. Es scheint daran zu liegen, daß die Eingaben von der DDL unter ZaehlArtAuswahl nicht bzw. noch nicht früh genug mit denen in der ListView und den in der dahinterliegenden Tabelle unter ZaehlArt abgespeicherten Werten syncronisiert werden.
Zur Ausblendung des Eingabefeldes für den Index bei Signaturen ohne Index hatte ich ja bereits vorher schon erfolgreich ein g-Label gesetzt. Das sah dann so aus:

Code: Select all

Gui, Add, DropDownList, xm w350 Choose1 vZaehlArtAuswahl gZaehlart, vollständige Akte|Faszikel ohne Deckblatt|abweichende Dokumentationsformate|ohne Indizes
.
.
Zaehlart:
Gui, submit, nohide
If (ZaehlArtAuswahl = "ohne Indizes")
{
   GuiControl, Disable, IndexEingabe
}
else
{
   GuiControl, Enable, IndexEingabe
}
return
Jetzt hatte ich gedacht, ich könnte das zur Synchronisation erweitern:

Code: Select all

Zaehlart:
Gui, submit, nohide
If (ZaehlArtAuswahl = "vollständige Akte") 
   ZaehlArtAuswahl := "vollst. Akte"
If (ZaehlArtAuswahl = "Faszikel ohne Deckblatt")
   ZaehlArtAuswahl := "ohne Deckblatt"
If (ZaehlArtAuswahl = "abweichende Dokumentationsformate")
   ZaehlArtAuswahl := "Einlagen"
If (ZaehlArtAuswahl = "ohne Indizes")
{
   GuiControl, Disable, IndexEingabe
   ZaehlArtAuswahl := "ohne Index"
}
else
   GuiControl, Enable, IndexEingabe
Aber leider hatte ich mich da zu früh gefreut. Die Ausblendung/Deaktivierung des Index-Eingabefeldes klappt weiterhin, aber sonst tut sich nichts.
Da man die Listeneinträge mit choose auch direkt über ihre Zeilennummer auswählen kann, wäre jetzt meine Frage: Geht das auch umgekehrt? Daß also die Listennummer oder eine anderer zweiter Zuordnungswert bei der Auswahl mit ausgegeben werden kann? Dann könnte ich an diese Stelle gleich die Variable ZaehlArt setzen. ZaehlArtAuswahl dient ja im Prinzip lediglich zur Beschriftung der Auswahloptionen.

Viele Grüße von Meister Lampe
just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Optimierung Umbenennungstool

26 Nov 2020, 04:20

Moin,

die Option für die Ausgabe einer Zeilennummer solltest Du :arrow: hier finden. Wenn Du allerdings im ListView bzw. in den Vorlagendateien Texte verwendest, ist das kein Selbstgänger
User avatar
Meister Lampe
Posts: 228
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

10 Jul 2021, 17:35

Hallo just me!

Nach längerem vergeblichen Probieren habe ich es erstmal aufgegeben, die wie oben vorgesehene Fallunterscheidung in der ListViev einzubauen. Vorerst werde ich die unterschiedlichen Zählformate dann manuell verändern.
Eine andere Sache hat sich mittlerweile auch als wichtiger herausgestellt und dazu bräuchte ich eine Erläuterung zu einem Teil des Codes.
In dem Teil des Scripts, das ich als erstes entwickelt hatte, nämlich zum Umbenennen hintereinander liegender Dateien, hast Du sie nach dem Auswählen in ein Array zusammengefaßt, u.a. um deren Anzahl bestimmen zu können:

Code: Select all

If !(ShellWin) ; das aktive Explorerfenster wurde nicht gefunden, Abbruch!
      Return
   ; Auswahl nach unten erweitern
   Send, +{LButton}
   ; Auswahl einlesen und bereinigen. Die erste Datei (mit dem Fokus) kommt ans Ende.
   ; -> docs.microsoft.com/en-us/windows/desktop/shell/shellfolderview-selecteditems
   If !(ShellWin.Document.SelectedItems.Count > 0) { ; keine Auswahl
      MsgBox, Sie müssen mindestens eine Datei markieren!
      Return
   }
SelectedItems := []
   For Item In ShellWin.Document.SelectedItems
      SelectedItems.Push(Item)
   LetzteDatei := SelectedItems.RemoveAt(1)  ; erste (bzw. letzte) Datei aus dem Array entfernen ...
   SelectedItems.Push(LetzteDatei)           ; ... und wieder anhängen
   Anzahl := SelectedItems.Length()
   ; Prüfen, ob die Dateinamenserweiterungen angezeigt werden
   ; -> docs.microsoft.com/en-us/windows/desktop/shell/shellfolderview-viewoptions
   ShowExt := (ShellWin.Document.ViewOptions & 2) ; SFVVO_SHOWEXTENSIONS (0x00000002)
   ; MsgBox, 0, ShowExt, %ShowExt%
 
Ich verstehe diesen Ablauf nicht ganz, insbesondere frage ich mich nach dem eigentlichen Namen des Arrays zum Aufrufen seines Inhaltes, da ich in einer Variante des Tools den Namen der ersten Datei im späteren Ablauf gerne weiterverwenden würde, um daraus die LetzteSign zu extrahieren.
Ich mußte aber feststellen, daß die Variable LetzteDatei leer ist! Und zwar von Anfang an, also nicht später erst geleert wird. Denn wenn ich direkt danach so etwas wie

Code: Select all

TestDatei := LetzteDatei
setzte und dann später die TestDatei prüfe, ist dort auch nichts drin.
Wie komme ich also an den Namen der ersten markierten - und damit ja wohl in das Array aufgenommenen - Datei heran?

Viele Grüße von Meister Lampe
just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Optimierung Umbenennungstool

11 Jul 2021, 03:37

Moin,

das Array mit den Dateien heißt SelectedItems. In diesem Array werden FolderItem Objekte abgelegt. Die Variable LetzteDatei enthält deshalb ebenfalls ein Objekt. Du kannst z.B. Pfad so auslesen:

Code: Select all

LetzterPfad := LetzteDatei.Path
Alternativ geht auch

Code: Select all

LetzterPfad := SelectedItems[Anzahl].Path
User avatar
Meister Lampe
Posts: 228
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

17 Jul 2021, 16:47

Hallo just me!

Vielen Dank, damit bin ich ein Stück weitergekommen.
Kannst Du mir noch erklären, warum zwar folgender Code funktoniert:

Code: Select all

ErsterPfad := SelectedItems[1].Path
   SplitPath, ErsterPfad, , , , ErsterName
   MsgBox, Die Variable ErsterName lautet jetzt %ErsterName%
Ich ihn aber nicht in eine Variable zusammenfassen kann:

Code: Select all

SplitPath, SelectedItems[1].Path, , , , ErsterName
   MsgBox, Die Variable ErsterName lautet jetzt %ErsterName%
Hier kommt dann den Fehler "illegal Character".
Welches Zeichen ist da falsch?

Viele Grüße von Meister Lampe
BoBo
Posts: 6564
Joined: 13 May 2014, 17:15

Re: Optimierung Umbenennungstool

18 Jul 2021, 04:00

Eines von diesen drei [.] ???
Vielleicht beherrscht SplitPath die 'forced expression' Schreibweise? SplitPath, % ...
gregster
Posts: 8989
Joined: 30 Sep 2013, 06:48

Re: Optimierung Umbenennungstool

18 Jul 2021, 06:30

https://ahkde.github.io/docs/commands/SplitPath.htm#Parameters wrote:[v1.1.21+]: Dieser Parameter kann ein % Ausdruck sein, allerdings muss das Prozent-Leerzeichen-Präfix verwendet werden.
User avatar
Meister Lampe
Posts: 228
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

08 Aug 2021, 16:44

Hallo just me & gregster!

Danke für Eure Hinweise.
Ich habe jetzt das Umbenennungsscript etwas modifiziert und diese neuen Elemente mit eingebaut. Hintergrund hierfür ist die Zusammenführung von Bildern aus verschiedenen Scannern in jeweils einen Datensatz.
Und so weit bin ich gekommen:

Code: Select all

Zusammenführen:
+LButton::
   ; Explorerfenster bestimmen
   ExplorerID := WinExist()
   ShellWin := 0
   For Win In ShellApp.Windows {
      If (Win.HWND = ExplorerID) {
         ShellWin := Win
         Break
      }
   }
   If !(ShellWin) ; das aktive Explorerfenster wurde nicht gefunden, Abbruch!
      Return
   ; Auswahl nach unten erweitern
   Send, +{LButton}
   ; Auswahl einlesen und bereinigen. Die erste Datei (mit dem Fokus) kommt ans Ende.
   ; -> docs.microsoft.com/en-us/windows/desktop/shell/shellfolderview-selecteditems
   If !(ShellWin.Document.SelectedItems.Count > 0) { ; keine Auswahl
      MsgBox, Sie müssen mindestens eine Datei markieren!
      Return
   }
Gosub, Sub_Zusammenführen
return

Sub_Zusammenführen:
  SelectedItems := []
   For Item In ShellWin.Document.SelectedItems
      SelectedItems.Push(Item)
   LetzteDatei := SelectedItems.RemoveAt(1)  ; erste (bzw. letzte) Datei aus dem Array entfernen ...
   ;~ ErsterPfad := LetzteDatei.Path
   SelectedItems.Push(LetzteDatei)           ; ... und wieder anhängen
   Anzahl := SelectedItems.Length()
   ; Prüfen, ob die Dateinamenserweiterungen angezeigt werden
   ; -> docs.microsoft.com/en-us/windows/desktop/shell/shellfolderview-viewoptions
   ShowExt := (ShellWin.Document.ViewOptions & 2) ; SFVVO_SHOWEXTENSIONS (0x00000002)
   ;~ MsgBox, 0, ShowExt, %ShowExt%
   
   SplitPath, % SelectedItems[1].Path, , , , ErsterName
   ;~ MsgBox, Die Variable ErsterName lautet jetzt %ErsterName%
   ErsteNummer := StrReplace(ErsterName, AktSign . "_")
   ;~ MsgBox, Die Variable ErsteNummer lautet jetzt %ErsteNummer%
   ErsteSign := StrSplit(ErsteNummer, "-")
   ;~ MsgBox, Die Variable ErsteSign lautet jetzt %ErsteSign%
   LetzteSign := Format("{:0" . StellenSign . "}", ErsteSign[1]) 
   ;~ MsgBox, Die Variable LetzteSign lautet jetzt %LetzteSign%
   LetzterIndex := 1
      
   ; Dateien umbenennen
   ShellWin.Document.SelectItem(SelectedItems[1], 4)
   For Index, Item In SelectedItems {
      ItemPath := Item.Path
      SplitPath, ItemPath, DateiName, , Erweiterung
      LetzterIndex := Format("{:0" . StellenIndex . "}", LetzterIndex)  ; Setzt Index auf 1 in 2 Ziffern
      Item.Name := AktSign . "_" . LetzteSign . "-" . LetzterIndex . (ShowExt ? "." . Erweiterung : "")
      LetzterIndex++
   }
   ;~ MsgBox, Die Datei LetzterIndex lautet jetzt %LetzterIndex%
   ; -> docs.microsoft.com/en-us/windows/desktop/shell/shellfolderview-selectitem
   ShellWin.Document.SelectItem(SelectedItems[Anzahl], 29)
   For Index, Item In SelectedItems
      Item := ""
   ShellWin := ""
   
Return
Der erste Block Zusammenführen ist praktisch eine Kopie aus dem anderen Script, der zweite Sub_Zusammenführen stellt vor dem Umbenennen die Signatur fest der ersten Datei fest und verwendet dann diese. Ich habe das absichtlich in zwei Routinen geteilt, weil ich mir vorbehalten wollte, die Auswahl auch anders treffen zu können, als durch manuelles Markieren.
Und genau darum geht es mir jetzt: Wie kann ich es Einrichten, daß das Programm, alle Dateien, die die einmal herausgefundene Startsignatur enthalten, zum Umbenennen sucht?
Einen Anfang habe ich gemacht (die erste Datei muß man aber immernoch markieren), komme aber jetzt nicht mehr weiter:

Code: Select all

AutomZusammenführen:
^!z::

; Explorerfenster bestimmen
ExplorerID := WinExist()
ShellWin := 0
For Win In ShellApp.Windows {
   If (Win.HWND = ExplorerID) {
      ShellWin := Win
      Break
   }
}
If !(ShellWin) ; das aktive Explorerfenster wurde nicht gefunden, Abbruch!
   Return

Clipboard := "" 					; ClipBoard leeren, damit ClipWait funktioniert
Send, ^c 					    ; mit Control+C Dateinamen inkl. Pfad ins ClipBoard kopieren
ClipWait, 1, 1 					; kurz warten, bis der Dateiname im ClipBoard angekommen ist
StartPfad := Clipboard
   MsgBox, Die Variable StartPfad lautet jetzt %StartPfad%
   
SplitPath, % StartPfad, , , , StartName
   MsgBox, Die Variable StartName lautet jetzt %StartName%
StartNummer := StrReplace(StartName, AktSign . "_")
   MsgBox, Die Variable StartNummer lautet jetzt %StartNummer%
StartSign_arr := StrSplit(StartNummer, "-")
SuchSign := AktSign . "_" . StartSign_arr[1]
   MsgBox, Die Variable SuchSign lautet jetzt %SuchSign% 
   
Clipboard := "" 
SendInput, ^a^c 
ClipWait, 1
AlleDateien := Clipboard
Clipboard := ""
Man müßte jetzt nach allen Dateien im Ordner suchen, die die Variable Suchsign als Zeichenkette am Anfang ihres Namens haben und sie ebenfalls in so ein Array wie das SelectedItems bringen. Dann könnte man entweder ebenfalls auf Sub_Zusammenführen springen oder - besser - das abgekürzt schreiben, da die Signatur ja nicht mehr ermittelt werden muß.
just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Optimierung Umbenennungstool

15 Aug 2021, 04:07

Moin,

man sollte meinen, dass Du inzwischen herausgefunden hast, wie man den Namen der in einem Explorerfenster markierten Datei auch ohne Zwischenablage einlesen kann. Sei's drum!

Wenn Du den Namen erst einmal hast, hast Du auch den Namen des Ordners. Du kannst dann den Rest mit Loop, Files, ... erledigen.

Alternativ kannst Du die Dateipfade auch direkt aus dem Ordnerobjekt des Explorerfensters auslesen und/oder die passenden Element in einem Array wie SelectedItems ablegen.

Code: Select all

#NoEnv
SetBatchLines, -1

Shell := ComObjCreate("Shell.Application")

Return

; Ein Explorerfenster öffnen, eine Datei auswählen und den Hotkey eingeben
+^f::
ActiveWindow := WinExist("A")
ShellWin := 0
For Win In Shell.Windows {
   If (Win.HWND = ActiveWindow) {
      ShellWin := Win
      Break
   }
}
If !(ShellWin)
   Return
If !(ShellWin.Document.SelectedItems.Count = 1) {
   MsgBox, 16, Fehler!, Bitte genau eine Datei auswählen!
   Return
}
FilePath := ShellWin.Document.SelectedItems.Item[0].Path
MsgBox, %FilePath%
I := 1
For Item In ShellWin.Document.Folder.Items {
   If Item.IsFolder() ; das Element ist ein Ordner -> überspringen
      Continue
   MsgBox, 0, % "Datei " . I++, % Item.Path
   If (I > 10) ; nach spätestens 10 Dateien ist Schluss
      Break
}
Return

Esc::
ExitApp

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: No registered users and 16 guests