Optimierung Umbenennungstool

Post a reply

Confirmation code
Enter the code exactly as it appears. All letters are case insensitive.
Smilies
:D :) ;) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :!: :?: :idea: :| :mrgreen: :geek: :ugeek: :arrow: :angel: :clap: :crazy: :eh: :lolno: :problem: :shh: :shifty: :sick: :silent: :think: :thumbup: :thumbdown: :salute: :wave: :wtf: :yawn: :facepalm: :bravo: :dance: :beard: :morebeard: :xmas: :HeHe: :trollface: :cookie: :rainbow: :monkeysee: :monkeysay: :happybday: :headwall: :offtopic: :superhappy: :terms: :beer:
View more smilies

BBCode is ON
[img] is OFF
[flash] is OFF
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: Optimierung Umbenennungstool

Re: Optimierung Umbenennungstool

Post by just me » 08 Dec 2021, 04:17

Meister Lampe wrote:Was soll das (ShowExt ? Erweiterung : "") eigentlich bewirken?
Keine Ahnung, ich habe das aus Deinem Beispielcode hier
Meister Lampe wrote:
19 Nov 2021, 18:36
Hallo just me!
...
übernommen. Wahrscheinlich hat es etwas mit den Explorereinstellungen zur Anzeige der Dateierweiterungen zu tun.

Re: Optimierung Umbenennungstool

Post by Meister Lampe » 07 Dec 2021, 14:16

Hallo just me!

Erstmal vielen Dank, das hat jetzt prima geklappt. Allerdings erst nach einer kleinen Korrektur, weshalb ich Dich nochmals fragen möchte.
So, wie Du es mir in Deiner letzten Nachricht geschrieben hast, kam dann immer der Fehler "Wenn Sie die Dateinamenerweiterung ändern, wird die Datei evtl. unbrauchbar." Ich habe dann den Strings M1, M2, M3 usw. wieder die üblichen Variablennamen zugeordnet, was auch nichts geändert hat.
Durch eine MsgBox-Prüfung hat sich dann herausgestellt, daß die Erweiterung gar nicht im Namen dabei war.

Code: Select all

...
   Progress, 2: m2 H45 W350 fs16 zh0 ZY11 WS600 ct0000ff CWffffff B, Bin gleich fertig ..., , Vorschau, Verdana  ; größeres Fenster und Schrift
   ...
 For Item In ShellWin.Document.Folder.Items {
      If Item.IsFolder() ; das Element ist ein Ordner -> überspringen
         Continue
      ScanPfad := Item.path
      SplitPath, ScanPfad, ScanName
      If !RegExMatch(ScanName, "^([^_]+)(_)([^-]+)(-)(\d+)(\.[^\.]+)$", M) ; der Name ist fehlerhaft aufgebaut -> überspringen
         Continue
      ; AktSign = M1, Signatur = M3, Index = M5, 
      Signatur := M3
      Erweiterung := M6
         ;~ MsgBox, Die Variablen Signatur und Erweiterung lautet jetzt %Signatur% und %Erweiterung%
      ; hier könntest Du Prüfungen auf die Gültigkeit von AktSign, Signatur  und Index einfügen
      If Akt_Sig_Idx[AktSign, Signatur]         ; Index für die Kombination M1/Signature bestimmen
         Akt_Sig_Idx[AktSign, Signatur] += 1
      Else
         Akt_Sig_Idx[AktSign, Signatur] := 1
      
      ;~ Signatur := Format("{:0" . StellenSign . "}", Akt_Sig_Idx[AktSign, Signatur])  ; Korrigiert Signaturformat
         ;~ MsgBox, Die Variable Signatur lautet jetzt %Signatur%
      NeuerIndex := Format("{:0"  . StrLen(M5) . "}",  Akt_Sig_Idx[AktSign, Signatur])
      ;~ Index := Format("{:0"  . StellenIndex . "}",  Akt_Sig_Idx[AktSign, Signatur])
         ;~ MsgBox, Die Variable NeuerIndex lautet jetzt %NeuerIndex%
      NeuerName := AktSign . "_" . Signatur . "_" . NeuerIndex . Erweiterung ;(ShowExt ? Erweiterung : "")
         ;~ MsgBox, Die Variable NeuerName lautet jetzt %NeuerName%
      ;~ Item.Name := AktSign . "_" . Signatur . "-" . NeuerIndex . "." (ShowExt ? Erweiterung : "")
      Item.Name := NeuerName 
   }
   Progress, 2: Off
Return
Ich hatte auch drei Versionen ausprobiert, war aber immer derselbe Fehler:

Code: Select all

; wie im letzten Post:
Item.Name := AktSign . "_" . Signatur . "-" . NeuerIndex . (ShowExt ? Erweiterung : "")
; einen Punkt eingefügt:
Item.Name := AktSign . "_" . Signatur . "-" . NeuerIndex . "." (ShowExt ? Erweiterung : "")
; mit dem Punkt in der Klammer, so steht es in den anderen Scripts:
Item.Name := AktSign . "_" . Signatur . "-" . NeuerIndex . (ShowExt ? "." . Erweiterung : "")
Erst das Weglassen von (ShowExt ? Erweiterung : "") hat Besserung gebracht:

Code: Select all

NeuerName := AktSign . "_" . Signatur . "_" . NeuerIndex . Erweiterung
Item.Name := NeuerName
Dann klappte es. Daraufhin habe ich noch, wie im anderen Script auch, die Progress-Fortschrittsanzeige eingefügt.
Was soll das (ShowExt ? Erweiterung : "") eigentlich bewirken?

Viele Grüße von Meister Lampe

Re: Optimierung Umbenennungstool

Post by just me » 01 Dec 2021, 11:11

Hallo,

das mit dem - im AktSign ist natürlich 'unglücklich', aber nicht tragisch. Also noch einmal auf Los:

Der aktive Ordner enthält Dateien, deren Namen an sich korrekt sind. Lediglich die Indizes sollen neu errechnet werden. Die Namen haben folgenden Aufbau:

Aktsign (enthält keinen Unterstrich)
_ (Unterstrich) als Trennung
Signatur (enthält keinen Bindestrich)
- (Bindestrich) als Trennung
Index (Ziffern in der für die Kombination AktSign/Signatur korrekten Anzahl
. (Punkt) als Trennung
Dateierweiterung

Außerdem sind sie bereits so sortiert, dass neue Indizes für jede Kombination AktSign/Signatur beginnend mit 1 fortlaufend vergeben werden können.

So weit, so gut! Wenn das so ist, kannst Du Folgendes probieren:

Code: Select all

...
   For Item In ShellWin.Document.Folder.Items {
      If Item.IsFolder() ; das Element ist ein Ordner -> überspringen
         Continue
      ScanPfad := Item.path
      SplitPath, ScanPfad, ScanName
      If !RegExMatch(ScanName, "^([^_]+)(_)([^-]+)(-)(\d+)(\.[^\.]+)$", M) ; der Name ist fehlerhaft aufgebaut -> überspringen
         Continue
      ; AktSign = M1, Signatur = M3, Index = M5, Erweiterung = M6
      ; hier könntest Du Prüfungen auf die Gültigkeit von AktSign, Signatur  und Index einfügen
      If Akt_Sig_Idx[M1, M3]         ; Index für die Kombination M1/Signature bestimmen
         Akt_Sig_Idx[M1, M3] += 1
      Else
         Akt_Sig_Idx[M1, M3] := 1
      NeuerIndex := Format("{:0"  . StrLen(M5) . "}",  Akt_Sig_Idx[M1, M3])
      Item.Name := M1 . "_" . M3 . "-" . NeuerIndex . (ShowExt ? M6 : "")
   }
...

Re: Optimierung Umbenennungstool

Post by Meister Lampe » 30 Nov 2021, 14:28

Hallo just me!

Dein Code kann so noch nicht einwandfrei funktionieren. Das liegt aber nicht an Dir, sondern an etwas Anderem: Wir haben auch Bestände mit Schrägstrichen im Namen (= AktSign), z.B. "B 789/1". Weil die nicht als Dateinamen zugelassen sind, werden sie dann durch zwei Bindestriche ersetzt ("B 789--1"). Deshalb klappt der Split-Mechanismus nicht richtig.
Wie bei den anderen Modulen habe ich jetzt auch hier die Auswahl für das Bestandsformat davorgesetzt, damit ist auch die AktSign festgelegt.
Diese muß deshalb nicht mehr durch Aufsplitten festgestellt werden. Deshalb lasse ich sie vor diesem Schritt jetzt ganz löschen. Dann greift die darauffolgende Prüfung auch für vielleicht vorhandene Bilder mit anderer AktSign.

Code: Select all

+^g::
If !(ModulAuswahl = 7 or ModulAuswahl = 0)
   {
      MsgBox, 17, Keine Bestandsvorlage!, Sie müssen zuerst eine Bestandsvorlage auswählen!
      IfMsgBox Ok
      {
         Gosub Auswahlfenster
         ModulAuswahl := 7
         return
      }
      else
      return
   }
else
   ModulAuswahl := 7

   ExplorerID := WinExist("A") ; <<<<<<<<<< Fenstertitel wird gebraucht
   ShellWin := 0
   For Win In ShellApp.Windows {
      If (Win.HWND = ExplorerID) {
         ShellWin := Win
         Break
      }
   }
   If !(ShellWin) ; das aktive Explorerfenster wurde nicht gefunden, Abbruch!
      Return
   Akt_Sig_Idx := [] ; Array für die Verwaltung der Indizes je AktSign und Signatur
   For Item In ShellWin.Document.Folder.Items {
      If Item.IsFolder() ; das Element ist ein Ordner -> überspringen
         Continue   
      ScanPfad := Item.path
      SplitPath, ScanPfad, ScanName
      ScanName := StrReplace(ScanName, AktSign . "_")
         MsgBox, Die Variable ScanName lautet jetzt %ScanName%
      Split := StrSplit(ScanName, ["-", ".", "_"])
      If (Split.Length() <> 3) ; der Name ist fehlerhaft aufgebaut -> überspringen
         MsgBox, der Name ist fehlerhaft aufgebaut - überspringen?
         Continue
      ;~ AktSign := Split[1]  ; auf diese 4 Zuordnungen könnte man auch verzichten
      Signatur := Split[1]
      Index := Split[2]
      Erweiterung := Split[3]
      ; hier könntest Du Prüfungen auf die Gültigkeit von AktSign (1), Signatur (2), and Index (3) einfügen
      If Akt_Sig_Idx[AktSign, Signatur]         ; Index für die Kombination AktSign/Signature bestimmen
         Akt_Sig_Idx[AktSign, Signatur] += 1
      Else
         Akt_Sig_Idx[AktSign, Signatur] := 1
      Index := Format("{:0"  . StellenIndex . "}",  Akt_Sig_Idx[AktSign, Signatur])
      Item.Name := AktSign . "_" . Signatur . "-" . Index . (ShowExt ? "." . Erweiterung : "")
   }
Return
Jetzt müßte man wahrscheinlich die unteren Zeilen mit dem Akt_Sig_Idx[AktSign, Signatur] anders formulieren. Da habe ich noch keine Idee, wie man das am machen würde. Ich kann ja nicht mit einem leeren String suchen. Wenn ich aber die Aktsign nicht wegnehme, sondern z.B. durch "xxx" ersetze, dann greift die Kontrolle nach anderen AktSign nicht, da die Zahl der Strings wieder gleich ist (bzw. gleich sein kann, wegen dem oben erwähnten Problem mit der /-Ersetzung).
Die Änderung und Erfassung bzw. Verwerfung von anderen AktSign klappt, nicht aber die weitere Umbenennung.

Viele Grüße von Meister Lampe

Re: Optimierung Umbenennungstool

Post by just me » 29 Nov 2021, 07:50

Moin,

wenn der Ordner im aktiven Explorerfenster korrekte Dateinamen in der notwendigen Sortierreihenfolge enthält, könnte es der folgende (ungetestete) Code tun:

Code: Select all

+^f::
   ExplorerID := WinExist("A") ; <<<<<<<<<< Fenstertitel wird gebraucht
   ShellWin := 0
   For Win In ShellApp.Windows {
      If (Win.HWND = ExplorerID) {
         ShellWin := Win
         Break
      }
   }
   If !(ShellWin) ; das aktive Explorerfenster wurde nicht gefunden, Abbruch!
      Return
   Akt_Sig_Idx := [] ; Array für die Verwaltung der Indizes je AktSign und Signatur
   For Item In ShellWin.Document.Folder.Items {
      If Item.IsFolder() ; das Element ist ein Ordner -> überspringen
         Continue
      ScanPfad := Item.path
      SplitPath, ScanPfad, ScanName
      Split := StrSplit(ScanName, ["-", ".", "_"])
      If (Split.Length() <> 4) ; der Name ist fehlerhaft aufgebaut -> überspringen
         Continue
      AktSign := Split[1]  ; auf diese 4 Zuordnungen könnte man auch verzichten
      Signatur := Split[2]
      Index := Split[3]
      Erweiterung := Split[4]
      ; hier könntest Du Prüfungen auf die Gültigkeit von AktSign (1), Signatur (2), and Index (3) einfügen
      If Akt_Sig_Idx[AktSign, Signatur]         ; Index für die Kombination AktSign/Signature bestimmen
         Akt_Sig_Idx[AktSign, Signatur] += 1
      Else
         Akt_Sig_Idx[AktSign, Signatur] := 1
      Index := Format("{:0"  . StellenIndex . "}",  Akt_Sig_Idx[AktSign, Signatur])
      Item.Name := AktSign . "_" . Signatur . "-" . Index . (ShowExt ? "." . Erweiterung : "")
   }
Return
Ich habe ein paar Kommentare zur (beabsichtigten) Funktionsweise eingebaut.

Re: Optimierung Umbenennungstool

Post by Meister Lampe » 28 Nov 2021, 17:12

Hallo just me!

Du hast die Idee ganz genau beschrieben. Die Notwendigkeit dazu hat sich folgendermaßen ergeben. Ich habe tausende Bilder eingescannt, mußte dazu aber unterschiedliche Scanner verwenden, da die Sammlung aus Fotonegativen (Durchlicht) und dazugehörigen Karteikarten mit einer genauen Beschreibung des Bildes (Auflicht) besteht. Die Fotos habe ich direkt beim Scannen unter den vorgesehenen Nummern abgespeichert und indiziert (Es treten durchaus auch mal mehrere Aufnahmen zum gleichen Motiv auf). Bei dem anderen Scanner erschienen die Scans in der Reihenfolge "scan001, scan002, scan003, ...". Mithilfe des anderen Umbenennungstool habe ich diese dann auch den einzelnen Signaturen zuordnen können, wobei ich dann für die Indizes nicht mit 01,02,03,.. wie die Bilder, sondern 11,12,13,.. verwendet habe, damit ich sie später überhaupt in einem Ordner zusammenbringen kann. Mehr als 9 Fotos unter derselben Signatur habe ich dann doch nicht gefunden. Nun gilt es, die Lücken zu schließen und aus den Indizes 01,02,11,12 dann 01,02,03,04 zu machen. Oder auch aus 11,12 dann 01,02 - wenn mal kein Bild verhanden ist, was auch vorkommt.
Die Originalnamen der Dateien sind also bereits jetzt in dem gewünschten Format, daß Du oben beschrieben hast. Es kann höchstens sein, daß ich für den Namen statt einem Bindstrich einen Unterstrich verwenden muß. Das könnte man aber leicht im Script ändern oder sogar später noch mit einer ganz gewöhnlichen Rename-Software erledigen.

Viele Grüße von Meister Lampe

Re: Optimierung Umbenennungstool

Post by just me » 28 Nov 2021, 05:49

Moin,

wenn ich das richtig verstehe, versuchst Du, die in einem Ordner gefundenen Dateien mit identischem AktSign und identischer Signatur mit einem neuen durchgehenden Index mit Start bei 1 zu versehen. Dabei wird der neue Name wie folgt gebildet:
AktSign_Signatur-Index ggf. gefolgt von der Erweiterung. Wie muss man sich die Originalnamen der Dateien im Ordner vorstellen?

Re: Optimierung Umbenennungstool

Post by Meister Lampe » 27 Nov 2021, 18:32

Hallo just me!

Dank Deiner letzten Empfehlungen bin ich jetzt ein ganzes Stück weiter gekommen. Das Suchen nach der Signatur und Umbenennen scheint jetzt zu funktionieren.

Code: Select all

+^f::

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

InputBox, SuchSign, , Hier bitte eine Startsignatur eingeben, , 225, 125

Loop, 5
{
LetzteSign := Format("{:0" . StellenSign . "}", SuchSign)
Suchstring := AktSign . "_" . LetzteSign
   MsgBox, Die Variable Suchstring lautet jetzt %Suchstring%
I := 1 ; zum Testen
Zusammenfuehren := []
For Item In ShellWin.Document.Folder.Items {
   ; If Item.IsFolder() ; das Element ist ein Ordner -> überspringen
      ; Continue
   Scanpfad := Item.path
   SplitPath, Scanpfad, ScanName
   If InStr(ScanName, SuchString) {
      MsgBox, 0, % "Datei " . I++, % ScanName ; zum Testen
      Zusammenfuehren.Push(Item)
   }
}
   
LetzterIndex := 1
   
  For Index, Item In Zusammenfuehren 
   {
      ItemPath := Item.Path
      SplitPath, ItemPath, DateiName, , Erweiterung
      LetzterIndex := Format("{:0" . StellenIndex . "}", LetzterIndex)  ; korrigiert die Ziffernzahl des Index
      LetzteSign := Format("{:0" . StellenSign . "}", LetzteSign)  ; Setzt Index auf 1 in 2 Ziffern
      Item.Name := AktSign . "_" . LetzteSign . "-" . LetzterIndex . (ShowExt ? "." . Erweiterung : "")
      LetzterIndex++
   }
SuchSign++
}
Return
1.) Ich habe die AktSign vor den Suchstring angefügt, damit weder Dateien mit anderen AktSign gefunden werden noch in den Indizes gesucht wird.
2.) Dann habe ich das Ganze noch in eine äußere Schleife gesetzt, die die SuchSign erhöht und damit die Prozedur auf alle Dateien im Ordner anwenden soll.
Und das ist jetzt mein Problem: Ich brauche eine Startzahl und eine vernünftige Abbruchbedingung. Statt der InputBox zur manuellen Eingabe und einer absoluten Zahl für die Schleifendurchgänge, sollten ab besten die kleinste und die größte Zahl stehen, die zu der vorgegebenen AktSign als Signaturnummer (Variable LetzteSign) existieren.
Wie bekomme ich die heraus? Das würde ja wohl nochmals eine Schleife am Start bedeuten. Oder gibt es eine bessere Methode? Da ich normalerweise für solche Zwecke keine Scans aus unterschiedlichen Beständen, also mit verschiedenen AktSign im selben Ordner habe, würde es wohl auch ausreichen, die erste und letzte Datei im Ordner prüfen. Bloß, wie kann ich nach denen suchen?

Viele Grüße von Meister Lampe

Re: Optimierung Umbenennungstool

Post by just me » 26 Nov 2021, 05:32

Meister Lampe wrote: Jetzt habe ich ja "nur" die Pfade. Kann ich dann gleich

Code: Select all

Loop, Parse, ShellWin.Document.Folder.Items, `n, `r
schreiben?
Das kannst Du natürlich nicht, weil ShellWin.Document.Folder.Items ein COM-Objekt mit einer Sammlung (Collection) von Item Objekten liefert. Mit Loop, Parse, ... kannst Du nur Text verarbeiten.

Re: Optimierung Umbenennungstool

Post by just me » 26 Nov 2021, 03:38

Moin,

meine Anmerkung zu ShellApp bezieht sich auf diese Zeile:

Code: Select all

For Win In Shell.Windows {
Deines neuen Codes.

Wenn Du ein Array aufbauen willst, wie es bei den anderen Berarbeitungsarten erstellt wird, sollte das so gehen:

Code: Select all

I := 1 ; zum Testen
Zusammenfuehren := []
For Item In ShellWin.Document.Folder.Items {
   ; If Item.IsFolder() ; das Element ist ein Ordner -> überspringen
      ; Continue
   Scanpfad := Item.path
   SplitPath, Scanpfad, ScanName
   If InStr(ScanName, SuchString) {
      MsgBox, 0, % "Datei " . I++, % ScanName ; zum Testen
      Zusammenfuehren.Push(Item)
   }
}
Du hast dann wieder ein Array mit Item Objekten.

Re: Optimierung Umbenennungstool

Post by Meister Lampe » 25 Nov 2021, 17:27

Hallo just me!
Was ist denn dieser erste Teil? Und warum hast Du

Code: Select all

If !(ShellWin)
   Return
entfernt. Das sichert ja nur ab, dass das aktive Fenster tatsächlich ein Explorerfenster ist.
Da hatte ich eine Zeile zuviel herausgenommen. Aber jetzt bleibt das Script immer dort hängen bzw. bricht dort ab. Ich habe keine Ahnung warum, denn dieser Einstieg ist ja bei meinen anderen Modulen, die Dateien in Fenstern bearbeiten sollen, auch dergleiche - und funktioniert. Bei denen steht übrigens auch immer ShellWin und nicht ShellApp. Ich habe das trotzdem mal ausprobiert, hat dann aber nichts genutzt.
Ich weiß nicht, ob das eine Rolle spielen könnte, aber mein Laptop hat neulich im Zuge eines Updates automatisch von Win 10 auf Win 11 umgestellt.

Zu Deinem zweiten Punkt:
Sollte man das Suchen der Dateien ins Array Zusammenfuehren dann besser mit einer Parse-Schleife machen? In dem anderen Script war die erste Variable die Dateien selber, und zwar aus dem Clipboard.

Code: Select all

DateienAuslese := Clipboard
;...
Loop, Parse, Dateienauslese, `n, `r
{
   AnzahlDateien++
   SplitPath, A_LoopField, , Verzeichnis, Erweiterung, AlterName
   ;...
Jetzt habe ich ja "nur" die Pfade. Kann ich dann gleich

Code: Select all

Loop, Parse, ShellWin.Document.Folder.Items, `n, `r
schreiben?

Viele Grüße von Meister Lampe

Re: Optimierung Umbenennungstool

Post by just me » 20 Nov 2021, 04:23

Moin Meister,
Meister Lampe wrote:Ja, jetzt klappt der erste Teil.
Was ist denn dieser erste Teil? Und warum hast Du

Code: Select all

If !(ShellWin)
   Return
entfernt. Das sichert ja nur ab, dass das aktive Fenster tatsächlich ein Explorerfenster ist.

Wenn das 'stört', hat das Skript kein passendes Fenster gefunden. Und dabei fällt mir auf, dass das Shell-Objekt bisher immer ShellApp hieß.

Wenn Du Dir unsicher bist, ob etwas so funktioniert, wie Du es willst, heißt das Instrument der Wahl immer noch MsgBox. Eine Möglichkeit wäre z.B.

Code: Select all

I := 1
For Item In ShellWin.Document.Folder.Items {
   MsgBox, 0, Element %A_Index%, % Item.Path
   ...
Wenn diese Meldung nicht kommt, hast Du entweder keinen Ordner / kein Explorerfenster gefunden oder der Ordner enthält keine Dateien.

Außerdem:

Code: Select all

		Zusammenfuehren.Push(A_LoopField)
In einer For-Schleife gibt es die Variable A_LoopField nicht.

Re: Optimierung Umbenennungstool

Post by Meister Lampe » 19 Nov 2021, 18:36

Hallo just me!

Ja, jetzt klappt der erste Teil. Die von Dir oben aufgeführten Zeilen waren überflüssig, haben sogar gestört.
Wie schon erwähnt, möchte ich mit den gefundenen Dateien ja auch was machen (sie umbenennen), sie nicht nur per MsgBox ansehen.
Ich habe jetzt also probiert, den Code zu erweitern und dazu Bestandteile aus dem anderen Script, die Du mal dort eingebaut hattest, verwendet:

Code: Select all

+^f::
ActiveWindow := WinExist("A")
ShellWin := 0
For Win In Shell.Windows {
   If (Win.HWND = ActiveWindow) {
      ShellWin := Win
      Break
   }
}
InputBox, SuchString, , Hier bitte Suchstring eingeben, , 225, 125

Zusammenfuehren := [] 

I := 1
For Item In ShellWin.Document.Folder.Items {
	;~ If Item.IsFolder() ; das Element ist ein Ordner -> überspringen
      ;~ Continue
	;~ else
	Scanpfad := Item.path
   SplitPath, Scanpfad, ScanName
   
	If InStr(ScanName, SuchString)
	{
		MsgBox, 0, % "Datei " . I++, % ScanName
		Zusammenfuehren.Push(A_LoopField)
		Continue
	}
		;~ else
		;~ MsgBox, %SuchString% nicht gefunden!
     	 ;~ If (I > 10) ; nach spätestens 10 Dateien ist Schluss
      ;~ Break
}

ShellWin.Document.SelectItem(SelectedItems[1], 4)
   For Index, Item In Zusammenfuehren[] {
      ItemPath := Item.Path
      SplitPath, ItemPath, DateiName, , Erweiterung
      LetzterIndex := Format("{:0" . StellenIndex . "}", LetzterIndex)  ; korrigiert die Ziffernzahl des Index
      Item.Name := AktSign . "_" . LetzteSign . "-" . LetzterIndex . (ShowExt ? "." . Erweiterung : "")
      LetzterIndex++
   }
return
Neu ist jetzt das Array 'Zusammenfuehren' in dem die zu bearbeitenden Dateien gesammelt werden sollen. Deshalb folgen jetzt auf die If InStr-Abfrage mehrere Zeilen in Klammern. Aber die werden anscheinend übergangen, denn die MsgBox wird überhaupt nicht mehr angezeigt - obwohl durchaus Dateien zu finden wären! Das wundert mich, denn außerhalb habe ich nichts verändert. Und selbst wenn das mit .push-Befehl falsch formuliert wäre, so müßte sich die MsgBox doch mindestens einmal öffnen.
So kann ich natürlich auch den unteren Teil für das Ausführen der Umbenennung nicht testen und ggf. anpassen.

Viele Grüße von Meister Lampe

Re: Optimierung Umbenennungstool

Post by just me » 14 Nov 2021, 05:59

Moin Meister,

ich habe (wieder einmal) Schwierigkeiten damit, Deinen Code und Deine dazu gemachten Äußerungen in Einklang zu bringen.
Meister Lampe wrote:So wie das jetzt ist, findet es die Dateien mit dem String darin (5 Stück sind das), die anderen aber nicht. Stattdessen werden diese Dateien ein zweites Mal aufgeführt, bis die 10 Schleifendurchläufe voll sind.

Code: Select all

I := 1
For Item In ShellWin.Document.Folder.Items {
Diese Schleife läuft genau 1 Mal für jedes im angezeigten Ordner enthaltene Element. Sie wird beendet, wenn 10 Elemente gefunden wurden oder alle abgearbeitet sind. Dabei wird kein Element 'ein zweites Mal' verarbeitet.

Meister Lampe wrote:Außerdem mußte ich die Prüfung If Item.IsFolder() auskommentieren, weil das continue alle weiteren Befehle ignoriert und nicht nur den nächsten überspringt. Wie löst man dieses Problem?
Dazu müsste ich zumindest wissen, wie Du Ordner verarbeiten willst. Bisher ging es meines Wissens nur um Dateien.

Code: Select all

If !(ShellWin.Document.SelectedItems.Count = 1) {
   MsgBox, 16, Fehler!, Bitte genau eine Datei auswählen!
   Return
}
FilePath := ShellWin.Document.SelectedItems.Item[0].Path

MsgBox, %FilePath%
Das sollte für diese Verarbeitung überflüssig sein.

Re: Optimierung Umbenennungstool

Post by Meister Lampe » 13 Nov 2021, 19:03

Hallo just me!

Nach einigen anderen Arbeiten komme ich wieder auf Deinen letzten Tipp zurück. Ich habe den etwas verändert und versucht, ihn zu einer Art Filter umzubauen, aber da hängt es noch.

Code: Select all

+^f::
ActiveWindow := WinExist("A")
ShellWin := 0
For Win In Shell.Windows {
   If (Win.HWND = ActiveWindow) {
      ShellWin := Win
      Break
   }
}
InputBox, SuchString, , Hier bitte Suchstring eingeben, , 225, 125
If !(ShellWin)
   Return
If !(ShellWin.Document.SelectedItems.Count = 1) {
   MsgBox, 16, Fehler!, Bitte genau eine Datei auswählen!
   Return
}
FilePath := ShellWin.Document.SelectedItems.Item[0].Path

MsgBox, %FilePath%
I := 1
For Item In ShellWin.Document.Folder.Items {
	;~ If Item.IsFolder() ; das Element ist ein Ordner -> überspringen
      ;~ Continue
	;~ else
   
	If InStr(Item.path, SuchString)
		MsgBox, 0, % "Datei " . I++, % Item.path
	else
		MsgBox, %SuchString% nicht gefunden!
   
   If (I > 10) ; nach spätestens 10 Dateien ist Schluss
      Break
}
Return
Man soll jetzt über eine InputBox eine Zeichenkette eingeben und dann sollen diejenigen Dateien angezeigt werden, die diese im Namen enthalten. Ziel ist natürlich - wenn das erstmal läuft - diese Dateien so zusammenzufassen, daß sie mit den bekannten Regeln bzw. Routinen umbenannt werden können. Soweit die Theorie.
So wie das jetzt ist, findet es die Dateien mit dem String darin (5 Stück sind das), die anderen aber nicht. Stattdessen werden diese Dateien ein zweites Mal aufgeführt, bis die 10 Schleifendurchläufe voll sind. Habe ich die Pfade oder Namen dort falsch angegeben oder benannt? Ich hab das Gefühl, daß es daran liegen könnte.
Außerdem mußte ich die Prüfung If Item.IsFolder() auskommentieren, weil das continue alle weiteren Befehle ignoriert und nicht nur den nächsten überspringt. Wie löst man dieses Problem?

Viele Grüße von Meister Lampe

Re: Optimierung Umbenennungstool

Post by just me » 15 Aug 2021, 04:07

Moin,

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

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

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

Code: Select all

#NoEnv
SetBatchLines, -1

Shell := ComObjCreate("Shell.Application")

Return

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

Esc::
ExitApp

Re: Optimierung Umbenennungstool

Post by Meister Lampe » 08 Aug 2021, 16:44

Hallo just me & gregster!

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

Code: Select all

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

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

Code: Select all

AutomZusammenführen:
^!z::

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

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

Re: Optimierung Umbenennungstool

Post by gregster » 18 Jul 2021, 06:30

https://ahkde.github.io/docs/commands/SplitPath.htm#Parameters wrote:[v1.1.21+]: Dieser Parameter kann ein % Ausdruck sein, allerdings muss das Prozent-Leerzeichen-Präfix verwendet werden.

Re: Optimierung Umbenennungstool

Post by BoBo » 18 Jul 2021, 04:00

Eines von diesen drei [.] ???
Vielleicht beherrscht SplitPath die 'forced expression' Schreibweise? SplitPath, % ...

Re: Optimierung Umbenennungstool

Post by Meister Lampe » 17 Jul 2021, 16:47

Hallo just me!

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

Code: Select all

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

Code: Select all

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

Viele Grüße von Meister Lampe

Top