Mehrere markierte Dateien behandeln

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

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

Mehrere markierte Dateien behandeln

30 Sep 2015, 17:00

Hallo zusammen!

Dank Eurer Tips habe ich jetzt ein Tool zusammengebasteln können, das mir beim Umbenennen bzw. bei der Neuvergabe von Dateinamen, insbesondere von Fotos, hilft. Eine Funktion davon bewirkt, daß der Name des gerade markierten Bildes auf einen vorgegebenen Standard getrimmt wird und dabei ggf. führende Nullen eingesetzt werden, damit die Nummer überall genau gleichviel Stellen hat.
Das geht aber nur mit dem einen gerade markierten Bild. Oder mit einer Schleife und einer vorher eingegebenen Anzahl von direkt aufeinander folgenden Bildern.
Wie kann ich es aber erreichen, mehrere Bilder mit Strg+Click auszuwählen und die anschließend auf einmal umbenennen zu können (und natürlich nur die!)? Geht das überhaupt mit dem AHK?

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

Re: Mehrere markierte Dateien behandeln

01 Oct 2015, 01:48

Wenn Du markierte Dateien in einem Explorerfenster meinst, kannst Du die mit Ctrl+c ins Clipboard holen. Aber so einfach ist es wohl nicht, oder?
User avatar
Meister Lampe
Posts: 231
Joined: 06 Apr 2014, 13:28

Re: Mehrere markierte Dateien behandeln

01 Oct 2015, 02:12

Hallo just me!

So einfach ist es leider wirklich nicht.
Ich möchte ja nicht die markierten Dateien oder ihre Inhalte abspeichern, sondern sie von dem AHK-Tool nacheinander bearbeiten lassen. In diesem Fall sollen ja nur die Namen umbenannt werden. Dazu habe ich ja bereits das fertige Script.
Mein Problem jetzt ist es, wie der AHK sich merken kann, welche Dateien zur Zeit des Starts von diesem Script markiert waren, damit er sie dann alle durchgehen kann - und eben nur die.

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

Re: Mehrere markierte Dateien behandeln

01 Oct 2015, 02:57

Ich verstehe das nicht ganz. Wenn nur eine Datei markiert ist, wie kommt Dein Skript an ihren Pfad?

Ist es für Dich eine denkbare Alternative, das Skript im Hintergrund zu halten und Hotkeys zu nutzen?
User avatar
Meister Lampe
Posts: 231
Joined: 06 Apr 2014, 13:28

Re: Mehrere markierte Dateien behandeln

01 Oct 2015, 04:42

Hallo just me!

Beispiel für das, was ich jetzt noch dazu brauche:
Wenn ich in einem Ordner mehrere Bilder habe, aber einige davon hochkant aufgenommen wurden und jetzt quer liegen, dann kann ich sie mit Strg+Mausklick links quasi "herauspicken" und anschließend mit "Drehen" in in die richtige Position bringen. Alle markierten mit einem Befehl, und ohne daß sich die anderen auch drehen.
Mein Umbenennen-Script wird auch über einen Befehl (eine Funktionstaste) gestartet und soll jetzt auch die vorher ausgewählten Dateien abarbeiten. Für eine einzelne klappt das bereits.

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

Re: Mehrere markierte Dateien behandeln

01 Oct 2015, 05:00

Hallo,

dann läuft also bereits ein AHK-Skript und die Funktionstaste startet die Funktion zum Umbenennen? Wenn zu diesem Zeitpunkt in einem aktiven Ordner/Explorerfenster Dateien markiert sind, kopiert Dir Ctrl+c alle markierten Pfade in das Clipboard.

Code: Select all

F1::
Clipboard := ""
SendInput, ^c
Clipwait, 1000
If (ErrorLevel = 0)
   MsgBox, 0, Dateien,  %Clipboard%
Else
   MsgBox, 0, Dateien, Niente!
Return
Entschuldige, falls ich hier begriffsstutzig bin.
User avatar
Meister Lampe
Posts: 231
Joined: 06 Apr 2014, 13:28

Re: Mehrere markierte Dateien behandeln

01 Oct 2015, 05:34

Hallo just me!

Muß das dann irgenwie in ein Array abgespeichert werden, damit das Script die URLs nacheinander aufrufen und die Dateinamen wie gewünscht verändern kann?
Und: Es weiß ja vorher nicht, wieviele das sind. Also brauche ich dazu eine Schleife, die aufhört, wenn nichts mehr da ist, oder vorher bereits die Anzahl der Dateien/URLs bestimmt.

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

Re: Mehrere markierte Dateien behandeln

01 Oct 2015, 10:00

Hallo Meister,

die einzelne Dateipfade sind mit `n bzw. `r`n getrennt. Wenn Du also nach dem Ctrl+c den Inhalt des Clipboards einer Variablen zuweist (ich persönlich arbeite nie direkt mit der Variablen Clipboard, es geht aber auch), kannst Du die entweder mit Loop, Parse, Variable, `n, `r abarbeiten oder mit Array := StrSplit(Variable, "`n", "`r") ein Array erzeugen. Array.Length() verrät Dir dann die Anzahl der Dateien. Alternativ kannst Du letzteres natürlich auch mit dem traditionellen StringSplit machen, wenn Dir das lieber ist.

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

Re: Mehrere markierte Dateien behandeln

01 Oct 2015, 17:09

Hallo just me!

Ich glaube, das bringt wird mich schon ein Stückchen weiter bringen. Morgen werde ich das in Ruhe studieren. Aus dem Clipboard heraus arbeite ich auch nicht gerne - immer gleich in eine eigene Variable.
Noch eine Frage zu einem kleinen Detail am Rande:
Du hast hier kopiert mit SendInput, ^c. Ich hatte bisher an solchen Stellen immer nur Send, ^c geschrieben. Was ist der Unterschied bzw. der Vorteil von SendInput?
Genauso kam bei mir danach immer ClipWait, 1, 1 , Du schreibst hier ClipWait, 1000 - Was ist besser?
Funktioniert hat Dein Code jedenfalls. :thumbup:

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

Re: Mehrere markierte Dateien behandeln

02 Oct 2015, 01:01

Moin Meister,

SendInput ist mit den Standardeinstellungen die schnellste Art, um Zeichen an 'normale' Anwendungen zu senden. Im mitgelieferten Musterscript ist deshalb auch die Anweisung SendMode enthalten:

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
die dafür sorgt, dass sich Send wie SendInput verhält. Das verwende ich nicht, weil ich lieber gezielt angebe, wie gesendet werden soll. Wenn allerdings nur kurze Zeichenfolgen wie Ctrl+c gesendet werden, dürfte es keinen relevanten Unterschied machen.

Mein ClipWait, 1000 ist ein Screibfehler, ich dachte da wohl an 1000 Millisekunden. ClipWait, 1, 1 würde ich in diesem Fall allerdings nicht benutzen, weil der zweite Parameter bewirkt, dass auch dann nicht weiter gewartet wird, wenn sich etwas Anderes als Text im Clipboard findet. Du brauchst ja aber den Text / die Dateipfade.

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

Re: Mehrere markierte Dateien behandeln

05 Oct 2015, 16:54

Hallo just me!

Wie kann ich jetzt die URLs gleichzeitig abarbeiten, umbenennen und wieder zuordnen?
Ich habe hier ein Tool (das ist eines der erwähnten fertigen Anwendungen) zum Trimmen des Namens auf einen bestimmten Standard: [Signaturname]_[laufende Nr. 4stellig]_[laufender Index 2stellig]

Code: Select all

F9::											
	Clipboard := ""
	Send, {F2}^a^c
	ClipWait, 1, 1
	AlterName := Clipboard
		
	StringSplit, OldName, AlterName, `_
	NewSign := SubStr("0000" . OldName2, -3)	; Setzt neue Signatur auf 4 Ziffern
	NewIndex := SubStr("00" . OldName3, -1)		; Setzt neuen Index auf 2 Ziffern
	Send, %OldName1%_%NewSign%_%NewIndex%		; Neu benennen
return
Aus 'Mallorka_23_1' wird damit jetzt 'Willi_0023_01'.
Jetzt habe ich angefangen, Deinen Code zu übertragen und dabei die Variable für das Speichern der URLs 'DateienAuswahl' genannt:

Code: Select all

F7::
	Clipboard := ""
	SendInput, ^c
	Clipwait, 1
	If (ErrorLevel = 0)
	DateienAuswahl := Clipboard
	
	Loop, Parse, DateienAuswahl, `n, `r
		(
		...
		)
	...
return
Und ab hier weiß ich nicht mehr weiter. Kann ich jetzt einfach den zweiten Teil meines Scripts oben in die Schleife setzen? Werden die Dateien (in diesem Fall meine Bilder) mit dem Loop, Parse aufgerufen? Markiert (dafür ist mein Sript gemacht, dann bräuchte ich aber noch den oberen Teil dazu!) oder wird sie gar geöffnet?
Wie wird die Schleife dann gestoppt? Wie muß ich das dann abschließen?

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

Re: Mehrere markierte Dateien behandeln

06 Oct 2015, 01:27

Moin Meister,

das Umbenennen mit Send wird für eine Mehrfachauswahl nicht funktionieren, weil der Explorer nicht wissen kann, welcher der markierten Einträge gemeint ist. Du wirst sie also per FileMove selbst umbenennen müssen. Das könnte so aussehen (ungetestet):

Code: Select all

F7::
   Clipboard := ""
   SendInput, ^c
   Clipwait, 1
   If (ErrorLevel) ; keine Dateien im Clipboard
      Return
      
   DateienAuswahl := Clipboard

   Loop, Parse, DateienAuswahl, `n, `r
   {
      SplitPath, A_LoopField, , Verzeichnis, Erweiterung, AlterName
      StringSplit, OldName, AlterName, `_
      NewSign := SubStr("0000" . OldName2, -3)  ; Setzt neue Signatur auf 4 Ziffern
      NewIndex := SubStr("00" . OldName3, -1)   ; Setzt neuen Index auf 2 Ziffern
      FileMove, %A_LoopField%, %Verzeichnis%\%OldName1%_%NewSign%_%NewIndex%.%Erweiterung%
   }
return
Um das Ergebnis zu sehen, musst Du das Explorerfenster wahrscheinlich aktualisieren.

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

Re: Mehrere markierte Dateien behandeln

08 Oct 2015, 17:31

Hallo just me!
Oder muß ich eigentlich besser "just you" schreiben? ;)

Also dafür, daß Du das - wie Du sagst - noch gar nicht getestet hast, war das schon ganz passabel. Genauer gesagt, es hat auf Anhieb und einwandfrei funktioniert!! :clap:
Vielen Dank!

Jetzt habe ich mich daran gemacht, eine weitere Umbenennen-Option, die ich schon vorher hatte, nach diesem Schema zu modifizieren.
Die ist mit einer zusätzlichen Eingabe verbunden und danach scheint mein Script nicht mehr weiter zu laufen.
Ziel ist es, nach derselben Vorlage, die bereits das obige Programm benützt, Bilder mit einer einzugebenden Signaturnummer und einem laufenden Index zu benennen. Folgendes Script verwende ich dazu bereits:

Code: Select all

NumpadEnter::
	Clipboard := "" 					; ClipBoard leeren, damit ClipWait funktioniert
	Send, 	^a^c 						; mit Control+C Dateinamen inkl. Pfad ins ClipBoard kopieren
	ClipWait, 1, 1 						; kurz warten, bis der Dateiname im ClipBoard angekommen ist
	StartSign := Clipboard				; Abspeichern der Starteingabe für die Nummerierung (0000,00)

	StringSplit, StartArray, StartSign, `,

	LetzteSign := SubStr("0000" . StartArray1, -3)	; setzt die Signatur auf 4 Ziffern
	ParamIndex := StartArray2						; Parameter für die Schleife
	LetzterIndex := 1  								; Setzt Index auf 1
	
	Loop , %ParamIndex%
	{
		LetzterIndex := SubStr("00" . LetzterIndex, -1)  ; Setzt Index auf 1 in 2 Ziffern
		Send, %AktSign%_%LetzteSign%_%LetzterIndex%
		LetzterIndex := ++LetzterIndex
		Send, {Tab}{F2}
	}
return
Das erste Bild wird angewählt und zum Umbenennen aktiviert. Darauf gibt man die Signaturnummer ein und die Anzahl der umzubenennenden Bilder, getrennt durch ein Komma. Durch die Enter-Taste des Numpad wird dann diese Anzahl von Bildern nach dem obigen Schema mit laufendem Index umbenannt (Der Wert von "AktSign" wird vorher in einem separaten Input eingegeben, da er in mehreren Anwendungen gleichermaßen benötigt wird).
Nun möchte ich das genauso modifizieren wie das andere Tool, das heißt ich möchte mir die Bilder durch anklicken auswählen können und unabhängig von deren Anzahl umbenennen. Dafür müßte währen des Ablaufs noch eine Eingabe für die Signaturnummer erfolgen.
Ich habe jetzt mal so angefangen:

Code: Select all

F7::
	Clipboard := ""	
	SendInput, ^c
	Clipwait, 1
	If (ErrorLevel) ; keine Dateien im Clipboard
      return
	InputBox, LetzteSign, Bilder durchnummerieren, Signaturnummer:
	
	LetzteSign := SubStr("0000" . LetzteSign, -3)	 ; Setzt Signatur auf 4 Ziffern
	LetzterIndex := 1								 ; Setzt Index auf 1	
	LetzterIndex := SubStr("00" . LetzterIndex, -1)  ; Setzt Index auf 2 Ziffern
	
	Loop, Parse, DateienAuswahl, `n, `r
   {
      SplitPath, A_LoopField, , Verzeichnis, Erweiterung, SignName
	  FileMove, %A_LoopField%, %Verzeichnis%\%LetzteSign%_%LetzterIndex%.%Erweiterung%
	  LetzterIndex := ++LetzterIndex
	}
return	
Bis zur InputBox läuft das auch, aber danach passiert nichts mehr - auch kein Fehler u.ä.
Muß da irgendwo noch eine Art von "run"-Befehl rein?

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

Re: Mehrere markierte Dateien behandeln

09 Oct 2015, 00:56

Hallo Meister,

das kann so mit 'meiner' Methode nicht funktionieren.

Wenn der Dateiname bereits zum Umbennen editierbar gemacht wurde, kopiert SendInput, ^c bestenfalls den editierbaren Namensteil. In DateienAuswahl (diese Variable wird allerdings in Deinem unteren Beispiel überhaupt nicht versorgt) würde sich also bestenfalls 1 Dateiname befinden, d.h. das Loop, Parse, ... würde bestenfalls einmal durchlaufen und auch da nicht funktionieren, weil es keinen kompletten Dateipfad hat.

Ich würde deshalb bei Deinem ersten Ansatz bleiben, vor Allem auch deshalb, weil er ja bisher schon genau das macht, was Du willst.

Alternativ bliebe nut die Möglichkeit, die (nicht editierbar gemachte) Auswahl per SendInput, ^c einzulesen, per SplitPath den Dateipfad zu ermitteln und dann per Loop, Files das komplette Verzeichnis abzuarbeiten, bis der kopierte Dateipfad erreicht ist. Das wäre dann der Startpunkt für das Umbenennen der gewünschten Anzahl von Dateien innerhalb der Schleife. Weil die Anzeige im Explorer aber nicht immer mit der Reihenfolge übereinstimmt, die Loop, Files liefert, könnte es auch unangenehme Überraschungen geben.

In den 'guten alten Zeiten' als die Dateianzeige im Explorer noch ein gemeiner/common ListView war, hätte es auch noch weitere 'einfache' und zuverlässige Möglichkeiten gegeben. Diese Tür hat Microsoft aber zugemacht, wahrscheinlich um Manipulationen der Anzeige zu erschweren.

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

Re: Mehrere markierte Dateien behandeln

15 Oct 2015, 17:50

Hallo just me!
das kann so mit 'meiner' Methode nicht funktionieren.
Sag niemals nie!
Dein Hinweis auf den fehlenden Zusammenhang der Variable Dateienauswahl, die ja über die InputBox aus gefüttert werden sollte, war Gold wert!
Jetzt klappt es, wie ich es mir vorgestellt habe, bis auf einen kleinen Schönheitsfehler.
Die Bilder werden jetzt zwar umbenannt mit laufendem Index, aber aus einem mir unerfindlichem Grund nicht immer in derselben Reihenfolge, wie sie im Win Explorer/im Dateienordner vorliegen. Immer wieder werden sie mal nach einem von mir noch nicht durchschauten System neu umgestellt. Vermutlich geschieht das bereits beim ersten Abspeichern der URLs. Allerdings hatte ich dieses Problem mit dem anderen Tool, das ich zuvor angefertigt hatte, und mit genau demselben Code zum Speichern der URLs der ausgewählten Bilder versehen ist, nicht.

Hier ist nochmals der Code des neuen Scripts:

Code: Select all

; Eingabe der bei den Umbenennungsvorgängen zu verwendenden Bestandssignatur
F11::		
InputBox, AktSign, Bestandssignatur, Bitte geben Sie hier die zum Nummerieren zu verwendende Bestandssignatur ein!
return
;------------------
; Benennt die ausgewählten Dateien mit der aktuellen Bestandsignatur, einer einzugebenden Aktensignatur und einem laufenden Index
F8::		
	Clipboard := ""	
	SendInput, ^c
	Clipwait, 1
	If (ErrorLevel) ; keine Dateien im Clipboard
      return
	DateienAuswahl := Clipboard
	InputBox, LetzteSign, Bilder durchnummerieren, Signaturnummer:
	
	LetzteSign := SubStr("0000" . LetzteSign, -3)	 ; Setzt Signatur auf 4 Ziffern
	LetzterIndex := 1								 ; Setzt Index auf 1	
	LetzterIndex := SubStr("00" . LetzterIndex, -1)  ; Setzt Index auf 2 Ziffern
	
	Loop, Parse, DateienAuswahl, `n, `r
   {
      SplitPath, A_LoopField, , Verzeichnis, Erweiterung, SignName
	  FileMove, %A_LoopField%, %Verzeichnis%\%AktSign%_%LetzteSign%_%LetzterIndex%.%Erweiterung%
	 ;LetzterIndex := ++LetzterIndex
	  LetzterIndex := SubStr("00" . ++LetzterIndex, -1)
	}
return
Kannst Du mir dafür nochmals einen Tip geben?

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

Re: Mehrere markierte Dateien behandeln

16 Oct 2015, 02:14

Moin Meister!
Sag niemals nie!
Ich habe auch gar nicht nie gesagt, sondern so nicht. ;)

Nach meinen Beoabchtungen wird bei einer Mehrfachauswahl per Shift-Click im Explorer immer die zuletzt ausgewählte Datei an den Anfang gestellt. Der Rest entspricht der Anzeigereihenfolge im Explorer.
Bei einer Mehrfachauswahl per Ctrl-Click wird das etwas unübersichtlicher. Bau doch einfach mal eine MsgBox, %DateienAuswahl% ein und schau nach, ob Dir Regelmäßigkeiten in den Unregelmäßigkeiten auffallen.

Wenn die Exploreranzeige immer alphabetisch nach Namen sortiert ist, könnte eine Sortierung der eingelesenen Dateien mit Sort, DateienAuswahl, CL helfen (siehe). Ich bin aber nicht 100-%-ig sicher, ob die Sortierung in AHK immer genau der im Explorer entspricht.

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

Re: Mehrere markierte Dateien behandeln

31 Jan 2018, 02:49

Hallo!

Ich will diesen Thread nochmals aufgreifen, denn das Thema ist für mich wieder aktuell geworden, nachdem ich eine Weile mit anderem zu tun hatte.
Ich habe mein ursprüngliches Umbenennungstool inzwischen auch etwas erweitert und jetzt versucht, die oben empfohlene Loop-Parse-Schleife einzuflechten. Die markierten Dateien werden zwar umbenannt, allerdings bleiben sie dabei nicht in der ursprünglichen Reihenfolge erhalten.
Wenn ich wüßte bzw. das Programm gleich erkennen würde , wie viele ich markiert habe, dann könnte es diese nacheinander abarbeiten. Das wäre eigentlich noch leichter in das bestehende Tool zu integrieren und auch schneller im Ablauf.
Meine Frage ist also:
Ich habe mehrere Dateien im Explorer hintereinander markiert. Wie bekommt der AHK heraus, wie viele es sind und wie setze ich dann den Focus wieder auf die erste von ihnen? Daraufhin könnten alle mit der Anzahl als Laufvariable in der Schleife nacheinander umbenannt werden.

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

Re: Mehrere markierte Dateien behandeln

31 Jan 2018, 05:20

Moin,

wenn Du immer noch die Zwischenablage nutzt, kannst Du ja in einer eigenen Loop, Parse, ... zunächst einmal die Anzahl der Dateien bestimmen. Es gibt dafür auch Alternativen.

Das folgende Skript holt die ausgewählten Dateien aus dem aktiven Explorerfenster, ohne die Zwischenablage zu bemühen. Das Problem bleibt aber dasselbe. Die zuletzt ausgewählte Datei (die mit dem Fokus) wird als erste geliefert, dann die übrigen in der Anzeigereihenfolge. Ich verstehe noch nicht, wie Du dieses Problem umschiffen willst. Es ist ja auch möglich, dass das Fenster nicht nach Namen sortiert ist. Man kann den Fokus setzen, wie soll das aber helfen?

Code: Select all

#NoEnv
^+s::
   WinGet, ExplorerID, ID, A
   ; hier könnte man noch prüfen, ob das überhaupt ein Explorerfenster ist
   Auswahl := GetSelectedItems(ExplorerID, Anzahl)
   MsgBox, 0, %Anzahl% ausgewählte Datei(en), %Auswahl%
Return

; --------------------------------------------------------------------------------------------------
; Ausgewählte Dateien aus dem übergebenen Explorerfenster auslesen.
; Die Funktion gibt eine durch "`n" getrennte Liste von Dateipfaden zurück.
; Im Parameter Anzahl wird ggf. die Anzahl der Dateien abgelegt.
; --------------------------------------------------------------------------------------------------
GetSelectedItems(ExplorerID, ByRef Anzahl := 0) {
   Anzahl := 0
   SelectedItems := ""
   For Window In ComObjCreate("Shell.Application").Windows {
      If (Window.HWND = ExplorerID) && (Window.Document.SelectedItems.Count > 0) {
         For Item In Window.Document.SelectedItems {
            Anzahl++
            SelectedItems .= Item.Path . "`n"
         }
      }
   }
   Return RTrim(SelectedItems, "`n") ; letztes "`n" entfernen
}
Grüße,
just me

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: No registered users and 20 guests