Optimierung Umbenennungstool

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

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

Re: Optimierung Umbenennungstool

21 Nov 2019, 18:26

Hallo just me!

Nachdem ich aus dem anderen Thread einiges mitnehmen konnte und auch nochmals im Handbuch gestöbert habe, habe ich das mit den dynamischen Labels mal ausprobiert. Insbesonder Du wolltest ja wissen, wozu die mir nützlich sein sollten. Um das näher darzustellen und weil das noch nicht so klappt, wie es eigentlich nach der Beschreibung zu erwarten wäre, stelle ich den betreffenden Code hier nochmals herein.
Ich habe unter F12 ein Modul erstellt, das bei ausgewählten Bildern, wenn sie bis dahin nur "nackte" Nummern tragen, diese nach der ausgewählten Vorlage trimmt und entsprechende Bestandsnummer AktSign davorsetzt. Das ist nur bestimmt für Dateien ohne Index (StellenIndex = 0). Dafür gibt es eine Prüfung. Zuvor wird aber geprüft, ob überhaupt eine Bestandsvorlage ausgewählt ist. Und an dieser Stelle soll, falls nötig, der Abzweig zum Auswahlfenster und von dort wieder zurück stattfinden.
Das sieht jetzt so aus:

Code: Select all

F12::
If (AktSign = "")
   {
      MsgBox, 17, Keine Bestandsvorlage!, Sie müssen zuerst eine Bestandsvorlage auswählen!
      IfMsgBox Ok
      {
         Lb_Ruecksprung := "Lb_NameErgaenzen_1"
         Goto, Auswahlfenster
         Lb_NameErgaenzen_1:
      }
      else
      return
   }
   
   If !(StellenIndex = "0")
   {
      ;Gosub, Trimmen_mI
      MsgBox, 16, Fehler!,  Sie können keine Signaturen mit Indizes ergänzen!`nBitte wähle Sie eine andere Vorlage aus.
      Lb_Ruecksprung := "Lb_NameErgaenzen_2"
      Goto, Auswahlfenster
      Lb_NameErgaenzen_2:
   }
   else
      
   Clipboard := ""
   SendInput, ^c
   Clipwait, 1
 
   DateienAuslese := Clipboard
   SignStellen := StellenSign
   IndexStellen := StellenIndex
   NewAktname := AktSign
   
   Loop, Parse, Dateienauslese, `n, `r
	{
      SplitPath, A_LoopField, , Verzeichnis, Erweiterung, SignRumpf	
	  
		; Wenn NameArray[2] mit einer oder mehreren Ziffer(n) beginnt und mit einer oder keiner 'Nichtziffer' endet ...
      If RegExMatch(SignRumpf, "^(\d+)(\D?)$", Match) 
      {
         ; MsgBox, % StrLen(Match1) . ": " . Match1 . "   <>   " . Match2
         If (StrLen(Match1) = SignStellen)
            NewSign := SignRumpf
         else
         {
            Match1 += 0 ; führende Nullen entfernen
            If !(StrLen(Match1) > SignStellen)
            {
               NewSign := Format("{:0" . SignStellen . "}", Match1) . Match2
               ; MsgBox, % StrLen(NewSign) . ": " . NewSign . "   <>   " . Match2
               ;FileMove, %A_LoopField%, %Verzeichnis%\%NewAktname%_%NewSign%.%Erweiterung%
            }
         }
         FileMove, %A_LoopField%, %Verzeichnis%\%NewAktname%_%NewSign%.%Erweiterung%
      }      	
   }  	
return
und im letzten der sich nacheinander aufrufenden Module Auswahlfenster incl. ListView, Anwenden und Anzeige steht dann am Schluß der Befehl zu Rücksprung zum letzten abgespeicherten Label:

Code: Select all

Anzeige:
If (AktSign = "")
{
   LeerAnzeige = Es ist keine Bestandsvorlage ausgewählt! 
   Progress, m2 fs12 zh0 ct0000ff CWffffff, %LeerAnzeige%, , Vorschau, Verdana
}
else
{
   VorschauSign := Format("{:0" . StellenSign . "}", 1)
   If (StellenIndex = "0")
   {
      VorschauMsg = %AktSign%_%VorschauSign%
   }
   else
   {
      VorschauIndex := Format("{:0" . StellenIndex . "}", 0)
      VorschauMsg = %AktSign%_%VorschauSign%-%VorschauIndex%
   }
   Progress, m2 fs12 zh0 ct0000ff CWffffff B, %VorschauMsg%, , Vorschau, Verdana
}
SetTimer, ProgressOff, 1500
Goto, %Lb_Ruecksprung%
Return

ProgressOff:
Progress, Off
Return
Nur bekomme ich immer eine Fehlermeldung
---------------------------

---------------------------
Error: A Goto/Gosub must not jump into a block that doesn't enclose it.

Line#
243: {
244: VorschauIndex := Format("{:0" . StellenIndex . "}", 0)
245: VorschauMsg = %AktSign%_%VorschauSign%-%VorschauIndex%
246: }
247: Progress,m2 fs12 zh0 ct0000ff CWffffff B,%VorschauMsg%,,Vorschau,Verdana
248: }
249: SetTimer,ProgressOff,1500
---> 250: Goto,%Lb_Ruecksprung%
251: Return
254: Progress,Off
255: Return
267: ExplorerID := WinExist()
268: ShellWin := 0
269: For Win, in ShellApp.Windows
269: {

The current thread will exit.
---------------------------
OK
---------------------------
(Ab Zeile 267 beginnt ein anderer Teil des Scripts!)
Ich habe keine Ahnung, was ich damit anfangen soll.

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

Re: Optimierung Umbenennungstool

23 Nov 2019, 06:02

Meister Lampe wrote:Insbesonder Du wolltest ja wissen, wozu die mir nützlich sein sollten.
Ich wollte schlichtweg wissen, warum Du glaubst, dynamische Rücksprunglabel zu brauchen. Jetzt sehe ich es. Du springst mit Deinem Ansatz die Subroutine für die Ausgabe des Auswahlfensters mit einem Goto an und hast deshalb keine Möglichkeit, automatisch zum aufrufenden Statement zurückzukehren. Beim Gosub ist das das normale Verhalten. Wozu also Goto?

Und letzlich läuft das Ganze darauf hinaus, dem Benutzer die EIngabe von zwei Hotkeys zu ersparen, wenn er noch keine Auswahl getroffen hat. Ich halte das nach wie vor für überflüssig. Wenn Du das nicht allein hinkriegst, kannst Du mit einiger Wahrscheinlichkeit den Code auch nicht allein warten, falls Anpassungen/Änderungen erforderlich werden, an die Du heute noch nicht denkst.
User avatar
Meister Lampe
Posts: 155
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

23 Nov 2019, 18:00

Hallo just me!

Es handelt sich nicht nur darum, das Tool in der Handhabung noch etwas einfacher zu gestalten - das natürlich auch, sondern es gibt auch andere Gründe:
Erstens wiederholt sich diese Prozedur am Anfang von mehreren Anwendungen: bei der Grundfunktion, dem Umbenennen sowie bei dem Trimmen und hier beim Ergänzen. Immer steht als erstes die Frage nach der Auswahl der Bestandsvorlage. Hätte man das einmal so geschrieben, könnte man es für alle vereinheitlichen.
Zweitens, und das ist - ebenfalls bei allen diesen Anwendungen - wohl bisher die größte Schwierigkeit in der Umsetzung im Code: Wenn ich die Möglickeit zur Auswahl mit Gosub Auswahlfenster aufrufe, dann fängt das Programm nach beim ersten return der drei zusammengehörenden Module (Anzeige der Gui) wieder an weiterzulaufen, noch während der Benutzer mit dem Auswählen beschäftigt ist. Ich muß also direkt nach dem Gosub die Sache wieder mit einem return stoppen. Und ein Gosub-Befehl, der nach dem Zurückkehren nicht weiterläuft (hier weil die eigentliche Subroutine noch gar nicht abgeschlossen ist), kommt schließlich einem Goto gleich.
Könnte man das Script auf andere Weise dort anhalten und das dann mit dem Ende der ganzen Subroutine, also dort, wo ich jetzt den Rückspringbefehl eingebaut habe, wieder lösen, dann wäre das auch eine Möglichkeit.

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

Re: Optimierung Umbenennungstool

25 Nov 2019, 05:39

Meister Lampe wrote:Könnte man das Script auf andere Weise dort anhalten...
Was glaubst Du wohl, was Dir dieser Beitrag zeigen sollte?

Du kannst natürlich nach dem Gui, Show, ... auch eine Variable setzen (wie Z.B. AuswahlFertig := False) und darauf warten, dass sie auf True gesetzt wird:

Code: Select all

...
Gui, Show, ...
AuswahlFertig := False
While !(AuswahlFertig)
   Sleep, 10 ; oder länger
...
Return
Du solltest aber bedenken, dass es mehrere mögliche Fehler gibt:
  1. Keine Auswahl
  2. Auswahl mit falschem Typ
  3. Frühere Auswahl, die hier gar nicht genutzt werden soll.
Und nachdem das Skript aus den Auswahlroutinen zurückkehrt, muss nochmal geprüft werden.

Du solltest deshalb darüber nachdenken, ob Du beim Start von Bearbeitungsroutinen nicht besser immer direkt in die Auswahlroutine verzweigst, wenn Du das weiterhin so realisieren willst.
User avatar
Meister Lampe
Posts: 155
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

11 Dec 2019, 18:00

Hallo just me!
Du solltest deshalb darüber nachdenken, ob Du beim Start von Bearbeitungsroutinen nicht besser immer direkt in die Auswahlroutine verzweigst, wenn Du das weiterhin so realisieren willst.
Vielen Dank, das war ein prima Tipp!
Ich habe den mit der anderen Idee, eine Variable zur Bestätigung der Auswahl zu führen kombiniert und damit auch ein weiteres Problem lösen können.
Der Code sieht jetzt am Anfang einer jeden solchen Anwendung (Trimmen, Ergänzen, Umbenennen, virtuelles Deckblatt etc.) so aus wie hier:

Code: Select all

F12::
If !(ModulAuswahl = 3)
   {
      MsgBox, 17, Keine Bestandsvorlage!, Sie müssen zuerst eine Bestandsvorlage auswählen!
      IfMsgBox Ok
      {
         Gosub Auswahlfenster
         ModulAuswahl := 3
         return
      }
      else
      return
   }
   ...
Lediglich die Variable ModulAuswahl hat dann jeweils einen anderen Wert.
Damit wird beim Start einer Anwendung einmal das Auswahlfenster aufgerufen, bei wiederholter Verwendung aber nicht mehr. Falls aber eine andere dazwischen benutzt wurde, muß die Auswahl wieder neu verifiziert werden.
Ich hatte mir schon längere Zeit Gedanken gemacht, wie ich es einrichte, daß nicht immer ohne Rückfrage die letzte Bestandsvorlage verwendet wird, die ja praktischerweise über das Schließen des Scripts hinaus abgespeichert wird. Falls man dann zwischendurch etwas Anderes für einen anderen Bestand gemacht hat, sollte diese neue AktSign nicht ohne nachzufragen weiterverwendet werden. Zu diesem Zweck hatte ich mich ja auch mal erkundigt nach einer InputBox mit drei Buttons, damit ich darin die aktuelle Vorlage anzeigen kann und der Nutzer die Möglichkeit hätte, über einen separaten Knopf zum Ändern das Auswahlfenster aufzurufen. Jetzt ist dieses Problem also auch gelöst.

Viele Grüße von Meister Lampe
User avatar
Meister Lampe
Posts: 155
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

13 Feb 2020, 17:48

Hallo just me!

Ich habe gerade entdeckt, da0ß jeman anders ein ähnliches Problem mit dem Progress-Fenster hat wie ich: https://www.autohotkey.com/boards/viewtopic.php?f=9&t=72226
Der möchte die Anzeige ebenfalls die ganze Zeit des Programablaufs über sichtbar haben. Wenn ich das richtig verstanden habe, ist der einzige Unterschied wohl, daß er sich aus den vielen sleep-Befehlen die Zeit ausrechnet und ich das so nicht machen kann. ließe sich da trotzdem eine Anregung übernehmen?
Mit meinen derzeitigen Parametern jedenfalls müßte das progress immer im Vordergrund bleiben - dazu bedarf es noch eines "A".

Code: Select all

Progress, m2 fs12 zh0 ct0000ff CWffffff B, Bin gleich fertig ..., , Vorschau, Verdana
Viele Grüße von Meister Lampe
just me
Posts: 6722
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Optimierung Umbenennungstool

14 Feb 2020, 05:12

Moin,

wenn es immer noch um ein Progressfenster in einer so aufgebauten Routine geht

Code: Select all

MitIndex:       ; zum Umbenennen, wenn Index vorhanden
   ; Benutzereingaben zum Umbenennen holen
   LetzteSign := Format("{:0" . StellenSign . "}", ++LetzteSign) ; Erhöht die letzte Signatur um 1 und setzt sie auf 4 Ziffern
   InputBox, BoxSign, Vorschau, Es werden %Anzahl% Bilder umsigniert, , 225, 125, , , , ,%LetzteSign%
   
   If (ErrorLevel) {
      LetzteSign--
      Return
   }
   Progress, m2 fs12 zh0 ct0000ff CWffffff B, Bin gleich fertig ..., , Vorschau, Verdana
   If !InStr(BoxSign, ",") { ; Prüft, ob ein anderer Startindex durch Komma getrennt eingegeben wurde
      LetzteSign := Format("{:0" . StellenSign . "}", BoxSign) ; Setzt neue Signatur auf 4 Ziffern
      LetzterIndex := 0 ; Setzt Index auf 0
   }
   Else {
      StringSplit, BoxArray, BoxSign, `,
      If (BoxArray1 = "")
         LetzteSign := Format("{:0" . StellenSign . "}", LetzteSign) ; Erhöht die letzte Signatur um 1 und setzt sie auf 4 Ziffern
      Else
         LetzteSign := Format("{:0" . StellenSign . "}", BoxArray1) ; Setzt neue Signatur auf 4 Ziffern
      LetzterIndex := BoxArray2
   }
   ; 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++
   }
   ; Fertig
   ; Letzte Datei selektieren
   ; -> docs.microsoft.com/en-us/windows/desktop/shell/shellfolderview-selectitem
   ShellWin.Document.SelectItem(SelectedItems[Anzahl], 29)
   For Index, Item In SelectedItems
      Item := ""
   ShellWin := ""
Progress, Off
Return
könnte das durchaus in recht kurzer Zeit fertig werden.

Der erste Teil braucht nur Mikrosekunden:

Code: Select all

   If !InStr(BoxSign, ",") { ; Prüft, ob ein anderer Startindex durch Komma getrennt eingegeben wurde
      LetzteSign := Format("{:0" . StellenSign . "}", BoxSign) ; Setzt neue Signatur auf 4 Ziffern
      LetzterIndex := 0 ; Setzt Index auf 0
   }
   Else {
      StringSplit, BoxArray, BoxSign, `,
      If (BoxArray1 = "")
         LetzteSign := Format("{:0" . StellenSign . "}", LetzteSign) ; Erhöht die letzte Signatur um 1 und setzt sie auf 4 Ziffern
      Else
         LetzteSign := Format("{:0" . StellenSign . "}", BoxArray1) ; Setzt neue Signatur auf 4 Ziffern
      LetzterIndex := BoxArray2
   }
Der Rest mag wegen COM etwas länger dauern.

Bau doch einfach mal zwei MsgBoxen ein, damit Du eine positive Rückmeldung über den Stand der Dinge erhältst:

Code: Select all

   MsgBox, Gleich geht's los!
   Progress, m2 fs12 zh0 ct0000ff CWffffff B, Bin gleich fertig ..., , Vorschau, Verdana
   If !InStr(BoxSign, ",") { ; Prüft, ob ein anderer Startindex durch Komma getrennt eingegeben wurde
   ;...
   ;...
   Progress, Off
   MsgBox, Ich habe fertig!
Return

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: No registered users and 38 guests