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

15 Apr 2019, 12:41

Hallo just me!

Jetzt klappt es soweit.
1.) Ich habe gestern allerdings erfahren, daß die Leute, die diese Bilder eingescannt haben, manchmal auch zuviele Nullen, statt zuwenig vorne angefügt hatten, so daß es jetzt schon 7 Stellen sind. Man müßte also zuerst alle Nullen, die links stehen, entfernen und danach wieder auf 6 Stellen auffüllen. Oder geht das auch "in einem Rutsch" mit dem jetzigen Script und läßt sich in die Formatierungszeile

Code: Select all

If RegExMatch(NameArray[2], "^(\d{1," . Max . "})(\D?)$", Match)
einfügen?

2.) Mich würde auch interessieren, wie man mehrere unterschiedliche Trennzeichen optional eingibt bzw. ausschließt. Das wäre praktisch, falls jemand mal einen Bindestrich statt einem Unterstrich verwendet hat. Dann sollte aber nicht vorne der Bestandsname mit dem doppelten Bindestrich aufgetrennt werden.

3.) Eine weitere Frage: Ich habe mir eine kleine animierte Gif heruntergeladen und mit

Code: Select all

Wartesymbol := A_ScriptDir .  "\Farbenscheibe.gif"
...
SplashImage , %Wartesymbol%
... Umbenennungsschleife
SplashImage, Off
in das Script gefügt. Klappt auch ganz gut, nur dreht sich das Symbol nicht mehr. Wenn ich es mit einem normalen Bildprogramm aufrufe, aber schon. Wie animiere ich das auch im Aufruf über das AHK-Script?

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

Re: Optimierung Umbenennungstool

16 Apr 2019, 07:38

Moin,

Wenn Du keine zusätzlichen Fehlerprüfungen eingebaut hast, nimmt das Skript beliebige Dateinamen, die zumindest einen Unterstrich und im zweiten Splitelement 1 - 5 Ziffern gefolgt von maximal 1 Buchstaben enthalten. Für das erste Splitelement sind keine Prüfungen vorhanden.

zu 1.): Du kannst natürlich auch nach 1 - 5 Ziffern mit beliebig vielen vorangestellten Nullen suchen:

Code: Select all

If RegExMatch(NameArray[2], "^(0*[1-9]\d{0," . (StellenZahl - 2) . "})(\D?)$", Match) ; wenn NameArray[2] 1 - Max Ziffern und ein oder kein Zeichen enthält, das keine Ziffer ist ...
{
   ; MsgBox, % StrLen(Match1) . ": " . Match1 . " - " . Match2
   If !(StrLen(Match1) = StellenZahl)
   {
      Match1 += 0
      If !(StrLen(Match1) < StellenZahl)
      {
         NewSign := Format("{:0" . StellenZahl . "}", Match1) . Match2
         FileMove, %A_LoopField%, %Verzeichnis%\%NewAktname%_%NewSign%.%Erweiterung%
      }
   }
}
*ungetestet*
User avatar
Meister Lampe
Posts: 228
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

25 Apr 2019, 17:25

Hallo just me!

Über die Osterfeiertage habe ich mir etwas Pause gegönnt, aber jetzt Deinen letzten Vorschlag genauer studiert. Ich habe den Code mal in das ganze Script eingefügt, aber da tut sich jetzt leider gar nichts mehr.

Code: Select all

+F6::
   Clipboard := ""
   SendInput, ^c
   Clipwait, 1
 
   DateienAuslese := Clipboard
   StellenZahl := 6
   Max := StellenZahl
    Loop, Parse, Dateienauslese, `n, `r
   {
      SplitPath, A_LoopField, , Verzeichnis, Erweiterung, AlterName
      NameArray := StrSplit(AlterName, "_")
      NewAktname := NameArray[1]
      If RegExMatch(NameArray[2], "^(0*[1-9]\d{0," . (StellenZahl - 2) . "})(\D?)$", Match) ; wenn NameArray[2] 1 - Max Ziffern und ein oder kein Zeichen enthält, das keine Ziffer ist ...
   {
   ; MsgBox, % StrLen(Match1) . ": " . Match1 . " - " . Match2
   If !(StrLen(Match1) = StellenZahl)
   {
      Match1 += 0
      If !(StrLen(Match1) < StellenZahl)
      {
         NewSign := Format("{:0" . StellenZahl . "}", Match1) . Match2
         FileMove, %A_LoopField%, %Verzeichnis%\%NewAktname%_%NewSign%.%Erweiterung%
      }
   }
}
   }
return
Auch das bisher bereits einwandfrei funktionierende Auffüllen von Signaturen mit weniger als 6 Stellen mit Nullen klappt nicht. Wenn ich allerdings die zwei Blöcke mit den If !(StrLen(Match1)-Bedingung auskommentiere, wird wenigsten diese Aufgabe wieder ausgeführt.
Wenn ich den Code richtig "entschlüsselt" habe, soll das If RegExMatch die isolierte Nummer (NameArray[2]) von vorne durchgehen, und zwar ab der ersten Ziffer, die keine Null ist bis zum Ende und in Match1 speichern, einen eventuell dabei am Ende aufgetauchten Buchstaben in Match2.
1.) Habe ich das soweit korrekt erkannt?
2.) Wenn ich im Dateinamen statt des Endbuchstabens ein Minuszeichen setzte, klappt es auch bei dem älteren Script nicht. Dabei steht im Tutorial, daß \D für alle Zeichen die keine Ziffern sind, stehen soll.
3.) Umgekehrt scheint es aber nichts auszumachen, ob in der If RegExMatch-Funktion . Max . oder . (StellenZahl-2) . oder gar . (StellenZahl-6) . steht. Was soll das dann bewirken?

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

Re: Optimierung Umbenennungstool

26 Apr 2019, 02:44

Moin,

zumindest eine 'Verneinung' ist falsch:

Code: Select all

   If !(StrLen(Match1) = StellenZahl)
   {
      Match1 += 0
      If (StrLen(Match1) < StellenZahl) ; <<<<< ! (not) entfernt
      {
         ...
Grüße, just me
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Optimierung Umbenennungstool

26 Apr 2019, 03:56

Noch eine Korrektur, nachdem ich Deine Fragen noch einmal gelesen habe:

1.) RegExMatch() soll das untersuchen, was durch StrSplit() in NameArray[2] gelandet ist. Es soll einen Treffer finden, wenn
  1. ^ am Anfang
  2. 0* beliebig viele oder auch keine Nullen stehen,
  3. [1-9] denen eine der Ziffern 1 - 9 folgt,
  4. \d{0," . (StellenZahl - 2) . "} der wiederum 0 - Stellenzahl - 2 Ziffern folgen (eine Ziffer ist bereits durch den vorangehenden Treffer verbraucht)
  5. (\D?) und eine oder keine 'Nichtziffer'
  6. $ als letztes Zeichen.
Die Prüfung auf Stellenzahl - 2 in 4. ist nicht immer korrekt. Man sollte das deshalb vereinfachen:

Code: Select all

      ; Wenn NameArray[2] mit einer oder mehreren Ziffer(n) beginnt und mit einer oder keiner 'Nichtziffer' endet ...
      If RegExMatch(NameArray[2], "^(\d+)(\D?)$", Match)
      {
         ; MsgBox, % StrLen(Match1) . ": " . Match1 . "   <>   " . Match2
         If !(StrLen(Match1) = StellenZahl)
         {
            Match1 += 0 ; führende Nullen entfernen
            If (StrLen(Match1) < StellenZahl)
            {
               NewSign := Format("{:0" . StellenZahl . "}", Match1) . Match2
               ; MsgBox, % StrLen(NewSign) . ": " . NewSign . "   <>   " . Match2
               FileMove, %A_LoopField%, %Verzeichnis%\%NewAktname%_%NewSign%.%Erweiterung%
            }
         }
      }
*nur oberflächlich getestet*

2.) Ich habe mit dem - Zeichen keine Probleme, wenn ich es direkt in einen Teststrig schreibe.

3.) Siehe 1.)
User avatar
Meister Lampe
Posts: 228
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

02 May 2019, 17:31

Hallo just me!

Jetzt funktioniert es.
Mittlerweile bin ich dabei, die beiden Scripts zu verknüpfen.
Folgendes habe ich dazu bereits hinbekommen bzw. bin noch daran:
1.) Man kann jetzt auch Bestandsnamen der Form W 123--2_1234 eingeben, also ohne Index. Dazu wird in das Indexfeld ein Bindestrich gesetzt.
2.) Das wird dann auch in der Liste abgespeichert und beim Gebrauch als StellenIndex = 0 ausgewertet.
3.) Durch entsprechende Abfragen wie If (IndexEingabe = "-") wurde das auch in der Anzeige berücksichtigt.
4.) Eine Abfrage If (StellenIndex = "0") habe ich auch schon in das eigentliche Umbenennungsmodul eingefügt. Da soll ein zweites entstehen mit Namen "OhneIndex", das eben nur die Signaturen durchzählt. Das müßte eigentlich dasselbe sein, wie der Teil, der beim anderen für die Zählung der Indizes sorgt. Ich habe das auch entsprechend mit den Variablen umzubenennen versucht, klappt aber nicht immer.
5.) Das Modul zum Trimmen der Signaturen übernimmt jetzt die Parameter von dem jeweils vorher aus der Bestandsliste ausgewählten Bestand. Allerdings geht das bisher nur bei Bestandsnamen ohne Index (wie oben beschrieben jetzt möglich einzugeben). Hier ist umgekehrt vorgesehen, das auch für Signaturen mit Indizes verfügbar zu machen. Ein erster Entwurf (GoSub Trimmen_mI) schachtelt zwei Aufspaltungen von Strings ineinander und kommt dem Soll schon recht nahe.
6.) Dazu komme ich zurück mit meiner Frage vom 15.April:
Mich würde auch interessieren, wie man mehrere unterschiedliche Trennzeichen optional eingibt bzw. ausschließt.
Am einfachsten wäre es, den ganzen String gleich in drei Teile zerlegen zu können, in dem man als Trennzeichen Unterstrich oder Bindestrich angibt. Dabei sollte man aber den doppelten Bindestrich ausschließen, denn dieser ist bei uns häufig Bestandteil des Bestandsnamens. Er steht dort für den Schrägstrich /, in den er erst später bei der Onlinestellung der Scans umgewandelt wird.
7.) Im Umbenennen-Modul habe ich versucht, das animierte Wartesymbol, genannt Farbenscheibe.gif einzufügen. Das bewegt sich aber beim Aufruf aus dem Script nicht mehr. Ich habe die entsprechenden SplashImage-Einträge im Script jetzt erst einmal auskommentiert, damit sie nicht beim Ablauf stören.
Und hier jetzt das ganze 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 Public-Order vom Infranet des Archivs:
VorgabenDatei := A_ScriptDir . "\Bestandsvorgaben.txt"
;VorgabenDatei := "\\STAF-SRV1\Public\Datenaustausch\BSchuehly\Tools-AutoHotkey\Bestandsvorgaben.txt" 
Anleitung := A_ScriptDir . "\Erläuterungen AHK-Tool StAF_3.1.pdf"
;Anleitung := "\\STAF-SRV1\Public\Datenaustausch\BSchuehly\Tools-AutoHotkey\Erläuterungen AHK-Tool StAF_3.1.pdf"
Wartesymbol := A_ScriptDir .  "\Farbenscheibe.gif"
;Wartesymbol := "\\STAF-SRV1\Public\Datenaustausch\BSchuehly\Tools-AutoHotkey\Farbenscheibe.gif"

^!F8::Run, %VorgabenDatei%
!F8::Run, %Anleitung%

; 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    x137  yp  h25  w70  vSignEingabe, ;%SignVorlage%
Gui, Add, Edit, cblue    x224  yp  h25  w70  vIndexEingabe, ;%IndexVorlage%
Gui, Add, Text, x124     yp+5    h25   w13 , % chr(863)
Gui, Add, Text, x211     yp+4    h25   w13  , % chr(862)

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)
If (IndexVorlage = "-")
{
   StellenIndex := 0
}
else
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!, Die Indexvorgabe darf nicht leer sein!
   GuiControl, Focus, IndexEingabe
   Return
}

; Alles OK, verarbeiten
AktSignNeu := AktSignEingabe
StellenSignNeu := StrLen(SignEingabe)
SignVorlageNeu := Format("{:0" . StellenSignNeu . "}", 0)
If (IndexEingabe = "-")
{
   IndexVorlageNeu := "-"
}
else
{  
   StellenIndexNeu := StrLen(IndexEingabe)
   IndexVorlageNeu := Format("{:0" . StellenIndexNeu . "}", 0)
}
FileAppend , `n%AktSignNeu%`t%SignVorlageNeu%`t%IndexVorlageNeu%, %VorgabenDatei%

; Auswahldatei updaten
If (IndexVorlageNeu = "-")
{
   VorschauMsgNeu = %AktSignNeu%_%SignVorlageNeu%
   StellenIndex := "-"
   LetzteSign := "-"
}
else
{
   VorschauMsgNeu = %AktSignNeu%_%SignVorlageNeu%-%IndexVorlageNeu%
   StellenIndex := StellenIndexNeu
   LetzteSign := 0
}
AktSign := AktSignNeu
StellenSign := StellenSignNeu

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, 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
^F8::
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, %VorschauMsg%, , Vorschau, Verdana
}
SetTimer, ProgressOff, 1500
Return

ProgressOff:
Progress, Off
Return

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

;------------------------------------------------------------------------
; Indexnummerierung auf Eingabebefehl 'Signaturnummer, Startindex' in Inputbox 
; nach Auswahl der Dateien mit der Maus

<!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%
   
   If (StellenIndex = "0")  ; fragt, ob Index vorhanden und wählt die Routine aus
   {
      Gosub, OhneIndex
   }
   Else
   ; 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%
   
;SplashImage , %Wartesymbol%, B
   
   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++
   }
;SplashImage, Off
   ; 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

OhneIndex:      ; zum Umbenennen, wenn kein Index vorhanden
; Benutzereingaben zum Umbenennen holen
   LetzteSign := Format("{:1" . 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%
;SplashImage , %Wartesymbol%, B
   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 Sign, Item In SelectedItems {
      ItemPath := Item.Path
      SplitPath, ItemPath, DateiName, , Erweiterung
      LetzteSign := Format("{:0" . StellenSign . "}", LetzteSign)  ; Setzt Index auf 1 in 2 Ziffern
      Item.Name := AktSign . "_" . LetzteSign . (ShowExt ? "." . Erweiterung : "")
      LetzteSign++
   }
;SplashImage, Off
   ; Fertig
   ; Letzte Datei selektieren
   ; -> docs.microsoft.com/en-us/windows/desktop/shell/shellfolderview-selectitem
   ShellWin.Document.SelectItem(SelectedItems[Anzahl], 29)
   For Sign, Item In SelectedItems
      Item := ""
   ShellWin := ""

return

;------------------------------------------------------------------------
; Dateinamen mit F6 auf 6stellige Signaturnummer und optionalen Buchstabenindex trimmen
; Beispiel Pragher: W 134_070936A.tif

F6::
   Clipboard := ""
   SendInput, ^c
   Clipwait, 1
 
   DateienAuslese := Clipboard
   SignStellen := StellenSign
   IndexStellen := StellenIndex
   If !(StellenIndex = "0")
   {
      Gosub, Trimmen_mI
   }
   else
   Loop, Parse, Dateienauslese, `n, `r
   {
      SplitPath, A_LoopField, , Verzeichnis, Erweiterung, AlterName
      NameArray := StrSplit(AlterName, "_")
      NewAktname := NameArray[1]
       ; Wenn NameArray[2] mit einer oder mehreren Ziffer(n) beginnt und mit einer oder keiner 'Nichtziffer' endet ...
      If RegExMatch(NameArray[2], "^(\d+)(\D?)$", Match)
      {
         ; MsgBox, % StrLen(Match1) . ": " . Match1 . "   <>   " . Match2
         If !(StrLen(Match1) = SignStellen)
         {
            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%
            }
         }
      }      	
   }  
return

Trimmen_mI:
MsgBox Sie haben eine Vorlage mit Index gewählt

Loop, Parse, Dateienauslese, `n, `r
   {
      SplitPath, A_LoopField, , Verzeichnis, Erweiterung, AlterName
      NameArray := StrSplit(AlterName, "_")
      NewAktname := NameArray[1]
      SignArray := StrSplit(NameArray[2], "-")
      
       ; Wenn NameArray[2] mit einer oder mehreren Ziffer(n) beginnt und mit einer oder keiner 'Nichtziffer' endet ...
      If RegExMatch(SignArray[1], "^(\d+)(\D?)$", MatchSign)
      {
         ; MsgBox, % StrLen(MatchSign1) . ": " . MatchSign1 . "   <>   " . MatchSign2
         If !(StrLen(MatchSign1) = SignStellen)
         {
            MatchSign1 += 0 ; führende Nullen entfernen
            If (StrLen(MatchSign1) < SignStellen)
            {
               If RegExMatch(SignArray[2], "^(\d+)(\D?)$", MatchIndex)
               {
                  If !(StrLen(MatchIndex1) = IndexStellen)
                  {   
                     MatchIndex1 += 0 ; führende Nullen entfernen
                     If (StrLen(MatchIndex1) < IndexStellen)

                     {
                        NewSign := Format("{:0" . SignStellen . "}", MatchSign1) . MatchSign2
                        NewIndex := Format("{:0" . IndexStellen . "}", MatchIndex1) . MatchIndex2
                        ; MsgBox, % StrLen(NewSign) . ": " . NewSign . "   <>   " . MatchSign2
                        FileMove, %A_LoopField%, %Verzeichnis%\%NewAktname%_%NewSign%-%NewIndex%.%Erweiterung%
                     }
                  }
               }
            }
         }
      }      	
   }  
return

#If ; Ende des bedingten HotKey

+NumpadSub::Send _		; Unterstrich auch mit Shift+Minus vom Numpad
;------------------------------------------------------------------------
; Beenden des Scriptes
Escape::
MsgBox, 33, AHK schließen, Wollen Sie das AHK-Tool StAF wirklich schließen?
IfMsgBox Ok
   ExitApp
else
Return
Viele Grüße von Meister Lampe

PS.: Das ist das Gif, das ich heruntergeladen und unter dem Namen "Farbenscheibe.gif" abgespeichert habe: https://www.gif-paradies.de/gifs/gemischtes/effekte/effekt_0084.gif
User avatar
Meister Lampe
Posts: 228
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

09 May 2019, 17:23

Hallo just me!

Ich habe die letzten Tage nochmals an dem Script herumgedoktort, insbesondere an dem Teil zum Trimmen der zweiteiligen Signaturen mit Aktensignaturen und Indizes (Beispiel: A 95--1_0123-4567.tif). Was ich dabei gemerkt habe ist, daß man nach dem Entfernen der führenden Nullen mit

Code: Select all

Match1 += 0 ; führende Nullen entfernen
nicht

Code: Select all

If (StrLen(Match1) < StellenZahl)
{
 ...
}
sollte, sondern besser

Code: Select all

If !(StrLen(Match1) > StellenZahl)
{
...
}
Dann werden auch Nullen entfernt, wenn bereits die StellenZahl an Ziffern ungleich 0 danach steht: Aus 0123456 wird also 123456. In der alten Version wäre diese Null nicht entfernt worden.

Wenn die Signaturen das zweiteilige Format besitzen, dann hat der erste Teil (später NewSign) keine Buchstaben am Ende. Das macht das Trimmen um einiges einfacher. Eigentlich bräuchte man ja nur die beiden Zeilen

Code: Select all

SignArray[1] += 0
NewSign := Format("{:0" . SignStellen . "}", SignArray[1])
dazu. Nur habe ich noch nicht herausgefunden, wo ich die in das Script für den zweiten Teil setzen soll, der ja die FileMove-Schleife mit der Generierung des neuen Namens enthält.
Das Trimmen der Indizes scheint nämlich bereits ganz gut zu funktionieren.
Ich stelle den neu veränderten Teil des Scripts hier wieder herein:

Code: Select all

F6::
   Clipboard := ""
   SendInput, ^c
   Clipwait, 1
 
   DateienAuslese := Clipboard
   SignStellen := StellenSign
   IndexStellen := StellenIndex
   If !(StellenIndex = "0")
   {
      Gosub, Trimmen_mI
   }
   else
   Loop, Parse, Dateienauslese, `n, `r
   {
      SplitPath, A_LoopField, , Verzeichnis, Erweiterung, AlterName
      NameArray := StrSplit(AlterName, "_")
      NewAktname := NameArray[1]
       ; Wenn NameArray[2] mit einer oder mehreren Ziffer(n) beginnt und mit einer oder keiner 'Nichtziffer' endet ...
      If RegExMatch(NameArray[2], "^(\d+)(\D?)$", Match)
      {
         ; MsgBox, % StrLen(Match1) . ": " . Match1 . "   <>   " . Match2
         If !(StrLen(Match1) = SignStellen)
         {
            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%
            }
         }
      }      	
   }  
return

Trimmen_mI:
; Beispiel Landeskommissär: A 95--1_0123-4567.tif
;MsgBox Sie haben eine Vorlage mit Index gewählt

Loop, Parse, Dateienauslese, `n, `r
   {
      SplitPath, A_LoopField, , Verzeichnis, Erweiterung, AlterName
      NameArray := StrSplit(AlterName, "_")
      NewAktname := NameArray[1]
      SignArray := StrSplit(NameArray[2], "-")
      
      SignArray[1] += 0
      NewSign := Format("{:0" . SignStellen . "}", SignArray[1])
      
      ; Wenn SignArray[2] mit einer oder mehreren Ziffer(n) beginnt und mit einer oder keiner 'Nichtziffer' endet ...
      If RegExMatch(SignArray[2], "^(\d+)(\D?)$", Match)
      {
         If !(StrLen(Match1) = IndexStellen)
         {
            Match1 += 0 ; führende Nullen entfernen
            If !(StrLen(Match1) > IndexStellen)
            {
            NewIndex := Format("{:0" . IndexStellen . "}", Match1) . Match2
            FileMove, %A_LoopField%, %Verzeichnis%\%NewAktname%_%NewSign%-%NewIndex%.%Erweiterung%
            }
         }
      }
   }
return
Aber vielleicht geht es ja noch eleganter mit einer einzigen Zerlegung der Signatur, wie ich es im letzten Post unter Punkt 6.) angedeutet hatte.

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

Re: Optimierung Umbenennungstool

10 May 2019, 03:19

Moin,

zuerst einmal zum Thema 'animiertes GIF'. AHK kann damit an sich nicht umgehen. Die in der Doku beschriebenen 'Workarounds' finden sich hier.

Dann zum Thema 'unterschiedliche Namensformate':
  • Ich verstehe bisher nicht, warum Du in der neu erstellten Routine F6:: mit ^c und dem Clipboard arbeitest. Hat das einen besonderen Grund?
  • Die vorhandenen Routinen <!LButton::/OhneIndex: und F6::/Trimmen_mI: zeigen deutlich, was passieren kann, wenn man die Anforderungen an ein Skript nachträglich verändert. Es wäre deshalb gut, wenn Du Dir ein paar abschließende Gedanken über die möglichen unterschiedlichen Dateinamensformate machst und die hier anhand von Beispielen detailliert beschreibst. Ansonsten wird das zu der neben dem Spaghetticode meist gehassten Balkonprogrammiererei.
In Deinem letzten Beitrag verstehe ich z.B. nicht, wie Du von einem Beispielnamen A 95--1_0123-4567.tif auf "Aus 0123456 wird also 123456." kommst. Es ist deshalb wichtig, dass Deine Beschreibung konkrete Beispiele wie "Aus Originalname wird neuer Name" enthält.

Von der Idee

Code: Select all

If !(StrLen(Match1) > StellenZahl)
halte ich nichts, weil damit eine Signatur, die bereits im Original oder nach dem Trimmen zu vieler führender Nullen kürzer als Stellenzahl ist, nicht verändert wird. Für mich ist in diesem Zusammenhang auch noch die Frage offen: "Was soll passieren, wenn Namensbestandteile wie Index oder SIgnatur zu lang sind?

Grüße, just me
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Optimierung Umbenennungstool

10 May 2019, 05:49

Ich habe mich noch einmal intensiver mit dem Thema F6:: beschäftigt. Ich verstehe das jetzt so:
  • Die Routine soll Dateinamen, die weitgehend den Namenskonventionen entsprechen, nur hinsichtlich der Länge der Signatur- und Indexteile prüfen und ggf. korrigieren. Die Namen haben den Aufbau Name_Signatur-Index oder Name_Signatur, wobei es Dir lieb wäre wenn für beide Trennzeichen sowohl _ als auch - zulässig wären.
  • Für die Längenprüfung von Signatur und Index werden zunächst führende Nullen entfernt. Die sich danach ergebende Länge wird mit der jeweiligen Wunschlänge verglichen. Das kann folgende Resultate liefern:
    1. Die Länge ist kleiner als die Wunschlänge.
      Dann werden das Feld links mit Nullen auf die Wunschlänge aufgefüllt und der Dateiname angepasst.
    2. Die Länge ist gleich der Wunschlänge.
      Wenn führende Nullen entfernt wurden, wird der Dateiname angepasst. Ansonsten geschieht nichts.
    3. Die Länge ist größer als die Wunschlänge,
      Hier kann ich bisher keinen Plan erkennen.
  • Wegen der Trennung von F6:: und Trimmen_mI: gehe ich davon aus, dass eine Mischung von Dateien mit und ohne Index nicht gemeinsam verarbeitet werden soll. Weil nur die Stellenzahl aber nicht der Inhalt der Felder verändert wird, könnte man das aber auch durch interne Prüfungen regeln. Eine Stellenzahl für den Index würde dann nur berücksichtigt, wenn das Feld Bestandteil des Namens ist.
User avatar
Meister Lampe
Posts: 228
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

13 May 2019, 17:22

Hallo just me!
Ich verstehe bisher nicht, warum Du in der neu erstellten Routine F6:: mit ^c und dem Clipboard arbeitest. Hat das einen besonderen Grund?
Das hat einen quasi historischen Grund, aber keinen Sinn mehr. Das fällt mir auch jetzt erst auf, nachdem Du darauf hingewiesen hast. Ich hatte vormals eine Routine mit einer ähnlichen Funktion, die wie die erste Version meines Umbenennen-Tools, die Namen der Dateien kopierte, zerlegte/modifiziert zusammenfügte um sie dann wieder einzusetzen. Diese habe ich als Inspiration verwendet und dann die neuen Funktionen, welche ich mittlerweile kennengelernt habe, hereingefügt und nicht bemerkt, daß ich das Clipboard nicht mehr benötige.
Die vorhandenen Routinen <!LButton::/OhneIndex: und F6::/Trimmen_mI: zeigen deutlich, was passieren kann, wenn man die Anforderungen an ein Skript nachträglich verändert. Es wäre deshalb gut, wenn Du Dir ein paar abschließende Gedanken über die möglichen unterschiedlichen Dateinamensformate machst und die hier anhand von Beispielen detailliert beschreibst.
Der Stand war in etwa folgender:
  1. 1. Eine Routine zur halbautomatischen Vergabe von Namen an Dateien (Bildern aus Scanvorgängen), die aus einem (beliebigen) Bestandsnamen, Unterstrich, Aktensignatur, Bindestrich, Indix innerhalb der Akte bestehen nach dem Schema A 95--1_0123-4567.tif, vobei die Dateinamenerweiterung mit erhalten bleibt.<!LButton::
    2. Dazu wurde eine Gui angefertigt, in der ich verschiedene Bestandsnamen und unterschiedliche Formate definieren und abspeichern kann. F8::
    3. Nun entstand eine Routine, mit der ich bereits benannte Dateien auf ein bestimmtes Einheitsformat bringen kann - ohne die Nummer selber zu verändern. Hier war zunächst das Schema W 134_012345A.tif ein Beispiel: Der Bestandsname, eine Bildnummer, die auf 6 Stellen aufgefüllt werden soll und optional noch direkt anschließend einen Buchstaben führen kann. F6::
    4. Es bot sich an, diese Routine zu verallgemeinern und auch für längere oder kürzere Nummern einstellbar zu machen, weswegen ich im Erstellen-Code der Gui die Option eingefügt hatte, auch Bestandsnamen ohne Index abzuspeichern, in dem man einen Bindestrich in das Edit-Feld einfügt.
    5. Damit liegt es aber auch nahe, das ganze Tool in zwei Richtungen zu erweitern bzw. zu komplementieren:
    • Die Umbenennung oder Neusignierung von Dateien nach einem Format ohne Index: Hierzu hatte einen ersten Versuch begonnen, und mit der Fallunterscheidung

      Code: Select all

      If (StellenIndex = "0")  ; fragt, ob Index vorhanden und wählt die Routine aus
      {
         Gosub, OhneIndex
      }
      eine zweite Routine entworfen, die nur die Signatur durchzählen soll. OhneIndex
    • Das Trimmen von Dateinamen nach zweiteiligen Formaten.
Wegen der Trennung von F6:: und Trimmen_mI: gehe ich davon aus, dass eine Mischung von Dateien mit und ohne Index nicht gemeinsam verarbeitet werden soll. Weil nur die Stellenzahl aber nicht der Inhalt der Felder verändert wird, könnte man das aber auch durch interne Prüfungen regeln. Eine Stellenzahl für den Index würde dann nur berücksichtigt, wenn das Feld Bestandteil des Namens ist.
Die Trennung von F6:: und Trimmen_mI: beruht einzig darauf, daß ich bis jetzt keine andere Möglichkeit als die Fallunterscheidung und Verzweigung über zwei Routinen gesehen hatte.
Die Routine soll Dateinamen, die weitgehend den Namenskonventionen entsprechen, nur hinsichtlich der Länge der Signatur- und Indexteile prüfen und ggf. korrigieren. Die Namen haben den Aufbau Name_Signatur-Index oder Name_Signatur, wobei es Dir lieb wäre wenn für beide Trennzeichen sowohl _ als auch - zulässig wären.
Korrekt. Und zwar sollten deshalb beide erkannt werden, weil man sich nicht sicher sein kann, ob sie in der vorliegenden Signierung richtig gesetzt wurden. Das würde dann bei dem Vorgang korrigiert werden.

So, das wäre es erstmal für heute (ist gerade gestern geworden ;) ). Wegen der Längenprüfung und noch einem Detail, das mir eingefallen ist, muß ich mich nochmals melden, aber jetzt muß ich ins Bett.

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

Re: Optimierung Umbenennungstool

14 May 2019, 17:39

Hallo just me!

Hier also die "Fortsetzung" meines gestrigen Posts.
  • Für die Längenprüfung von Signatur und Index werden zunächst führende Nullen entfernt. Die sich danach ergebende Länge wird mit der jeweiligen Wunschlänge verglichen. Das kann folgende Resultate liefern:
  • 1. Die Länge ist kleiner als die Wunschlänge.
    Dann werden das Feld links mit Nullen auf die Wunschlänge aufgefüllt und der Dateiname angepasst.
  • 2. Die Länge ist gleich der Wunschlänge.
    Wenn führende Nullen entfernt wurden, wird der Dateiname angepasst. Ansonsten geschieht nichts.
  • 3. Die Länge ist größer als die Wunschlänge,
    Hier kann ich bisher keinen Plan erkennen.
1. Exakt, so ist das vorgesehen.
2. Dito.
3. Außer an überflüssige Nullen vornedran hatte ich bisher nicht gedacht, da in dem ersten Bestand (Format W 134_070936A.tif) , mit dem ich begonnen hatte, damit eigentlich nicht zu rechnen ist. Aber Du hast natürlich Recht. Es gibt nun zwei Möglichkeiten, wie solch ein Fall entstanden sein könnte. Entweder durch einen Fehler desjenigen, der die Nummern vorher vergeben hat. Oder man bräuchte wirklich mal eine Stelle mehr. Das kann selten auftreten und nur bei den zweiteiligen Signaturen: Ein Bestand wird digitalisiert, jede von z.B. <10000 Akten hat <100 Seiten, deshalb wählt man als Formatvorlage X--1_0000-000. Und am Ende kommt dann doch noch eine Akte mit >1000 Seiten. In diesem Fall würde man den Index nur dieser einen Signatur auf 4 Stellen erweitern. Das mindeste, mas man in F6:: machen sollte, ist eine Warnung mit einer MsgBox. Ich weiß nicht, ob man den beschriebenen Fall überhaupt berücksichtigen kann, da hier ja nicht nur ausnahmsweise eine zu lange Zeichenkette toleriert werden soll, sondern auch die kleineren Indexnummern aus derselben Signatur dieselbe Länge beibehalten sollten. Ich glaube, das wird zu kompliziert, auch noch zu implizieren, weil das Programm dazu ja jeweils signaturweise die Indizes prüfen müßte. Vielleicht sollte man auf das Trimmen und korrigieren der Indizes bei zweiteiligen Dateinamen ganz verzichten.

So, das wär's jetzt wieder für heute. wie gestern ist mir beim Schreiben wieder einiges auf- und eingefallen, morgen liefere ich das nach.

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

Re: Optimierung Umbenennungstool

15 May 2019, 04:56

Moin Meister,

ich warte noch ab bis Du sagst: Das war's für jetzt. Danach schaue ich mir das noch einmal an.

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

Re: Optimierung Umbenennungstool

21 May 2019, 17:58

Hallo just me!

Letzte Woche war auch noch einiges anderes los bei mir, da hatte ich keine Zeit für weitere Überlegungen hier.

Um nocheinmal das Problem 3. aufzugreifen: Eine Nummer hat nach dem Entfernen der führenden Nullen mehr Ziffern als die ausgewählte Vorlage es vorgibt. Vielleicht sollte man ja zuvor prüfen, ob es auch wirklich die Vorlage ist, die zu diesem Bestand gehört.
  • Bei eingliedrigen Dateinamen (Format W 134_012345A.tif) handelt es sich dann höchstwahrscheinlich um einen Fehler bei der Nummernvergabe. Am besten wäre, auf die mit dem fehlerhaften Namen würde in einer MsgBox hingewiesen, der Vorgang könnte aber bei den anderen Dateien abgeschlossen werden.
  • Bei zweigliedrigen Dateinamen (Format A 95--1_0123-4567.tif) gilt für den Signaturteil im Prinzip dasselbe. Hier ist allerdings nicht mit weiteren Buchstaben mittendrin zu rechnen.
  • Bei den Indizes der zweigliedrigen Dateinamen kann es - wie bereits beschrieben - kompliziert werden. Falls tatsächlich eine Signatur vorläge, bei dem wegen zuviel Elementen die Stellenzahl des Indexes erweitert werden mußte, dann muß das Script sie alle gleich behandeln und nicht etwa bei den niedrigeren Nummern die Nullen vorne wegnehmen.
  • Theoretisch könnte man natürlich auch grundsätzlich die Stellenzahl für den Index aus der Vorlage als Standardwert nehmen, die Dateien mit derselben Signatur zählen und deren Index falls nötig erweitern. Wenn dann trotzdem noch zu lange Zeichenketten auftreten, dann handelt es sich - wie oben - ebenfalls um einen Fehler.
Das ist vermutlich zu kompliziert und aufwendig. Und vielleicht nicht so wichtig wie bei den eingliedrigen Dateinamen.
Bei diesen ist mir aber aufgefallen, daß es insbesondere unter den alten Beständen auch welche gibt, die mehr als nur einen einzelnen Buchstaben hinten haben. Z.B. zerrissene Karten. Dann heißt es dort K 67_0034_1.Teil und K 67_0034_2.Teil oder _Vorderseite/ _Rückseite. Es wäre also schön, wenn nicht einfach auf das letzte Zeichen - und nur eines - hin geprüft würde, sondern das erste in der Zeichenkette, das keine Ziffer ist - egal, ob sich noch Ziffern danach anschließen. Z.Z. wird ein Name nämlich ignoriert, wenn mehr als ein Buchstabe o.a. hinter den Ziffen steht. Auch das war mit ein Grund, weshalb ich gleich zwei verschiedene Routinen erstellt hatte. Hier könnte eben noch ein Unterstrich auftauchen, der als Trennungszeichen erkannt würde und den namen dann als zweigliedrig interpretiert.

Wichtiger als das Trimmen der zweigliedrigen Namen, die ja immer mehr bereits durch mein Umbenennungstool erstellt werden und somit fehlerfrei sein sollten, ist wohl dieses auch für eingliedrige Namen fit zu machen. Ich hatte ja bereits damit begonnen und eine Fallunterscheidung zu diesem Zweck eingebaut, die auf eine zweite Routine leiten soll. Diese hatte ich auch begonnen, aber sie noch nicht funktionstüchtig. In dem Script hat sich seit dem letzten Post nichts geändert.

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

Re: Optimierung Umbenennungstool

22 May 2019, 04:00

Moin,

ich schaue mir das in Ruhe an. Eine letzte Verständnisfrage (ich habe immer noch Probleme damit, Deine Formulierungen für mich passend zu 'übersetzen'):

Für das 'Korrekturtool' gibt es auf der Eingangsseite zwei Dateinamensformate
  • Mit Index: Name[_/-]Signatur[-/_]Index
    Dabei bestehen Signatur und Index ausschließlich aus Ziffern.
  • Ohne Index: Name[_/-]Signatur[Sonstwas]
    Dabei besteht Signatur ausschließlich aus Ziffern und Sonstwas aus beliebigen Zeichen. Sonstwas soll nicht verändert werfen.
Ist das so?

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

Re: Optimierung Umbenennungstool

23 May 2019, 01:50

Hallo just me!
Ist das so?
Im Prinzip ja. Nur eine kleine Ergänzung und eine Verdeutlichung:
Bei den Formaten mit Index kann der Index ebenfalls ein [Sonstwas] haben.
Also:
  • Mit Index: Name[_/-]Signatur[-/_]Index[Sonstwas]
    Dabei bestehen Signatur und Index ausschließlich aus Ziffern und Sonstwas aus beliebigen Zeichen. Sonstwas soll nicht verändert werden.
Weiter gilt (weil sie hier in denselben eckigen Klammern geschreiben wurden:
Das [Sonstwas] ist optional, die Trennzeichen [_/-] bzw. [-/_] aber verpflichtend und deshalb auf der Eingangsseite bereits vorhanden.
[Sonstwas] fängt immer mit einem Nicht-Ziffernzeichen an, das kann auch mal eines dieser Trennzeichen sein.
Man könnte zuerst den Namen mit der Formatvorlage abgleichen, damit man sieht, wo genau die Signatur anfängt, da der Name ja ebenfalls Bindestrich/Unterstrich enthalten kann.

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

Re: Optimierung Umbenennungstool

23 May 2019, 03:46

Moin,

es tut mir leid, aber ich finde das schlichtweg wirr.

Dass _ und - auch innerhalb des Namens verwendet werden dürfen, macht es nicht leichter, wenn beide Zeichen auch als Trenner zwischen Name und Signatur bzw. Signatur und Index genutzt werden (durften).

Aber ok, man kann natürlich den Beginn des Dateinamens mit dem Namen der Formatvorlage abgleichen. Das stelle ich mir so vor:
1. Prüfen, ob der Dateiname mt dem Namen der Formatvorlage beginnt.
2. Das folgende Zeichen muss _ oder - sein.
3. Jetzt müssen Ziffern folgen.
4. Wenn auf die Ziffern ein - oder _ folgt, wird geprüft, auf darauf Ziffern folgen:
Wenn ja, handelt es sich um ein Format Name_Signatur-Index und die Längen von Signatur und Index müssen ggf. korrigiert werden.
Wenn nein, handelt es sich um ein Format Name_Signatur und die Länge der Signatur muss ggf. korrigiert werden.
5. Alle ggf. noch folgenden Zeichen werden unverändert übernommen.

Soweit die Theorie, eines Deiner Beispiele wirft das aber wieder über den Haufen: K 67_0034_1.Teil. Hier haben wir die Reihenfolge Name_Ziffern_ZifferSonstwas und damit eigentlich ein Name_Signatur_IndexSonstwas Format, wenn das zweite _ auch als Trennzeichen erlaubt werden soll. Mir fällt dazu nur ein, dass man bei Vorgabe von IndexStellen = 0 immer das Format Name_SignaturSonstwas unterstellt. Diese Vorgabe wäre dann für die korrekte Verarbeitung des Beispiels zwingend erforderlich.
User avatar
Meister Lampe
Posts: 228
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

23 May 2019, 16:46

Hallo just me!
ich finde das schlichtweg wirr.
Dann will ich versuchen, das etwas zu entwirren.
Durch die Auswahl der Formatvorlage mit F8 ist auch der Name festgelegt. Unabhängig, ob er noch weitere Trennzeichen enthält oder nicht. Das erste weitere, danach folgende Trennzeichen, ist gleichzeitig auch das vor der Signatur und soll im Ausgabeformat dann immer durch einen Unterstrich dargestellt werden.
Falls die Vorlage einen Index hat, ist liegt das zweite Trennzeichen zwischen der Signatur und dem Index und erscheint in der Ausgabe als ein Bindestrich. Alle weiteren Trennzeichen, die dahinter noch auftauchen sollten, gehören zu dem [Sonstwas].
Falls die Vorlage keinen Index hat, kommt das [Sonstwas] eben direkt hinter der Signatur.
Das Beispiel K 67_0034_1.Teil ist somit eindeutig als Dateiname ohne Index zu erkennen: In der Vorgabenliste wäre abgespeichert: { K 67 | 0000 | - } . Im Script wird das unter den Parametern StellenIndex := "-" bzw. IndexStellen := 0 geführt. Der Anhang _1.Teil gehört also nicht zu dem in der Vorlage deklariertem verpflichtenden Format für den Dateinamen, sondern ist ein optioniales Anhängsel, eben ein [Sonstwas]. Es gilt also genau das, was Du unten in Deinem Post auch sagst.

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

Re: Optimierung Umbenennungstool

24 May 2019, 02:19

Gut, dann also alles stur nach Vorlage und nichts automatisch. Ich melde mich wieder!

Gruß, just me
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Optimierung Umbenennungstool

26 May 2019, 03:43

OK, das ergibt sich für mich aus den zuletzt gesammelten Anforderungen:

Code: Select all

F6::
   If (AktSign = "")
   {
      MsgBox, 16, Fehler!, Es ist keine Bestandsvorlage ausgewählt!
      Return
   }

   Clipboard := ""
   SendInput, ^c
   Clipwait, 1

   If (ErrorLevel)
   {
      MsgBox, 16, Fehler!, Es sind keine Dateien ausgewählt!
      Return
   }

   DateienAuslese := Clipboard
   SignStellen := StellenSign
   IndexStellen := StellenIndex
   AktSignLen := StrLen(AktSign)

   NamensFehler := []
   Umbenennen := []
   AnzahlDateien := 0

   Loop, Parse, Dateienauslese, `n, `r
   {
      AnzahlDateien++
      SplitPath, A_LoopField, , Verzeichnis, Erweiterung, AlterName
      If (SubStr(AlterName, 1, AktSignLen) <> AktSign)
      {
         NamensFehler.Push(A_LoopField)
         Continue
      }
      Trenner := SubStr(AlterName, AktSignLen + 1, 1)
      If Trenner Not In _,-
      {
         NamensFehler.Push(A_LoopField)
         Continue
      }
      RestName := SubStr(AlterName, AktSignLen + 2)
      If !RegExMatch(RestName, "^(\d+)(.*)$", Rest)
      {
         NamensFehler.Push(A_LoopField)
         Continue
      }
      Signatur := Rest1
      If (StrLen(Rest1) <> SignStellen)
      {
         Signatur += 0
         If (StrLen(Signatur) <= SignStellen)
         {
            Signatur := Format("{:0" . SignStellen . "}", Signatur)
         }
         Else
         {
            NamensFehler.Push(A_LoopField)
            Continue
         }
      }
      If (IndexStellen = 0)
      {
         NeuerName := Verzeichnis . "\" . AktSign . "_" . Signatur . Rest2 . "." . Erweiterung
         Umbenennen.Push({Alt: A_LoopField, Neu: NeuerName})
         Continue
      }
      Trenner := SubStr(RestName, StrLen(Rest1) + 1, 1)
      If Trenner Not In _,-
      {
         NamensFehler.Push(A_LoopField)
         Continue
      }
      RestName := SubStr(RestName, StrLen(Rest1) + 2)
      If !RegExMatch(RestName, "^(\d+)(.*)$", Rest)
      {
         NamensFehler.Push(A_LoopField)
         Continue
      }
      Index := Rest1
      If (StrLen(Rest1) <> IndexStellen)
      {
         Index += 0
         If (StrLen(Index) <= IndexStellen)
         {
            Index := Format("{:0" . IndexStellen . "}", Index)
            NeuerName := Verzeichnis . "\" . AktSign . "_" . Signatur . "-" . Index . Rest2 . "." . Erweiterung
            Umbenennen.Push({Alt: A_LoopField, Neu: NeuerName})
            Continue
         }
         Else
         {
            NamensFehler.Push(A_LoopField)
            Continue
         }
      }
   }
   If NamensFehler.Length()
   {
      FehlerListe := ""
      For Each, Datei In NamensFehler
         FehlerListe .= Datei . "`n"
      If (Umbenennen.Length() = 0)
      {
         MsgBox, 16, Fehler!, Folgende Dateinamen konnten nicht korrigiert werden:`n`n%FehlerListe%
         Return
      }
      Else
      {
         MsgBox, 4, Fehler!, % "Folgende Dateinamen können nicht korrigiert werden:`n`n" . FehlerListe .  "`n`n"
                             . "Sollen " . Umbenennen.Length() . " dennoch umbenannt werden?"
         IfMsgBox, No
            Return
      }
   }
   For Each, Datei In Umbenennen
   {
      ; FileMove, % Datei["Alt"], Datei["Neu"]
      MsgBox, 0, Umbenennen!, % Datei["Alt"] . "`n`n" . Datei["Neu"]
   }
Return
Ich habe das nur grob angetestet. Wenn Du damit Probleme hast, stelle bitte die Dateinamen ein, die Deiner Meinung nach funktionieren sollten, es aber nicht tun. In den kommenden zwei Wochen habe ich für AHK allerdings weniger Zeit.
User avatar
Meister Lampe
Posts: 228
Joined: 06 Apr 2014, 13:28

Re: Optimierung Umbenennungstool

19 Jun 2019, 17:37

Hallo just me!

Das Script, das Du mir im letzten Post geschickt hast, arbeitet noch nicht so wie gewünscht. Es wird lediglich die erste Datei geprüft und ggf. korrigiert, alle weiteren werden dann im der Liste "Umbenennen?" eingesammelt und angezeigt - unabhängig davon, ob etwas daran zu korrigieren ist oder nicht. Ich habe es in meinem Code unter dem Befehl ^F6 eingefügt.

Ich habe mich dann erstmal an ein paar andere Sachen herangemacht:

1.) Ich habe im Kopf eine Abfrage mit IfFileExist geschrieben, die prüft, ob das Intranet des Archivs erreichbar ist. Dann wird auf die dort liegenden Dateien zurückgegriffen. So brauche ich nicht jedesmal neu die Pfade zu editieren. Die kann ich hier im Script natürlich nur gekürzt wiedergeben.
2.) Ich werde vorerst auf das animierte Wartesymbol verzichten und habe stattdessen ebenfalls ein Progressfenster mit der Anzeige "Bin gleich fertig" gebastelt. Eigenartigerweise blitzt das aber nur kurz auf und bleibt dann während des restlichen Vorgangs im Hintergrund (oder wird ganz geschlossen?), obwohl ich keine entsprechenden Parameter (großes "A" müßte das sein) hinzugefügt habe.
3.) Ich habe das Umbenennen-Modul jetzt zweigeteilt für Signaturen mit und ohne Index, jetzt können beide durchnummeriert werden.
4.) Ich habe das bereits funktionierende Tool zum Korrigieren/Trimmen (über F6) von Signaturen ohne Index als Basis genommen, um dort etwas anderes auszuprobieren, was man später übernehmen könnte und habe dazu in die bereits bestehende Abfrage zur Unterscheidung zu Vorlagen mit Index eine Warnmeldung gesetzt.
5.) Dann habe ich versucht, für die Variable NewAktname in der Zusammenfügung des neuen Dateinamens nicht den ersten Teil aus dem Split-Array, also NameArray[1], sondern gleich den Bestandsnamen aus der Vorlage zu nehmen, also AktSign. Dann würde dieser, falls falsch geschrieben, gleich auch korrigiert werden. Die Variable wird aber nicht richtig übernommen. Womöglich habe ich die Zuordnung an die falschen Stelle gesetzt.
6.) Schön wäre es ebenfalls, wenn man diese Funktion erweitern könnte, daß man damit auch Nummern ganz ohne Bestandsnamen mit diesem ergänzen kann. Damit man also die Bilder welche bereits Nummern haben, die übernommern werden sollen, beim Scannen nur mit dieser zu benennen braucht, und dann später den vollstädigen Namen daraus macht: Aus 1234a wird dann W 134_001234a. Ich kann nicht beurteilen, ob es einfacher ist, vorliegende Dateinamen mit und ohne Bestandsnamen vornedran zu unterscheiden und das somit in einem Modul zu schreiben, oder ob man das den User unterscheiden läßt und für die "nackten Zahlen" zur Bestandsnamensergänzung einen anderen Befehl wie z.B.. F5 verwendet, der dann nach einer etwas anderen Festlegung der Variablen in dieselbe Routine einsteigt.
7.) Ich bezweifle mittlerweile immer mehr, ob ich eine solche Korrektur- und Trimfunktion wie für die Signaturen ohne Index auch für diejenigen mit Index überhaupt benötige. Punkt 6,) wäre da wohl wichtiger.

Hier ist jetzt der aktuelle Code:

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

If FileExist("\\...-Intranet Archiv-...\Arbeitsdateien AHK-Tool StAF\")
{
   VorgabenDatei := "\\...-Intranet Archiv-...\Arbeitsdateien AHK-Tool StAF\Bestandsvorgaben.txt" 
   Anleitung := "\\...-Intranet Archiv-...\Arbeitsdateien AHK-Tool StAF\Erläuterungen AHK-Tool StAF_3.1.pdf"
   ;Wartesymbol := "\\...-Intranet Archiv-...\Arbeitsdateien AHK-Tool StAF\Farbenscheibe.gif"
}
else
{   
   AuswahlDatei := A_ScriptDir . "\Arbeitsdateien AHK-Tool StAF\Auswahl.txt"  ; zuletzt verwendeter Vorlagenname, lokal gespeichert
   VorgabenDatei := A_ScriptDir . "\Arbeitsdateien AHK-Tool StAF\Bestandsvorgaben.txt"
   Anleitung := A_ScriptDir . "\Arbeitsdateien AHK-Tool StAF\Erläuterungen AHK-Tool StAF_3.1.pdf"
   ;Wartesymbol := A_ScriptDir . "\Arbeitsdateien AHK-Tool StAF\Farbenscheibe.gif"
}

^!F8::Run, %VorgabenDatei%
!F8::Run, %Anleitung%

; 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    x137  yp  h25  w70  vSignEingabe, ;%SignVorlage%
Gui, Add, Edit, cblue    x224  yp  h25  w70  vIndexEingabe, ;%IndexVorlage%
Gui, Add, Text, x124     yp+5    h25   w13 , % chr(863)
Gui, Add, Text, x211     yp+4    h25   w13  , % chr(862)

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)
If (IndexVorlage = "-")
{
   StellenIndex := 0
}
else
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!, Die Indexvorgabe darf nicht leer sein!
   GuiControl, Focus, IndexEingabe
   Return
}

; Alles OK, verarbeiten
AktSignNeu := AktSignEingabe
StellenSignNeu := StrLen(SignEingabe)
SignVorlageNeu := Format("{:0" . StellenSignNeu . "}", 0)
If (IndexEingabe = "-")
{
   IndexVorlageNeu := "-"
}
else
{  
   StellenIndexNeu := StrLen(IndexEingabe)
   IndexVorlageNeu := Format("{:0" . StellenIndexNeu . "}", 0)
}
FileAppend , `n%AktSignNeu%`t%SignVorlageNeu%`t%IndexVorlageNeu%, %VorgabenDatei%

; Auswahldatei updaten
If (IndexVorlageNeu = "-")
{
   VorschauMsgNeu = %AktSignNeu%_%SignVorlageNeu%
   StellenIndex := "-"
   LetzteSign := "-"
}
else
{
   VorschauMsgNeu = %AktSignNeu%_%SignVorlageNeu%-%IndexVorlageNeu%
   StellenIndex := StellenIndexNeu
   LetzteSign := 0
}
AktSign := AktSignNeu
StellenSign := StellenSignNeu

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, 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
^F8::
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
Return

ProgressOff:
Progress, Off
Return

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

;------------------------------------------------------------------------
; Indexnummerierung auf Eingabebefehl 'Signaturnummer, Startindex' in Inputbox 
; nach Auswahl der Dateien mit der Maus

<!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%
   
   If (StellenIndex = "0")  ; fragt, ob Index vorhanden und wählt die Routine aus
      Gosub, OhneIndex
   Else
      Gosub, MitIndex
   return
   
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

OhneIndex:      ; zum Umbenennen, wenn kein Index vorhanden
; Benutzereingaben zum Umbenennen holen
   If (LetzteSign = 0)
      LetzteSign := Format("{:0" . StellenSign . "}", 1)
   else
      LetzteSign := Format("{:0" . StellenSign . "}", LetzteSign) 
   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 Sign, Item In SelectedItems {
      ItemPath := Item.Path
      SplitPath, ItemPath, DateiName, , Erweiterung
      LetzteSign := Format("{:0" . StellenSign . "}", LetzteSign)  ; Setzt Index auf 1 in 2 Ziffern
      Item.Name := AktSign . "_" . LetzteSign . (ShowExt ? "." . Erweiterung : "")
      LetzteSign++
   }
   ; Fertig
   ; Letzte Datei selektieren
   ; -> docs.microsoft.com/en-us/windows/desktop/shell/shellfolderview-selectitem
   ShellWin.Document.SelectItem(SelectedItems[Anzahl], 29)
   For Sign, Item In SelectedItems
      Item := ""
   ShellWin := ""
Progress, Off
return

;------------------------------------------------------------------------
; Dateinamen mit F6 auf 6stellige Signaturnummer und optionalen Buchstabenindex trimmen
; Beispiel Pragher: W 134_070936A.tif

F6::
   Clipboard := ""
   SendInput, ^c
   Clipwait, 1
 
   DateienAuslese := Clipboard
   SignStellen := StellenSign
   IndexStellen := StellenIndex
   NewAktname := AktSign
   If !(StellenIndex = "0")
   {
      ;Gosub, Trimmen_mI
      MsgBox, 16, Fehler!,  Sie können keine Signaturen nach Vorlagen mit Indizes prüfen!
      return
   }
   else
   Loop, Parse, Dateienauslese, `n, `r
   {
      SplitPath, A_LoopField, , Verzeichnis, Erweiterung, AlterName
      NameArray := StrSplit(AlterName, "_")
      
       ; Wenn NameArray[2] mit einer oder mehreren Ziffer(n) beginnt und mit einer oder keiner 'Nichtziffer' endet ...
      If RegExMatch(NameArray[2], "^(\d+)(\D?)$", Match)
      {
         ; MsgBox, % StrLen(Match1) . ": " . Match1 . "   <>   " . Match2
         If !(StrLen(Match1) = SignStellen)
         {
            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%
            }
         }
      }      	
   }  
return

;~ Trimmen_mI:
;~ ; Beispiel Landeskommissär: A 95--1_0123-4567.tif
;~ ;MsgBox Sie haben eine Vorlage mit Index gewählt

;~ Loop, Parse, Dateienauslese, `n, `r
   ;~ {
      ;~ SplitPath, A_LoopField, , Verzeichnis, Erweiterung, AlterName
      ;~ NameArray := StrSplit(AlterName, "_")
      ;~ NewAktname := NameArray[1]
      ;~ SignArray := StrSplit(NameArray[2], "-")
      
      ;~ SignArray[1] += 0
      ;~ NewSign := Format("{:0" . SignStellen . "}", SignArray[1])
      
      ;~ ; Wenn SignArray[2] mit einer oder mehreren Ziffer(n) beginnt und mit einer oder keiner 'Nichtziffer' endet ...
      ;~ If RegExMatch(SignArray[2], "^(\d+)(\D?)$", Match)
      ;~ {
         ;~ If !(StrLen(Match1) = IndexStellen)
         ;~ {
            ;~ Match1 += 0 ; führende Nullen entfernen
            ;~ If !(StrLen(Match1) > IndexStellen)
            ;~ {
            ;~ NewIndex := Format("{:0" . IndexStellen . "}", Match1) . Match2
            ;~ FileMove, %A_LoopField%, %Verzeichnis%\%NewAktname%_%NewSign%-%NewIndex%.%Erweiterung%
            ;~ }
         ;~ }
      ;~ }
   ;~ }
;~ return

^F6::
   If (AktSign = "")
   {
      MsgBox, 16, Fehler!, Es ist keine Bestandsvorlage ausgewählt!
      Return
   }

   Clipboard := ""
   SendInput, ^c
   Clipwait, 1

   If (ErrorLevel)
   {
      MsgBox, 16, Fehler!, Es sind keine Dateien ausgewählt!
      Return
   }

   DateienAuslese := Clipboard
   SignStellen := StellenSign
   IndexStellen := StellenIndex
   AktSignLen := StrLen(AktSign)

   NamensFehler := []
   Umbenennen := []
   AnzahlDateien := 0

   Loop, Parse, Dateienauslese, `n, `r
   {
      AnzahlDateien++
      SplitPath, A_LoopField, , Verzeichnis, Erweiterung, AlterName
      If (SubStr(AlterName, 1, AktSignLen) <> AktSign)
      {
         NamensFehler.Push(A_LoopField)
         Continue
      }
      Trenner := SubStr(AlterName, AktSignLen + 1, 1)
      If Trenner Not In _,-
      {
         NamensFehler.Push(A_LoopField)
         Continue
      }
      RestName := SubStr(AlterName, AktSignLen + 2)
      If !RegExMatch(RestName, "^(\d+)(.*)$", Rest)
      {
         NamensFehler.Push(A_LoopField)
         Continue
      }
      Signatur := Rest1
      If (StrLen(Rest1) <> SignStellen)
      {
         Signatur += 0
         If (StrLen(Signatur) <= SignStellen)
         {
            Signatur := Format("{:0" . SignStellen . "}", Signatur)
         }
         Else
         {
            NamensFehler.Push(A_LoopField)
            Continue
         }
      }
      If (IndexStellen = 0)
      {
         NeuerName := Verzeichnis . "\" . AktSign . "_" . Signatur . Rest2 . "." . Erweiterung
         Umbenennen.Push({Alt: A_LoopField, Neu: NeuerName})
         Continue
      }
      Trenner := SubStr(RestName, StrLen(Rest1) + 1, 1)
      If Trenner Not In _,-
      {
         NamensFehler.Push(A_LoopField)
         Continue
      }
      RestName := SubStr(RestName, StrLen(Rest1) + 2)
      If !RegExMatch(RestName, "^(\d+)(.*)$", Rest)
      {
         NamensFehler.Push(A_LoopField)
         Continue
      }
      Index := Rest1
      If (StrLen(Rest1) <> IndexStellen)
      {
         Index += 0
         If (StrLen(Index) <= IndexStellen)
         {
            Index := Format("{:0" . IndexStellen . "}", Index)
            NeuerName := Verzeichnis . "\" . AktSign . "_" . Signatur . "-" . Index . Rest2 . "." . Erweiterung
            Umbenennen.Push({Alt: A_LoopField, Neu: NeuerName})
            Continue
         }
         Else
         {
            NamensFehler.Push(A_LoopField)
            Continue
         }
      }
   }
   If NamensFehler.Length()
   {
      FehlerListe := ""
      For Each, Datei In NamensFehler
         FehlerListe .= Datei . "`n"
      If (Umbenennen.Length() = 0)
      {
         MsgBox, 16, Fehler!, Folgende Dateinamen konnten nicht korrigiert werden:`n`n%FehlerListe%
         Return
      }
      Else
      {
         MsgBox, 4, Fehler!, % "Folgende Dateinamen können nicht korrigiert werden:`n`n" . FehlerListe .  "`n`n"
                             . "Sollen " . Umbenennen.Length() . " dennoch umbenannt werden?"
         IfMsgBox, No
            Return
      }
   }
   For Each, Datei In Umbenennen
   {
      ; FileMove, % Datei["Alt"], Datei["Neu"]
      MsgBox, 0, Umbenennen!, % Datei["Alt"] . "`n`n" . Datei["Neu"]
   }
Return

#If ; Ende des bedingten HotKey

+NumpadSub::Send _		; Unterstrich auch mit Shift+Minus vom Numpad
;------------------------------------------------------------------------
; Beenden des Scriptes
Escape::
MsgBox, 33, AHK schließen, Wollen Sie das AHK-Tool StAF wirklich schließen?
IfMsgBox Ok
   ExitApp
else
Return
Viele Grüße von Meister Lampe

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: Rohwedder and 38 guests