Optimierung Umbenennungstool

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

just me
Posts: 6511
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Optimierung Umbenennungstool

06 Mar 2019, 04:54

Moin,

wenn unterschiedliche Anwender unterschiedliche Versionen eines Skripts verwenden, sollte man irgendwie kontrollieren können, dass jeder auch die für ihn bestimmte Version hat. Das kann je nach Grad der 'Absicherung' der Rechner einigen Aufwand bedeuten.

Dagegen stehen in diesem Fall Änderungen an einer Textdatei, die im Löschen oder Hinzufügen einzelner Zeilen mit 3 relativ kurzen Werten bestehen. Dermaßen 'komplizierte' Änderungen mach jeder Texteditor einschließlich Notepad mit links. Ich verstehe deshalb nicht, warum Du das Risiko eingehen willst, dass eine 'Adminversion' des Skripts auf den Rechner eines 'NichtAdmin' Benutzers gerät, der nichts Besseres zu tun weiß, als die für ihn neue Option einfach mal auszuprobieren.
User avatar
Meister Lampe
Posts: 141
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

06 Mar 2019, 17:30

Hallo just me!

Die von Dir vorgebrachten Bedenken sind nicht nötig. So groß ist unser Archiv nicht, daß ich dort die Übersicht verlieren könnte; und ich kenne auch alle Mitarbeiter persönlich und damit ihre Tätigkeitsbereiche. Es sind nicht alle mit solchen Arbeiten beschäftigt, diese werden sowieso die Standardversion erhalten. Ebenso die meisten, die damit arbeiten werden. Lediglich die entsprechenden Projektleiter erhielten dann die Admin-Version. Das wird abgesprochen nach einer kleinen Einführung. Da besteht also kein Risiko, daß jemand diese Möglichkeit unkontrolliert mißbrauchen würde.

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

Re: Optimierung Umbenennungstool

07 Mar 2019, 03:06

Moin Meister Lampe,

es bleibt Deine Entscheidung. Ich habe mich in meiner Zeit als Berufsprogrammierer zu lange mit den Folgen des Fehlverhaltens von Anwendern beschäftigen müssen, um erkannte potentielle Fehlerquellen nicht sofort zu beseitigen.

Grüße,
just me
User avatar
Meister Lampe
Posts: 141
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

07 Mar 2019, 17:10

Hallo just me!

Ich nehme das vermeintliche Risiko auf mich.
Ich weiß eben nur noch nicht wie genau. ;)

Mit dem File.Write wird ja immer eine Zeile geschrieben bzw. beim nächsten Mal überschrieben. Im vorliegenden Fall soll sie ja jeweils unten an die Tabelle neu angefügt werden. Vermutlich wird man dazu die drei Parameter aus den drei Variablen erst mit zwei Tab-Befehlen dazwischen zu einer Variablen zusammenfügen müssen um sie dann schreiben zu können. Oder gibt es da eine elegantere Lösung?

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

Re: Optimierung Umbenennungstool

08 Mar 2019, 03:36

Moin,

überlegen wir mal, wie Deine Subroutine Neuerstellen: aussehen könnte.
  • Zunächst einmal müssen die Werte aus den drei Edits in ihre Variablen eingelesen werden. Das erledigt ein Gui, Submit, NoHide.
  • Nun muss geprüft werden, ob der Inhalt der 3 Variablen den Anforderungen entspricht.
  • Danach sollte geprüft werden, ob es im ListView schon einen Eintrag zu AktSignNeu gibt. Wenn ja, was soll geschehen?
  • Wenn alles in Ordnung ist, kann der neue Eintrag jetzt gespeichert werden. Dafür sind zwei Schritte nötig:
    1. Die Werte müssen in das ListView-Control gestellt werden (LV_Add()).
    2. Die Werte müssen an die Datei angehängt werden (z.B. mit FileAppend).
  • Wenn gewünscht, werden die neuen Werte im ListView als aktuelle Auswahl gekennzeichnet. Ansonsten müssten die Edits jetzt wieder mit den Werten der vorherigen Auswahl überschrieben werden.
Die anderen Anwender bekommen von der Änderung erst einmal nichts mit.

Denkst Du Dir das auch so?

Grüße,
just me
User avatar
Meister Lampe
Posts: 141
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

08 Mar 2019, 18:34

Hallo just me!

Teile zur Subroutine Neuerstellen::
1.) Variablen einlesen:
Ja, wäre so in Ordnung.
2.) Variablen prüfen:
Ich weiß nicht genau, auf welche Anforderung hier geprüft werden soll oder kann. Der Datentyp? Ob in das 2. und 3. Feld nur Nullen eingegeben wurden? Das ist nicht nötig, da ja dort nur die Anzahl der Zeichen gezählt und daraus der Eintrag generiert wird.
3.) Prüfen, ob schon vorhanden:
Ja, das sollte man. In diesem Fall könnte man eine MsgBox mit dem Hinweis "Es existiert bereits eine Vorlage zu %AktSign%. Bitte verwenden sie diese. Im Zweifelsfall wenden Sie sich an ..." einblenden, die Subroutine schließen und wieder zurück auf die Gui mit dem ListView gehen. Im komfortabelsten Fall dann gleich die bestehende Vorlage auswählen. Ich könnte dann immernoch, falls einmal ein Eintrag falsch generiert wurde, diesen direkt in der Datei mit einem Editor reparieren.
4.) Abspeichern in ListView und Bestandsvorgaben.txt
Ja, so habe ich mir das auch vorgestellt.
5.) Neue Werte als aktuelle Auswahl:
Im Allgemeinen wird man neue Werte eintragen, wenn man sie benötigt oder wenn sie ein anderer braucht. In beiden Fällen ist es gut, sofort erkennen zu können, was sich in der Liste verändert hat.
6.) Andere Nutzer:
Wenn diese das nächste Mal mit F8 die Gui öffnen und damit die Datei einlesen, werden, sie die Äderungen ja auch bemerken. Das ist für die dann früh genug.

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

Re: Optimierung Umbenennungstool

15 Mar 2019, 08:08

Hallo just me!

Ich habe jetzt mal versucht, wenigstens einen Teil der Subroutine Neuerstellen zu entwerfen.

Code: Select all

Neuerstellen:
Gui, Submit, NoHide  ; Speichert die Benutzereingaben für eine neue Vorlage
AktSignNeu := AktSignEingabe
StellenSignNeu := StrLen(SignEingabe)
StellenIndexNeu := StrLen(IndexEingabe)

SignVorlageNeu := Format("{:0" . StellenSignNeu . "}", 1)
IndexVorlageNeu := Format("{:0" . StellenIndexNeu . "}", 0)

FileAppend , %AktSignNeu% `t %SignVorlageNeu% `t %IndexVorlageNeu%, VorgabenDatei 
VorschauMsgNeu = %AktSignNeu%_%SignVorlageNeu%-%IndexVorlageNeu%
AktSign := AktSignNeu
StellenSign := StellenSignNeu
StellenIndex := StellenIndexNeu
Gui, Destroy
MsgBox, Ihre neu erstellte Vorlage %VorschauMsgNeu% wurde abgespeichert.
return
Damit wir der neue Daensatz allerdings nicht in die Datei Bestandsvorgaben.txt, die intern unter dem Namen "VorgabenDatei" läuft und aufgerufen werden sollte, abgespeichert, sondern es wird eine neue erstellt, die diesen Namen trägt.
In der ListView braucht man den neuen Datensatz eigentlich nicht auch noch abzuspeichern, da er beim nächsten Öffnen der Gui ja automatisch dann mit aufgerufen wird. Die Vorlage wird gleich in die Variablen abgespeichert, die zum Umbenennen verwendet werden und kann somit auch über F8 und Anzeige eingesehen werden. Dieses Progresselement könnte man danach ebenfalls nochmal als Vorschau aufrufen, wie bei der Auswahl aus der ListView oder - noch besser - es mit der MsgBox zu einer einzigen Vorschau zusammenfassen. Aber alles nach der Reihe.

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

Re: Optimierung Umbenennungstool

21 Mar 2019, 02:50

Moin Meister Lampe,

ich war ein wenig abgelenkt. Jetzt habe ich aber versucht, Deine Änderungen um eine rudimentäre Eingabeprüfung zu ergänzen:

Code: Select all

Neuerstellen:
Gui, Submit, NoHide  ; Speichert die Benutzereingaben für eine neue Vorlage
; AktSignEingabe darf nicht leer sein
AktSignEingabe := Trim(AktSignEingabe)
If (StrLen(SignEingabe) = 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)
   If (AktSignEingabe = AktSignLV)
   {
      MsgBox, 16, Fehler!, Der Bestandsname ist bereits vergeben!
      GuiControl, Focus, AktSignEingabe
      Return
   }
}
; SignEingabe darf nicht leer sein
SignEingabe := Trim(SignEingabe)
If (StrLen(IndexEingabe) = 0)
{
   MsgBox, 16, Fehler!, Der Signaturvorgabe darf nicht leer sein!
   GuiControl, Focus, SignEingabe
   Return
}
; IndexEingabe darf nicht leer sein
IndexEingabe := Trim(IndexEingabe)
If (StrLen(IndexEingabe) = 0)
{
   MsgBox, 16, Fehler!, Der Indexvorgabe darf nicht leer sein!
   GuiControl, Focus, IndexEingabe
   Return
}
; Alles OK, verarbeiten
AktSignNeu := AktSignEingabe
StellenSignNeu := StrLen(SignEingabe)
StellenIndexNeu := StrLen(IndexEingabe)
SignVorlageNeu := Format("{:0" . StellenSignNeu . "}", 1)
IndexVorlageNeu := Format("{:0" . StellenIndexNeu . "}", 0)
FileAppend , %AktSignNeu% `t %SignVorlageNeu% `t %IndexVorlageNeu%, VorgabenDatei
; ----------------------------------------------------------------------------------
; Wenn Du die interne Auswahl mit den folgenden 4 Zeilen ändern willst,
; solltest Du meiner Meinung nach auch die Auswahldatei updaten!
VorschauMsgNeu = %AktSignNeu%_%SignVorlageNeu%-%IndexVorlageNeu%
AktSign := AktSignNeu
StellenSign := StellenSignNeu
StellenIndex := StellenIndexNeu
; ----------------------------------------------------------------------------------
Gui, Destroy
MsgBox, Ihre neu erstellte Vorlage %VorschauMsgNeu% wurde abgespeichert.
Return
Vielleicht zeigt das, was ich meine. Es ist aber wieder nicht getestet.

Grüße aus Berlin,
just me
User avatar
Meister Lampe
Posts: 141
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

21 Mar 2019, 17:46

Hallo just me!
ich war ein wenig abgelenkt.
Kein Problem. Du kannst ja nicht nur just for me da sein!

Ich habe mir Deinen Code mal angesehen und dann auch bei mir in das Script eingefügt. Deine Prüfungen funktionieren, ebenso die Speicherung in die Auswahldatei, ich mir einfach von oben nochmal da herein kopiert habe. Probleme gibt es alledings mit dem Speichern der neuen Vorlage. Es passiert genau dasselbe, wovon ich bereits in meinem letzten Post berichtet habe. Die neue Vorlage wird nicht in der bereits existierenden Datei Bestandsvorgaben.txt an der Tabelle unten angehängt, sondern es wird eine neue erstellt mit dem Namen VorgabenDatei, also dem Namen, der im Script für die ursprüngliche .txt-Datei stehen soll und unter dem sie für die Listview auch aufgerufen wird. Wenn ich dann eine weitere neue Vorlage abspeichern will, wird diese ebenfalls in diese neue Datei geschrieben, aber direkt hinter die letzten Zeichen und ohne eine neue Zeile zu beginnen. In der Listview sind die neuen Vorlagen natürlich nicht zu sehen, wohl aber die alten. Wenn die Zuordnung VorgabenDatei := A_ScriptDir . "\Bestandsvorgaben.txt" nicht stimmen würde, dann dürfte das ja auch nicht funktionieren! Das Abspeichern in der Auswahldatei klappt aber prima.
Wo ist also der Wurm begraben?
Ich stelle Dir jetzt nochmal das gesamte Script herein.

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance force
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
SetTitleMatchMode, RegEx
SetBatchLines, -1

;------------------------------------------------------------------------
; Shell-Objekt erzeugen
ShellApp := ComObjCreate("Shell.Application")

;------------------------------------------------------------------------
; Gruppe Windows Explorer Fenster definieren
GroupAdd, Explorer, ahk_class ExploreWClass
GroupAdd, Explorer, ahk_class CabinetWClass

;------------------------------------------------------------------------
; Vorlagendateien zum Abspeichern definieren
AuswahlDatei := A_ScriptDir . "\Auswahl.txt"  ; zuletzt verwendeter Vorlagenname, lokal gespeichert
; Auflistung im Intranetordner des Archivs:
;VorgabenDatei := "Pfad ... \Bestandsvorgaben.txt"
; Auflistung zum Ausprobieren:
VorgabenDatei := A_ScriptDir . "\Bestandsvorgaben.txt"  

; Vorlagen und Auswahlen aufrufen und einlesen
F8::
Auswahl := FileExist(AuswahlDatei) ? FileOpen(AuswahlDatei, "r").Read() : ""
If !(File := FileOpen(VorgabenDatei, "r")){
   MsgBox, 16, Fehler!, Die Datei %VorgabenDatei% konnte nicht geöffnet werden!
;   ExitApp
}
Vorgaben := StrSplit(File.Read(), "`n", "`r")
File.Close()

; Auswahlfenster erstellen und anzeigen
Rows := (L := Vorgaben.Length()) > 10 ? 10 : L
GuiText_1 := "Wählen Sie hier den Standard für das nächste Umbenennungsprojekt aus!"
Gui, Margin, 20, 20
Gui, Font, s10 , Verdana
Gui, Add, Text, xm w350, %GuiText_1%
Gui, Add, ListView, xm wp r%Rows% -Multi vBestandAuswahl Sort, Bestand|Signatur|Index
For Each, Vorgabe In Vorgaben
{
   Felder := StrSplit(Vorgabe, "`t")
   Option := (Felder[1] = Auswahl) ? "Focus Select" : ""
   LV_Add(Option, Felder*)
}
Loop, % LV_GetCount("Column")
   LV_ModifyCol(A_Index, "AutoHdr")

Gui, Add, Edit, cblue    xm  h25   w100  vAktSignEingabe, %Auswahl%
Gui, Add, Edit, cblue    x135  yp  h25  w70  vSignEingabe, %SignVorlage%
Gui, Add, Edit, cblue    x220  yp  h25  w70  vIndexEingabe, %IndexVorlage%
Gui, Add, Text, x123     yp+5    h25   w15  , _
Gui, Add, Text, x210     yp    h25   w15  , -

Gui, Add, Button, xm  h30 w100 Default gAnwenden, Anwenden
; Button "Neu Erstellen"  wird in der Standardversion auskommentiert
Gui, Add, Button, x145 yp h30 w100 gNeuerstellen, Neu Erstellen
Gui, Add, Button, x270 yp h30 w100 gAbbrechen, Abbrechen

Menu, Tray, Icon, , , 1
GuiControl, Focus, BestandAuswahl
Gui, Show, x100 y100, Signierungsvorlagen
Return

;------------------------------------------------------------------------
; Auswahl übernehmen
Anwenden:
If !(Row := LV_GetNext())
{
   MsgBox, 16, Fehler!, Bitte wählen Sie einen Bestand aus!
   GuiControl, Focus, BestandAuswahl
   Return
}
LV_GetText(AktSign, Row, 1)
LV_GetText(SignVorlage, Row, 2)
LV_GetText(IndexVorlage, Row, 3)
StellenSign := StrLen(SignVorlage)
StellenIndex := StrLen(IndexVorlage)
LetzteSign := 0
; hier müßte wohl auch die externe Abspeicherung stattfinden!
If (AktSign <> Auswahl)
{
   Auswahl := AktSign
   File := FileOpen(AuswahlDatei, "w")
   File.Write(Auswahl)
   File.Close()
}
Gui, Destroy
Gosub, Anzeige
Menu, Tray, Icon, , , 0
Return

;------------------------------------------------------------------------
; 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(SignEingabe) = 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)
   If (AktSignEingabe = AktSignLV)
   {
      MsgBox, 16, Fehler!, Der Bestandsname ist bereits vergeben!
      GuiControl, Focus, AktSignEingabe
      Return
   }
}
; SignEingabe darf nicht leer sein
SignEingabe := Trim(SignEingabe)
If (StrLen(IndexEingabe) = 0)
{
   MsgBox, 16, Fehler!, Der Signaturvorgabe darf nicht leer sein!
   GuiControl, Focus, SignEingabe
   Return
}
; IndexEingabe darf nicht leer sein
IndexEingabe := Trim(IndexEingabe)
If (StrLen(IndexEingabe) = 0)
{
   MsgBox, 16, Fehler!, Der Indexvorgabe darf nicht leer sein!
   GuiControl, Focus, IndexEingabe
   Return
}
; Alles OK, verarbeiten
AktSignNeu := AktSignEingabe
StellenSignNeu := StrLen(SignEingabe)
StellenIndexNeu := StrLen(IndexEingabe)
SignVorlageNeu := Format("{:0" . StellenSignNeu . "}", 1)
IndexVorlageNeu := Format("{:0" . StellenIndexNeu . "}", 0)
FileAppend , %AktSignNeu% `t %SignVorlageNeu% `t %IndexVorlageNeu%, VorgabenDatei
; ----------------------------------------------------------------------------------
; Wenn Du die interne Auswahl mit den folgenden 4 Zeilen ändern willst,
; solltest Du meiner Meinung nach auch die Auswahldatei updaten!
VorschauMsgNeu = %AktSignNeu%_%SignVorlageNeu%-%IndexVorlageNeu%
AktSign := AktSignNeu
StellenSign := StellenSignNeu
StellenIndex := StellenIndexNeu
If (AktSign <> Auswahl)
{
   Auswahl := AktSign
   File := FileOpen(AuswahlDatei, "w")
   File.Write(Auswahl)
   File.Close()
}
; ----------------------------------------------------------------------------------
Gui, Destroy
MsgBox, Ihre neu erstellte Vorlage %VorschauMsgNeu% wurde abgespeichert.
Return

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

;------------------------------------------------------------------------
; Vorschau mit Progresselement statt MsgBox, damit Schrift formatierbar ist
^F8::
Anzeige:
VorschauSign := Format("{:0" . StellenSign . "}", 1)
VorschauIndex := Format("{:0" . StellenIndex . "}", 0)
VorschauMsg = %AktSign%_%VorschauSign%-%VorschauIndex%
Progress, m2 fs12 zh0 ct0000ff CWffffff, %VorschauMsg%, , Vorschau, Verdana
SetTimer, ProgressOff, 2000
Return

ProgressOff:
Progress, Off
Return

;------------------------------------------------------------------------
; Bilder umbenennen im Windows Explorer
#IfWinActive ahk_group Explorer

<!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
   }
   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%
   ; 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
   }
   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 := ""
Return

#If ; Ende des bedingten HotKey
;------------------------------------------------------------------------
; Beenden des Scriptes
Escape::
ExitApp
Return
Viele Grüße von Meister Lampe
just me
Posts: 6511
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Optimierung Umbenennungstool

22 Mar 2019, 02:55

Moin Meister Lampe,

ich habe diesen Teil Deines Beitrags wohl zu schnell überflogen und hatte den Eindruck, dass das Wegschreiben in eine neue Datei für den Test erst einmal Absicht ist.

Wir haben es hier wieder einmal mit dem berühmten "Wann genau werden Variablen mit Prozentzeichen umschlossen (%)?" Problem zu tun:

Code: Select all

FileAppend , %AktSignNeu% `t %SignVorlageNeu% `t %IndexVorlageNeu%, VorgabenDatei
erwartet im letzten Parameter einen Dateinamen als Text. Wenn Du da einen Variablennamen benutzt, muss der in %-Zeichen eingeschlossen sein.

Wenn Du noch etwas auf dem Herzen hast, melde Dich!
just me
User avatar
Meister Lampe
Posts: 141
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

25 Mar 2019, 17:06

Hallo just me!
Wir haben es hier wieder einmal mit dem berühmten "Wann genau werden Variablen mit Prozentzeichen umschlossen (%)?" Problem zu tun:
Ja, aber diesmal anscheinend besonders gemein. Oben die File-Befehle und das analog aufgebaute GuiControl funtionierten ohne Prozentzeichen. Jetzt klappt es aber.
Ein anscheinend ähnliches Problem habe ich jetzt wieder, aber da klappt es weder mit noch ohne Prozentzeichen. Um leichter prüfen zu können, ob und wie sich die Datei verändert hat, hatte ich oben noch folgende Zeile eingefügt:

Code: Select all

^!F8::Run, Notepad.exe, VorgabenDatei
Aber damit öffnet sich lediglich eine neue Textdatei, die bestehende Bestandsvorgaben.txt wird nicht aufgerufen. Auch wenn ich den Namen in Prozentzeichen setze.

Ich habe am Ende der Subroutine "Neuerstellen" jetzt eine MsgBox gesetzt, in der man sich entscheiden kann, ob man zurück zum Auswahlfenster (also der Gui mit der Listview) gehen möchte, z.B. falls man weitere neue Vorlagen eingeben möchte oder ob man den Vorgang abschließen möchte, um z.B. gleich mit dem Signieren zu beginnen. Dann wird jeweils die Gui (die jetzt auch den Namen "Auswahlfenster" erhalten hat) bzw. die Anzeige aufgerufen. Meine Frage dazu: Was eignet sich besser zu diesem Zweck - GoTo oder GoSub? Ich will ja weitergehen zu diesen anderen Modulen, aber ich muß ja von dort nach deren Ablauf nicht wieder zurückkehren.

Hier nochmals das etwas überarbeitete Script:

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance force
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
SetTitleMatchMode, RegEx
SetBatchLines, -1

;------------------------------------------------------------------------
; Shell-Objekt erzeugen
ShellApp := ComObjCreate("Shell.Application")

;------------------------------------------------------------------------
; Gruppe Windows Explorer Fenster definieren
GroupAdd, Explorer, ahk_class ExploreWClass
GroupAdd, Explorer, ahk_class CabinetWClass

;------------------------------------------------------------------------
; Vorlagendateien zum Abspeichern definieren
AuswahlDatei := A_ScriptDir . "\Auswahl.txt"  ; zuletzt verwendeter Vorlagenname, lokal gespeichert
; Auflistung im Intranetordner des Archivs:
;VorgabenDatei := "Pfad ... \Bestandsvorgaben.txt"
; Auflistung zum Ausprobieren:
VorgabenDatei := A_ScriptDir . "\Bestandsvorgaben.txt"

^!F8::Run, Notepad.exe, %VorgabenDatei%

; Vorlagen und Auswahlen aufrufen und einlesen
F8::
Auswahlfenster:
Auswahl := FileExist(AuswahlDatei) ? FileOpen(AuswahlDatei, "r").Read() : ""
If !(File := FileOpen(VorgabenDatei, "r")){
   MsgBox, 16, Fehler!, Die Datei %VorgabenDatei% konnte nicht geöffnet werden!
;   ExitApp
}
Vorgaben := StrSplit(File.Read(), "`n", "`r")
File.Close()

; Auswahlfenster erstellen und anzeigen
Rows := (L := Vorgaben.Length()) > 10 ? 10 : L
GuiText_1 := "Wählen Sie hier den Standard für das nächste Umbenennungsprojekt aus!"
Gui, Margin, 20, 20
Gui, Font, s10 , Verdana
Gui, Add, Text, xm w350, %GuiText_1%
Gui, Add, ListView, xm wp r%Rows% -Multi vBestandAuswahl Sort, Bestand|Signatur|Index
For Each, Vorgabe In Vorgaben
{
   Felder := StrSplit(Vorgabe, "`t")
   Option := (Felder[1] = Auswahl) ? "Focus Select" : ""
   LV_Add(Option, Felder*)
}
Loop, % LV_GetCount("Column")
   LV_ModifyCol(A_Index, "AutoHdr")

Gui, Add, Edit, cblue    xm  h25   w100  vAktSignEingabe, ;%Auswahl%
Gui, Add, Edit, cblue    x135  yp  h25  w70  vSignEingabe, ;%SignVorlage%
Gui, Add, Edit, cblue    x220  yp  h25  w70  vIndexEingabe, ;%IndexVorlage%
Gui, Add, Text, x123     yp+5    h25   w15  , _
Gui, Add, Text, x210     yp    h25   w15  , -

Gui, Add, Button, xm  h30 w100 Default gAnwenden, Anwenden
; Button "Neu Erstellen"  wird in der Standardversion auskommentiert
Gui, Add, Button, x145 yp h30 w100 gNeuerstellen, Neu Erstellen
Gui, Add, Button, x270 yp h30 w100 gAbbrechen, Abbrechen

Menu, Tray, Icon, , , 1
GuiControl, Focus, BestandAuswahl
Gui, Show, x100 y100, Signierungsvorlagen
Return

;------------------------------------------------------------------------
; Auswahl übernehmen
Anwenden:
If !(Row := LV_GetNext())
{
   MsgBox, 16, Fehler!, Bitte wählen Sie einen Bestand aus!
   GuiControl, Focus, BestandAuswahl
   Return
}
LV_GetText(AktSign, Row, 1)
LV_GetText(SignVorlage, Row, 2)
LV_GetText(IndexVorlage, Row, 3)
StellenSign := StrLen(SignVorlage)
StellenIndex := StrLen(IndexVorlage)
LetzteSign := 0
; hier müßte wohl auch die externe Abspeicherung stattfinden!
If (AktSign <> Auswahl)
{
   Auswahl := AktSign
   File := FileOpen(AuswahlDatei, "w")
   File.Write(Auswahl)
   File.Close()
}
Gui, Destroy
Gosub, Anzeige
Menu, Tray, Icon, , , 0
Return

;------------------------------------------------------------------------
; 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)
   If (AktSignEingabe = AktSignLV)
   {
      MsgBox, 16, Fehler!, Der Bestandsname 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)
{
   MsgBox, 16, Fehler!, Der Indexvorgabe darf nicht leer sein!
   GuiControl, Focus, IndexEingabe
   Return
}
; Alles OK, verarbeiten
AktSignNeu := AktSignEingabe
StellenSignNeu := StrLen(SignEingabe)
StellenIndexNeu := StrLen(IndexEingabe)
SignVorlageNeu := Format("{:0" . StellenSignNeu . "}", 0)
IndexVorlageNeu := Format("{:0" . StellenIndexNeu . "}", 0)
FileAppend , `n%AktSignNeu% `t%SignVorlageNeu% `t%IndexVorlageNeu%, %VorgabenDatei%

; Auswahldatei updaten
VorschauMsgNeu = %AktSignNeu%_%SignVorlageNeu%-%IndexVorlageNeu%
AktSign := AktSignNeu
StellenSign := StellenSignNeu
StellenIndex := StellenIndexNeu
If (AktSign <> Auswahl)
{
   Auswahl := AktSign
   File := FileOpen(AuswahlDatei, "w")
   File.Write(Auswahl)
   File.Close()
}
; Abschluß-Message
Gui, Destroy
MsgAnzeige = 
(
Ihre neu erstellte Vorlage %VorschauMsgNeu% wurde abgespeichert.
Möchten Sie zurück zur Vorlagenauswahl?
)
MsgBox, 4, , %MsgAnzeige%
   IfMsgBox Yes
      goto, Auswahlfenster
   else
      gosub, Anzeige
Return

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

;------------------------------------------------------------------------
; Vorschau mit Progresselement statt MsgBox, damit Schrift formatierbar ist
^F8::
Anzeige:
VorschauSign := Format("{:0" . StellenSign . "}", 1)
VorschauIndex := Format("{:0" . StellenIndex . "}", 0)
VorschauMsg = %AktSign%_%VorschauSign%-%VorschauIndex%
Progress, m2 fs12 zh0 ct0000ff CWffffff, %VorschauMsg%, , Vorschau, Verdana
SetTimer, ProgressOff, 1500
Return

ProgressOff:
Progress, Off
Return

;------------------------------------------------------------------------
; Bilder umbenennen im Windows Explorer
#IfWinActive ahk_group Explorer

<!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
   }
   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%
   ; 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
   }
   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 := ""
Return

#If ; Ende des bedingten HotKey
;------------------------------------------------------------------------
; Beenden des Scriptes
Escape::
ExitApp
Return
Viele Grüße von Meister Lampe
just me
Posts: 6511
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Optimierung Umbenennungstool

26 Mar 2019, 02:11

Moin,

nein, dieser Fall ist nicht besonders gemein.

Code: Select all

Run, Ziel [, Arbeitsverz, Optionen, AusgabeVarPID]
Zähle mal die Kommata und schau Dir an, was die einzelnen Paramater bedeuten.
Ziel
Damit Parameter übergeben werden können, müssen sie unmittelbar nach dem Programm- oder Dokumentnamen erfolgen. Wenn ein Parameter Leerzeichen enthält, sollte man ihn sicherheitshalber in Anführungszeichen setzen (auch wenn es in einigen Fällen ohne sie funktionieren würde).

Wenn Du eine Subroutine (ein Modul) aufrufen willst, nimm Gosub, weil es genau dafür gedacht ist. Wenn Dir der Aufruf die aktuelle Routine zu lange blockieren würde, nimm SetTimer.

Grüße
just me
User avatar
Meister Lampe
Posts: 141
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

29 Mar 2019, 05:17

Hallo just me!

Nach ein paar individuellen Anpassungen, Erstellung einer Anleitung und Einsetzung der Befehle

Code: Select all

^!F8::Run, %VorgabenDatei%
!F8::Run, %Anleitung%
bin ich jetzt fast fertig.
Eine Schwierigkeit habe ich noch, die mir erst beim Testen an mehreren der anderen Computer im Büro aufgefallen ist:
Das Laufwerk im Intranet, auf dem die Datei Bestandsvorgaben.txt hinterlegt ist, hat zwar den festen Namen Public, aber nicht auf allen Computern denselben Laufwerksbuchstaben.

Code: Select all

VorgabenDatei := "P:\Ordner\Unterordner\Unterunterordner\Bestandsvorgaben.txt
So funtioniert es bei einigen PCs, auch meinem eigenen, weshalb ich das bis jett noch nicht bemerkte.
Es gibt eben auch welche, da heißt das Laufwerk Public z.B. H:\ statt P:\.
Wie kann ich die Datei dann unabhängig davon aufrufen?

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

Re: Optimierung Umbenennungstool

29 Mar 2019, 07:04

Moin,

probier es mal mit UNC.

Grüße, just me
User avatar
Meister Lampe
Posts: 141
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

03 Apr 2019, 17:08

Hallo just me!
probier es mal mit UNC.
Genau das wars. Jetzt klappt es prima. Damit ist dieser (wichtigste) Teil des Scriptes eigentlich abgeschlossen. Was nicht bedeutet, daß mir nicht noch irgendwann Verbesserungsmöglichkeiten einfallen werden, die ich dann auch umsetzen will...
Herzlichen Dank für Deine Hilfe!

Hat der AHK eigentlich außer dem Progressfenster auch noch eine Sanduhr oder so einen Kreisel o.ä.? Halt nur, damit man sieht, wenn er noch am Arbeiten ist. Manchmal dauern die Umbenennungen relativ lange bzw. es ist lange keine Veränderung zu sehen, weil alles im Hintergrund passiert.
-----
Ich habe da aber noch eine andere Frage, die den vorigen ähnelt:
Diesmal geht es um bereits mit der richtigen Nummer versehene Bilder. Nur ist das Format dort oft nicht einheitlich, u.a. auch, weil verschiedene Leute an den größeren Beständen arbeiten und dann z.B. führende Nullen vergessen einzufügen. Im aktuellen Fall geht es um ein Format nach dem Schema 'A 123_123456.jpg' oder 'A 123_123456a.jpg' , also ein Bestandname wie oben die AktSign, ein Unterstrich, eine (hier sechsstellige) Nummer, optional (ohne ein Trennzeichen!) ein Buchstabenindex dahinter. Ziel ist also, daß man die fehlerhaft formatierten Bilder markiert und diese dann mit F6 in des vorgegebene Format gebracht werden. Dabei werden führende Nullen so dazugesetzt, daß es 6 Zahlzeichen werden. Falls noch ein Buchstabe dahintersteht, wird dieser nicht mitgezählt!
Ich hatte dafür aus älteren Scripts etwas hervorgekramt und versucht, das mit den Erkenntnissen, die ich mittlerweile von Dir mitbekommen habe, umzuschreiben, aber das hat noch nicht ganz geklappt.

Code: Select all

F6::
   Clipboard := ""
   SendInput, ^c
   Clipwait, 1
 
   DateienAuslese := Clipboard
   StellenZahl := 6
   
   Loop, Parse, Dateienauslese, `n, `r
   {
      SplitPath, A_LoopField, , Verzeichnis, Erweiterung, AlterName
      NameArray := StrSplit(AlterName, `_)
      NewAktname := NameArray[1]
      NewSign := Format("{:0" . StellenZahl . "}", NameArray[2])
      FileMove, %A_LoopField%, %Verzeichnis%\%NewAktname%_%NewSign%.%Erweiterung%
   }  
return 
Schwierigkeiten:
1.) Bei der Aufteilung des Dateinamens geht der erste Teil ganz oder teilweise verloren, insbesondere die Ziffern nach dem Leerzeichen, obwohl als Trennzeichen für das StrSplit der Unterstrich angegeben ist, nicht der Leerraum.
2.) Die vorliegende Nummer bleibt nicht erhalten, sondern wird hier durch als Länge angegebene Zahl von Nullen ersetzt.
3.) Muß ich eigentlich zum Aufrufen der Strings im Array NameArray1 oder NameArray[1] schreiben? Ich hatte es bisher nach der ertsen Version gemacht, im Tutorial steht in den Beispielen die zweite. Was ist der Unterschied?

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

Re: Optimierung Umbenennungstool

04 Apr 2019, 02:55

Moin Meister Lampe,

ich kann Dir nur raten, die Hilfe und besonders die Beispiele in der Hilfe aufmerksamer zu lesen. Zu StrSplit() gibt es z.B. Folgendes:

Code: Select all

StrSplit(Farben, ",")
Wenn Du das mit Deinem Versuch vergleichst

Code: Select all

StrSplit(AlterName, `_)
sollte Dir auffallen, dass der zweite Parameter in Anführungszeichen eingeschlossen wird, falls es sich um Text handelt. Deshalb:

Code: Select all

StrSplit(AlterName, "_")
Der Grund ist ebenso logisch wie einfach: Funktionen sind Ausdrücke (expressions) und in Ausdrücken wird Text immer in Anführungszeichen eingeschlossen.

Zugriff auf Arrayelemente:
Für den Zugriff auf Arrayelemente gibt es in AHK zwei Schreibweisen:
  1. Objektsyntax:
    Hier wird der Schlüsselname des Elements abgetrennt durch einen Punkt (.) direkt an den Arraynamen angehängt:

    Code: Select all

    NameArray.1
  2. Arraysyntax:
    Hier wird der Schlüsselname in eckige Klammern eingeschlossen und an den Arraynamen angehängt:

    Code: Select all

    NameArray[1]
    Zwischen den Klammern steht ein Ausdruck, und wie bei allen Ausdrücken gilt auch hier: Wenn der Schlüsselname keine Zahl ist, muss er in Anführungszeichen eingeschlossen werden.
Das 'althergebrachte' NameArray1 passt nur auf die sogenannten Pseudoarrays, wie sie von der Anweisung StringSplit erzeugt werden, nicht aber von der Funktion StrSplit().
User avatar
Meister Lampe
Posts: 141
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

08 Apr 2019, 07:19

Hallo just me!

Ich habe das nochmals genauer verglichen. In dem älteren Script, das ich hevorgeholt und etwas angepaßt hatte, wurde der StringSplit-Befehl verwendet und ich habe die Parameter daraus dann in Klammern von StrSplit kopiert. Dort benötigte man ja keine Anführungszeichen.
Mittlerweile klappt das eigentlich ganz gut:

Code: Select all

F6::
   Clipboard := ""
   SendInput, ^c
   Clipwait, 1
 
   DateienAuslese := Clipboard
   StellenZahl := 6
   
   Loop, Parse, Dateienauslese, `n, `r
   {
      SplitPath, A_LoopField, , Verzeichnis, Erweiterung, AlterName
      NameArray := StrSplit(AlterName, "_")
      NewAktname := NameArray[1]
      NewSign := Format("{:0" . StellenZahl . "}", NameArray[2])
      FileMove, %A_LoopField%, %Verzeichnis%\%NewAktname%_%NewSign%.%Erweiterung%
   }  
return  
Nur hatte ich im letzten Post ja angedeutet, daß die Signaturen hier 6 Stellen haben können und optional noch einen Buchstaben hintendran. Da ist dann aber kein Trennzeichen dazwischen. Gibt es eine Möglichkeit, Ziffern und Buchstaben zu unterscheiden, damit ich das letzte Zeichen, falls es ein Buchstaben ist, ignorieren kann? Oder müßte ich dazu erst die gesamte Zeichenkette auftrennen und mit so etwas wie "If not (0,1,2,3,4,5,6,7,8,9)" durchgehen?

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

Re: Optimierung Umbenennungstool

08 Apr 2019, 09:14

Moin Meister Lampe,

Du hast weiter oben Folgendes gesagt:
Im aktuellen Fall geht es um ein Format nach dem Schema 'A 123_123456.jpg' oder 'A 123_123456a.jpg' , also ein Bestandname wie oben die AktSign, ein Unterstrich, eine (hier sechsstellige) Nummer, optional (ohne ein Trennzeichen!) ein Buchstabenindex dahinter.
Ich verstehe die Bedingungen deshalb so:
Wenn im Dateinamen auf den ersten Unterstrich maximal 5 Ziffern und ein oder kein Buchstabe folgen, sind die Ziffern auf 6 Stellen mit vorangestellten Nullen aufzufüllen. Der Buchstabe wird 'ignoriert' heißt für mich 'entfernt'.

Code: Select all

   StellenZahl := 6
   Max := StellenZahl - 1
   Loop, Parse, Dateienauslese, `n, `r
   {
      SplitPath, A_LoopField, , Verzeichnis, Erweiterung, AlterName
      NameArray := StrSplit(AlterName, "_")
      NewAktname := NameArray[1]
      If RegExMatch(NameArray[2], "^(\d{1," . Max . "})\D?$", Match) ; wenn NameArray[2] 1 - Max Ziffern und ein oder kein Zeichen enthält, das keine Ziffer ist ...
      {
         NewSign := Format("{:0" . StellenZahl . "}", Match1)
         FileMove, %A_LoopField%, %Verzeichnis%\%NewAktname%_%NewSign%.%Erweiterung%
      }      	
   }  
*nicht getestet*
User avatar
Meister Lampe
Posts: 141
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

11 Apr 2019, 16:10

Hallo just me!
Ich verstehe die Bedingungen deshalb so:
Wenn im Dateinamen auf den ersten Unterstrich maximal 5 Ziffern und ein oder kein Buchstabe folgen, sind die Ziffern auf 6 Stellen mit vorangestellten Nullen aufzufüllen. Der Buchstabe wird 'ignoriert' heißt für mich 'entfernt'.
Ich habe das wohl etwas mißverständlich formuliert, denn so war es eigentlich nicht gemeint. Diese Signaturen stammen aus einem Fotoarchiv, u.a. auch Fotonegative. Die Älteren hier erinnern sich vielleicht noch: die waren jeweils entweder mit glatten Zahlen oder mit einem zusätzlichen Buchstabenindex versehen, jenachdem, wie der Film gerade in der Kamera lag oder in die Entwicklung gekommen ist. Der Fotograf hat teilweise diese Nummern übernommen, teils aber auch Aufnahmeserien desselben Objekts mit Buchstaben indiziert. Diese werden in der Signatur übernommen, aber die laufende Zahl davor bleibt immer 6stellig. Es würde auch Fehler geben, da es Bilder gibt, die sich nur durch den Buchstabenindex unterscheiden.

Ich müßte also die Zeichenkette erst nach einem Nicht-Zahlzeichen (wohl mit ^/D) durchsuchen, dort auftrennen, den 1.Teil auf die vorgegebene Stellenzahl (hier 6) trimmen und den 2.Teil wieder anhängen. Ich habe mir Deinen Code und die Erläuterungen in der Hilfe zu dem RegExMatch nochmal genauer angesehen. Und ich habe dann noch was anderes gefunden, mit dem es vielleicht auch gehen könnte:

Code: Select all

NewSign := RegExReplace(NameArray[2],
Allerdings komme ich da dann nicht mehr weiter. Ich nehme mal an, daß man ^/D hier genauso einsetzen könnte und dann im nächsten Parameter (der Beschreibung der Ersatzkette) auch genauso die Formatierung vornehmen kann. Aber das, was Du in Deinem letzten Post geschrieben hast, kann ich ja da nicht einfach reinkopieren. ;)
Auch weiß ich nicht, ob ich da eine Fallunterscheidung machen muß, falls die Suche negativ ausfällt, es also keinen Buchstaben am Ende gibt.

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

Re: Optimierung Umbenennungstool

12 Apr 2019, 01:59

Hallo Meister Lampe,

wenn ich es jetzt richtig verstehe, sollte es reichen, das 'Nichtziffernzeichen' im RegExMatch() in einem eigenen Teiltreffer zu speichern ((\D?)):

Code: Select all

      If RegExMatch(NameArray[2], "^(\d{1," . Max . "})(\D?)$", Match) ; wenn NameArray[2] 1 - Max Ziffern und ein oder kein Zeichen enthält, das keine Ziffer ist ...
      {
         NewSign := Format("{:0" . StellenZahl . "}", Match1) . Match2
         FileMove, %A_LoopField%, %Verzeichnis%\%NewAktname%_%NewSign%.%Erweiterung%
      }      	
Grüße,
just me

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: Bing [Bot] and 19 guests