Dynamisches Menu mit Loop auf .txt erstellen Topic is solved

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

User avatar
Heloo1982
Posts: 27
Joined: 12 Jan 2017, 07:39

Dynamisches Menu mit Loop auf .txt erstellen

10 Jan 2019, 10:32

Hallo zusammen,

ich mal wieder einen kleinen Hänger und hoffe es kann mir einer helfen.

Hintergrund:
Ich möchte eine kleines Tool für Textbausteine erstellen. Die User, welche es später anwenden, haben AHK nicht installiert und erhalten daher nur die compilierte .exe, sollen jedoch die Textbausteine selbst verwalten.
Idee:
Das Skript holt sich seine Variablen bei jedem Start aus einer .txt und baut dann dynamisch ein Menu auf, welches über einen Hotstring "++" aufgerufen werden kann. Es gibt zwei hart gecodete Hauptordner "WS" und "QS", die Submenu darunter und die "ausführenden Einträge" können über die .txt gesteuert werden.

Grundsätzlich funktioniert es ja schon mal, jedoch soll der erste und der zweite Eintrag im gleichen Submenu landen. Wenn ich in der zweiten Spalte jedoch gleiche Namen verwende, dann zeigt er ihn richtigerweise nur einmal an, aber der erste Eintrag in Spalte 3 wird überschrieben bzw. taucht im Menu nicht auf.
AHK.JPG
AHK.JPG (4.93 KiB) Viewed 458 times
Wo hab ich denn da den Denkfehler?

Hier meine Textbausteine.txt:

Code: Select all

WS	Ordner1	hallo1	der erste
WS	Ordner1	hallo2	der zweite
QS	Ordner2	hallo3	der dritte
QS	Ordner3	hallo4	der vierte
und hier das Skript:

Code: Select all

Loop, read, Ordner/Textbausteine.txt, 
{
  
	
	Loop, parse, A_LoopReadLine, %A_Tab%
	
	If (A_LoopField = "")	
					break
				else	
					Einzelmerkmale 			:= StrSplit(A_LoopReadLine, A_Tab)
					ebene1_%A_Index%		:= Einzelmerkmale[2]
					Ebene1					:= % ebene1_%A_Index%
					
					ebene2_%A_Index%		:= Einzelmerkmale[3]
					Ebene2					:= % ebene2_%A_Index%
					
					ebene3_%A_Index%		:= Einzelmerkmale[4]

					
					
					if(Einzelmerkmale[1]="WS")
						{	
					Menu, WS%Ebene2%, add,  %A_Index%.%Ebene2%, Senden_Dummy%A_Index%		
					Menu, WSEbene1, add,  %Ebene1%,	:WS%Ebene2%	
						}
					if(Einzelmerkmale[1]="QS")
						{
					Menu, QS%Ebene2%, add,  %Ebene2%, Senden_Dummy%A_Index%
					Menu, QSEbene1, add,  %Ebene1%,	:QS%Ebene2%
						}		
}

:*:++::
Menu, Start, add, WS, :WSEbene1
Menu, Start, add, QS, :QSEbene1
Menu, Start, show
Return

Senden_Dummy1:
Textbaustein := % ebene3_1
Gosub TxtSenden
Return
Senden_Dummy2:
Textbaustein := % ebene3_2
Gosub TxtSenden
Return
Senden_Dummy3:
Textbaustein := % ebene3_3
Gosub TxtSenden
Return
Senden_Dummy4:
Textbaustein := % ebene3_4
Gosub TxtSenden
Return

TxtSenden:
Sendinput %Textbaustein%
Return
Danke und Gruß
User avatar
Gerdi
Posts: 155
Joined: 03 Aug 2015, 18:48
GitHub: grrdi
Location: Germany

Re: Dynamisches Menu mit Loop auf .txt erstellen

12 Jan 2019, 15:33

Deine Einrückungen passen überhaupt nicht zu der Klammerung. Setze mal konsequent hinter jeden Loop und hinter jedes if ein
{
und ein
}
Dann lasse es in Scite4Autohotkey im Debugmodus (F7) laufen.

Wenn Du dann noch Hilfe brauchst poste nochmals mit korrekter Klammerung.
Win 10 Home (x64) or Win 7 Enterprise
https://github.com/Grrdi/ZackZackOrdner ... master.zip --> get folders on the quick
User avatar
Heloo1982
Posts: 27
Joined: 12 Jan 2017, 07:39

Re: Dynamisches Menu mit Loop auf .txt erstellen

15 Jan 2019, 13:37

Hallo Gerdi,

vielen Dank für deinen Hinweis, mir war nicht klar, dass es solch eindeutige Regeln für die Formatierung gibt.

SciTE4AutoHotkey hab ich runtergeladen und bin im Debug Mode jede Zeile durch, allerdings hat es mich nicht wirklich erleuchtet.
Ich habe im Loop eine MsgBox eingebaut und da habe ich gemerkt, dass er der Loop zu viele Schleifen hat, da er jede Zeile 2mal durchläuft.
Was ich allerdings nicht verstehe, denn ich dachte

Code: Select all

Loop, parse, A_LoopReadline, A_Tab
bedeutet, er teilt die variablen Reihe für Reihe auf und bricht die Schleife ab, sobald er eine leere Variable trifft.

Code: Select all

If (A_LoopField="") {	
				break
		}
Was natürlich blöd ist, weil er jede variable einmal unnötig überschreibt.

Wobei ich der Lösung meines ursprünglichen Problems meiner Meinung nach nicht näher gekommen bin, da er einen Menupunkt gar nicht erzeugt,
außer ich benenne den Ordner um, dann ist er auf einmal da.

Ich habe den Code nochmal aufgrund des Hinweises von Gerdi bzgl. der Klammern und des Einrückens angepasst, ich hoffe es passt jetzt halbwegs und der Code ist jetzt für alle besser zu lesen. Ich freue mich über jede Hilfe und bedanke mich schon einmal im Voraus.

Code: Select all

#NoEnv 
SendMode Input 
SetWorkingDir %A_ScriptDir%  


Loop, read, Ordner/Textbausteine.txt, 
{	

	Loop, parse, A_LoopReadLine, A_Tab
	{

	If (A_LoopField="") {	
				break
		}
							
		else	{
			Einzelmerkmale 			:= StrSplit(A_LoopReadLine, A_Tab)
			ebene1_%A_Index%		:= Einzelmerkmale[2]
			Ebene1					:= % ebene1_%A_Index%
			
			
			ebene2_%A_Index%		:= Einzelmerkmale[3]
			Ebene2					:= % ebene2_%A_Index%
			
			ebene3_%A_Index%		:= Einzelmerkmale[4]

			MsgBox % Einzelmerkmale[1] Einzelmerkmale[2] Einzelmerkmale[3] Einzelmerkmale[4]
			
			if(Einzelmerkmale[1]="WS")	{	
				Menu, WS%Ebene2%, add,%Ebene2%, Senden_Dummy%A_Index%		
				Menu, WSEbene1, add,  %Ebene1%,	:WS%Ebene2%	
				}
			if(Einzelmerkmale[1]="QS")	{
				Menu, QS%Ebene2%, add,  %Ebene2%, Senden_Dummy%A_Index%
				Menu, QSEbene1, add,  %Ebene1%,	:QS%Ebene2%
				}		
		}						
	}									
}

:*:++::
Menu, Start, add, WS, :WSEbene1
Menu, Start, add, QS, :QSEbene1
Menu, Start, show
Return

#Include labels.ahk

TxtSenden:
Sendinput %Textbaustein%
Return
User avatar
Gerdi
Posts: 155
Joined: 03 Aug 2015, 18:48
GitHub: grrdi
Location: Germany

Re: Dynamisches Menu mit Loop auf .txt erstellen

15 Jan 2019, 18:56

ersetze mal

Code: Select all

Loop, parse, A_LoopReadLine, A_Tab
Loop, parse, A_LoopReadLine, %A_Tab%
Dann funktioniert die Trennung nach den Tabulatoren.
Wegen der nochmaligen Trennung nach den Tabulatoren durch die StrSplit Befehle und der falschen Einrückung verstehe ich das Skript noch nicht.
Ich rücke mal ein streng nach der Klammerung:

Code: Select all

#NoEnv 
SendMode Input 
SetWorkingDir %A_ScriptDir%  


Loop, read, Ordner/Textbausteine.txt 
{	

	Loop, parse, A_LoopReadLine, %A_Tab%
	{

		If (A_LoopField="") 
		{	
			break
		}
							
		else	
		{
			Einzelmerkmale 			:= StrSplit(A_LoopReadLine, A_Tab)
			ebene1_%A_Index%		:= Einzelmerkmale[2]
			Ebene1					:= % ebene1_%A_Index%
			
			
			ebene2_%A_Index%		:= Einzelmerkmale[3]
			Ebene2					:= % ebene2_%A_Index%
			
			ebene3_%A_Index%		:= Einzelmerkmale[4]

			MsgBox % Einzelmerkmale[1] Einzelmerkmale[2] Einzelmerkmale[3] Einzelmerkmale[4]
			
			if(Einzelmerkmale[1]="WS")	
			{	
				Menu, WS%Ebene2%, add,%Ebene2%, Senden_Dummy%A_Index%		
				Menu, WSEbene1, add,  %Ebene1%,	:WS%Ebene2%	
			}
			if(Einzelmerkmale[1]="QS")	
			{
				Menu, QS%Ebene2%, add,  %Ebene2%, Senden_Dummy%A_Index%
				Menu, QSEbene1, add,  %Ebene1%,	:QS%Ebene2%
			}		
		}						
	}									
}

:*:++::
Menu, Start, add, WS, :WSEbene1
Menu, Start, add, QS, :QSEbene1
Menu, Start, show
Return

; #Include labels.ahk

TxtSenden:
Sendinput %Textbaustein%
Return
Dann sieht man auch dass Du mehrfach nach A_Tab trennst, --> erklärt die Doppelten.

Mein Tip entscheide Dich für die Parsende A_Tab Schleife oder für die Alternative StrSplit.
lass aber eines von beiden weg.
User avatar
Heloo1982
Posts: 27
Joined: 12 Jan 2017, 07:39

Re: Dynamisches Menu mit Loop auf .txt erstellen

16 Jan 2019, 04:04

Vielen Dank für den Tipp, die parsende Schleife war wirklich Schwachsinn. Ich habe hier einfach zu kompliziert gedacht und mich auch mit den Variablen verkünstelt. Dein Vorschlag hat mich wieder abgeholt, jetzt hab ich was ich wollte:

Code: Select all

Loop, read, Ordner/Textbausteine.txt, 
{	
		Einzelmerkmale 			:= StrSplit(A_LoopReadLine, A_Tab)
	
		Spalte4_%A_Index%		:= Einzelmerkmale[4]
				
		Menu, % Einzelmerkmale[2], add, % Einzelmerkmale[3], % "Senden_Dummy" A_index
		Menu, % Einzelmerkmale[1], add, % Einzelmerkmale[2],	% ":" Einzelmerkmale[2]
		

}

:*:++::
Menu, Start, add, WS, :WS
Menu, Start, add, QS, :QS
Menu, Start, show
Return

Senden_Dummy1:
Textbaustein := % Spalte4_1
Gosub TxtSenden
Return
Senden_Dummy2:
Textbaustein := % Spalte4_2
Gosub TxtSenden
Return
Senden_Dummy3:
Textbaustein := % Spalte4_3
Gosub TxtSenden
Return
Senden_Dummy4:
Textbaustein := % Spalte4_4
Gosub TxtSenden
Return

TxtSenden:
Sendinput %Textbaustein%
Return
Was mich momentan noch nervt sind die Dummy_Labels, hier habe ich in Excel halt mal 300 Stück erstellt und in ein anderes Skript ausgelagert.
Kann man die eigentlich nicht auch über einen Loop je Zeile erzeugen lassen?
User avatar
Gerdi
Posts: 155
Joined: 03 Aug 2015, 18:48
GitHub: grrdi
Location: Germany

Re: Dynamisches Menu mit Loop auf .txt erstellen

16 Jan 2019, 10:51

Wenn Du mit Dummy-labels die Ansprung-Labels bei KLick auf einen Menue-Eintrag meinst.
Dann gibt's da wahrscheinlich eine elegantere Lösung:
Lass alle Menue-Eintraege auf 1 Label verweisen und unterscheide dann im Unterprogramm mit einer A_*Menu* variablen.

Welche A_... variabeln es gibt zeigt Dir Scite an wenn Du in einem Quelltext A_ ein gibst und dann mit der Down-Taste durchblätterst.
Win 10 Home (x64) or Win 7 Enterprise
https://github.com/Grrdi/ZackZackOrdner ... master.zip --> get folders on the quick
User avatar
Heloo1982
Posts: 27
Joined: 12 Jan 2017, 07:39

Re: Dynamisches Menu mit Loop auf .txt erstellen  Topic is solved

16 Jan 2019, 15:31

Auch der Tip war gold wert, ich habe diese Variablen noch nie vorher benutzt. Ich denke, du hast es so oder so ähnlich gemeint?

Code: Select all

txtObjekt := {}

Loop, read, Ordner/Textbausteine.txt, 
{	
		Einzelmerkmale 			:= StrSplit(A_LoopReadLine, A_Tab)
		
		txtObjekt[Einzelmerkmale[2] Einzelmerkmale[3]] := Einzelmerkmale[4]
				
		Menu, % Einzelmerkmale[2], add, % Einzelmerkmale[3], txtSenden
		Menu, % Einzelmerkmale[1], add, % Einzelmerkmale[2],	% ":" Einzelmerkmale[2]

}

:*:++::
Menu, Start, add, WS, :WS
Menu, Start, add, QS, :QS
Menu, Start, show
Return

txtSenden:
Textbaustein := txtObjekt[A_ThisMenu A_ThisMenuItem]
Sendinput % Textbaustein
return
Sieht eigentlich ganz einfach aus, wenn man es weiß. Vielen Dank für deine Hilfe. :dance:
Liebe Grüße
User avatar
Gerdi
Posts: 155
Joined: 03 Aug 2015, 18:48
GitHub: grrdi
Location: Germany

Re: Dynamisches Menu mit Loop auf .txt erstellen

16 Jan 2019, 17:31

du hast es so oder so ähnlich gemeint?
genau

jetzt ist es richtig übersichtlich.


Eine Anmerkung bzw. Tip hätte ich noch
Ich weiss nicht wie lange Deine Textbausteine werden?
Der Send-Befehl läuft normalerweise so ab, dass man den Aufbau verfolgen kann (so ein optischer Effekt kann gewollt sein),
wenn sich in dieser Zeit ein Programm den Fokus holt, bekommt es den Rest des Textbausteines ab.

Wenn Du den jeweiligen Textbaustein ins Clipboard kopierst und dann nur noch ^v sendest
läuft das ganze anähernd unverzögert ab.
vorher noch TempClip := ClipboardAll
und danach Clipboard := TempClip restauriert den bisherigen Inhalt. Eventuell benötigt die Ergänzung noch Clipwait.

Ps. Die Textbausteine werden dann auch 1:1 verwendet
z.B. drei+sieben bleibt bei der Ausgabe
vorher würde dreiSieben ausgegeben.
Win 10 Home (x64) or Win 7 Enterprise
https://github.com/Grrdi/ZackZackOrdner ... master.zip --> get folders on the quick
User avatar
Heloo1982
Posts: 27
Joined: 12 Jan 2017, 07:39

Re: Dynamisches Menu mit Loop auf .txt erstellen

25 Jan 2019, 04:33

Danke, hab ich mit eingebaut.

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: No registered users and 34 guests