variable Variablen, Ordneraulistung, Menu, Option, variable Liste optimieren
jaja toller beitragstitel, trifft es aber nur zu gut...
hi, ich komme gleich zu meinem problem:
ich brauche Variablen (zahlen) in anderen Variablen bzw einen variablen Variablen Aufruf.
beispiel:
vorher habe ich die programme ausgelesen per dir befehl, das speicher ist jah möglich set "prog%count%=xxx"
aber das aufrufen nicht...
oder kenne ich den befehl nur nicht?
ich weiß leider auch nicht wie ich richtig danach suchen soll... "variable variabalen" liefert nichts anständiges...
bitte um hilfe,
Ph
hi, ich komme gleich zu meinem problem:
ich brauche Variablen (zahlen) in anderen Variablen bzw einen variablen Variablen Aufruf.
beispiel:
@echo off
cls
set /a "count=1"
:: VERSION
set version=0.0
title DiscMenu - Phlegma - ver.%version%
:: Das Menu liest den Ordnerinhalt aus, und erstellt dann Optionen zum anwählen.
for /f "delims=;" %%i in ('dir /b') do call :setprog "%%i"
set /a "count-=1"
echo.
echo.
echo Hi, du hast grade eine CD oder DVD von mir eingeschoben,
echo jetzt kannst du ausw„hlen welches Programm du installieren m”chtest!
echo.
echo Anzahl der gefunden Programme: %count%
echo.
if %count% EQU 0 goto end
if %count% GEQ 1 echo 1: %prog1%
if %count% GEQ 2 echo 2: %prog2%
if %count% GEQ 3 echo 3: %prog3%
if %count% GEQ 4 echo 4: %prog4%
if %count% GEQ 5 echo 5: %prog5%
if %count% GEQ 6 echo 6: %prog6%
if %count% GEQ 7 echo 7: %prog7%
if %count% GEQ 8 echo 8: %prog8%
if %count% GEQ 9 echo 9: %prog9%
if %count% GEQ 10 echo 10: %prog10%
if %count% GEQ 11 echo 11: %prog11%
if %count% GEQ 12 echo 12: %prog12%
echo.
set /p choice= Gib die Zahl deines Programms ein:
echo
::hier is grade baustelle....
for /f %%c in (1 2 3 4 5 6 7 8 9 10 11 12) do if %choice% EQU %%c start %prog%%c%
pause>nul
goto :eof
:setprog
echo zeile=%1
set "prog%count%=%~1"
::echo %prog1%,%prog2%,%prog3%
set /a "count+=1"
goto :eof
vorher habe ich die programme ausgelesen per dir befehl, das speicher ist jah möglich set "prog%count%=xxx"
aber das aufrufen nicht...
oder kenne ich den befehl nur nicht?
ich weiß leider auch nicht wie ich richtig danach suchen soll... "variable variabalen" liefert nichts anständiges...
bitte um hilfe,
Ph
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 62518
Url: https://administrator.de/contentid/62518
Ausgedruckt am: 22.11.2024 um 11:11 Uhr
13 Kommentare
Neuester Kommentar
Hallo Phlegma!
Sollte eigentlich so klappen ...
Um das Ganze etwas variabler zu machen, könntest Du auch etwa so vorgehen:
Um ":Fehler" und :Weiter" musst Du Dich selbst kümmern ...
Grüße
bastla
Sollte eigentlich so klappen ...
@echo off & setlocal enabledelayedexpansion
...
...
for /f %%c in (1 2 3 4 5 6 7 8 9 10 11 12) do if %choice% EQU %%c start !prog%%c!
...
@echo off & setlocal enabledelayedexpansion
...
...
if %count% EQU 0 goto end
for /l %%n in (1,1,%count%) do echo %%n:!prog%%n!
echo.
set /p choice= Gib die Zahl deines Programms ein:
echo.
set /a Nr=%choice%
if %Nr% leq 0 goto :Fehler
if %Nr% gtr %count% goto :Fehler
start "Fenstertitel" "!prog%Nr%!"
goto :Weiter
Grüße
bastla
Hallo Phlegma!
Im Prinzip war das schon OK, nur die Zählvariable sollte bei 0 beginnen, damit auch der (theoretische) Fall "Kein Programm gefunden" abgedeckt wird. Außerdem ersparst Du Dir dann auch das "set /a count-=1".
Warum verwendest Du eigentlich "delims=;"? Wenn's keinen besonderen Grund dafür gibt, müsste "delims=" reichen, um auch Programmnamen mit Leerstellen "am Stück" zu erhalten.
Da ich annehme, dass diese Batchdatei selbst nicht auch als Programm aufgelistet werden soll, würde ich noch eine entsprechende Überprüfung vor dem Aufruf von ":setprog" vorschlagen.
Die nächste Version könnte dann so aussehen:
Offen bleiben noch die Fehlerbehandlung und eine ev Verabschiedung (bei ":Ende") sowie die Anpassung der Versionsnummer .
Grüße
bastla
[Edit] @Biber: Danke, auch für die Ergänzungen zum Thema "delayedexpansion" (war bei mir leider auf der Strecke geblieben ...) [/Edit]
Im Prinzip war das schon OK, nur die Zählvariable sollte bei 0 beginnen, damit auch der (theoretische) Fall "Kein Programm gefunden" abgedeckt wird. Außerdem ersparst Du Dir dann auch das "set /a count-=1".
Warum verwendest Du eigentlich "delims=;"? Wenn's keinen besonderen Grund dafür gibt, müsste "delims=" reichen, um auch Programmnamen mit Leerstellen "am Stück" zu erhalten.
Da ich annehme, dass diese Batchdatei selbst nicht auch als Programm aufgelistet werden soll, würde ich noch eine entsprechende Überprüfung vor dem Aufruf von ":setprog" vorschlagen.
Die nächste Version könnte dann so aussehen:
@echo off & setlocal enabledelayedexpansion
set /a count=0
:: VERSION
set version=0.0
title DiscMenu - Phlegma - ver.%version%
:: Das Menu liest den Ordnerinhalt aus, und erstellt dann Optionen zum Anwählen.
for /f "delims=;" %%i in ('dir /b') do if "%%i" neq "%~nx0" call :setprog "%%i"
if %count% EQU 0 goto end
cls
echo.
echo.
echo Hi, du hast grade eine CD oder DVD von mir eingeschoben,
echo jetzt kannst du ausw„hlen, welches Programm du installieren m”chtest!
echo.
echo Anzahl der gefunden Programme: %count%
:Menue
echo.
for /l %%n in (1,1,%count%) do echo %%n:!prog%%n!
echo.
echo 0:Ende
echo.
echo.
set /p choice= Gib die Zahl deines Programms ein:
echo.
set /a Nr=%choice%
if %Nr% equ 0 goto :Ende
if %Nr% lss 0 goto :Fehler
if %Nr% gtr %count% goto :Fehler
start "Fenstertitel" "!prog%Nr%!"
cls
goto :Menue
:setprog
set /a count+=1
set "prog%count%=%~1"
goto :eof
Grüße
bastla
[Edit] @Biber: Danke, auch für die Ergänzungen zum Thema "delayedexpansion" (war bei mir leider auf der Strecke geblieben ...) [/Edit]
Moin Phlegma, moin bastla,
was soll ich noch großartig an bastlas Lösungsansätzen verbessern wollen?
Aber um Dir, Phlegma, noch einmal näherzubringen, dass man/frau sich nur Sachen wünschen sollte, wenn sich auch die Nebenwirkungen der Wunscherfüllung klar abschätzen lassen...
...natürlich geht es ohne "DelayedExpansion", haben wir ja früher auch so gemacht... vor der Währungsreform...
Einfacher zu lesen (oder zu schreiben) wird es dadurch allerdings nur bedingt.
Eine Variation von bastlas Schnipsel ohne "verzögerte Variablenauflösung" folgt...
Wie bei mir üblich, ist das "ECHO" nur zum Testen drin..
Sagen wir so - wenn ich die Wahl hätte, würde ich auf die (trotz alledem) lesbarere EnableDelayedExpansion-Variante umsteigen...
...die von mir vorgeturnte Variante mit x-mal %-Zeichen drumherumwickeln ist nerviger.
Und fehlerträchtiger.
Grüße
Biber
was soll ich noch großartig an bastlas Lösungsansätzen verbessern wollen?
Aber um Dir, Phlegma, noch einmal näherzubringen, dass man/frau sich nur Sachen wünschen sollte, wenn sich auch die Nebenwirkungen der Wunscherfüllung klar abschätzen lassen...
...natürlich geht es ohne "DelayedExpansion", haben wir ja früher auch so gemacht... vor der Währungsreform...
Einfacher zu lesen (oder zu schreiben) wird es dadurch allerdings nur bedingt.
Eine Variation von bastlas Schnipsel ohne "verzögerte Variablenauflösung" folgt...
::--------snipp DiscMenu-BiberVariante.bat
@echo off & setlocal <b>disableDelayedExpansion</b>
set /a count=0
:: VERSION
set version=0.0
title DiscMenu - Phlegma - ver.%version%
:: Das Menu liest den Ordnerinhalt aus, und erstellt dann Optionen zum Anwählen.
for /f "delims=;" %%i in ('dir /b ') do if "%%i" neq "%~nx0" call :setprog "%%i"
if %count% EQU 0 goto end
cls
echo.
echo.
echo <b>Moin,</b> du hast grade eine CD oder DVD von mir eingeschoben,
echo jetzt kannst du auswählen, welches Programm du installieren möchtest!
echo.
echo Anzahl der gefundenen Programme: %count%
:Menue
echo.
for /l %%n in (1,1,%count%) do <b>call echo %%n:%%prog%%n%%</b>
echo.
echo 0:Ende
echo.
echo.
set /p choice= Gib die Zahl deines Programms ein:
echo.
set /a Nr=%choice%
if %Nr% equ 0 goto :Ende
if %Nr% lss 0 goto :Fehler
if %Nr% gtr %count% goto :Fehler
<b>call ECHO start "Fenstertitel" "%%prog%Nr%%%"</b>
<b>pause</b>
cls
goto :Menue
:setprog
set /a count+=1
set "prog%count%=%~1"
goto :eof
::--------snapp DiscMenu-BiberVariante.bat
Wie bei mir üblich, ist das "ECHO" nur zum Testen drin..
Sagen wir so - wenn ich die Wahl hätte, würde ich auf die (trotz alledem) lesbarere EnableDelayedExpansion-Variante umsteigen...
...die von mir vorgeturnte Variante mit x-mal %-Zeichen drumherumwickeln ist nerviger.
Und fehlerträchtiger.
Grüße
Biber
Moin Phlegma,
kennst Du die alte Forumsweisheit "Neue Frage, neuer Beitrag"?
Ist ähnlich universell wie meine Lieblings-Bauernregel "April vorbei - Anfang Mai"...
Abgesehen davon - statt irgendeiner Vor-/Zurück-Blätterei mit Tasteneingabe "v" und "z"...*grusel*
...das sieht ja echt aus wie aus der Zeit vor Erfindung der Alufolie....
Mach doch stattdessen lieber den Bildschirm zwei Meter lang mit "mode con lines=300".
Bzw. statt "300" den Wert von %count%+10.
Das hast Du alles und bekommst es auch ohne Hilfe hin.
Grüße
Biber
kennst Du die alte Forumsweisheit "Neue Frage, neuer Beitrag"?
Ist ähnlich universell wie meine Lieblings-Bauernregel "April vorbei - Anfang Mai"...
Abgesehen davon - statt irgendeiner Vor-/Zurück-Blätterei mit Tasteneingabe "v" und "z"...*grusel*
...das sieht ja echt aus wie aus der Zeit vor Erfindung der Alufolie....
Mach doch stattdessen lieber den Bildschirm zwei Meter lang mit "mode con lines=300".
Bzw. statt "300" den Wert von %count%+10.
Das hast Du alles und bekommst es auch ohne Hilfe hin.
Grüße
Biber
... und damit es ein paar Zentimeter weniger werden:
Grüße
bastla
P.S.: @Biber - Ja, ich weiß ...
@echo off & setlocal enabledelayedexpansion
:: VERSION
set version=0.0
title DiscMenu - Phlegma - ver. %version%
set /a count=0
for /f "delims=;" %%i in ('dir /b /a-d') do if "%%i" neq "%~nx0" call :setprog "%%i"
if %count% EQU 0 goto :eof
set /a Zeilen=(%count%+2)/3
call :MenueText
mode con lines=(%Zeilen%+5)
cls
echo.
echo.
echo Hi, Du hast grade eine CD oder DVD von mir eingeschoben,
echo jetzt kannst Du ausw„hlen, welches Programm Du installieren m”chtest!
echo.
echo Anzahl der gefunden Programme: %count%
echo.
echo.
echo Weiter mit einer beliebigen Taste zur Programmauswahl ...
pause>nul
:Menue
cls
for /l %%n in (1,1,%Zeilen%) do echo!MZeile%%n!
echo.
echo.
set /p choice= Gib die Nummer Deines Programms ein (0 fr Ende):
set /a Nr=-1
set /a Nr=%choice% 2>nul
if %Nr% equ 0 goto :Ende
if %Nr% lss 0 goto :Fehler
if %Nr% gtr %count% goto :Fehler
start "Fenstertitel" "!prog%Nr%!"
goto :Menue
:setprog
set /a "count+=1"
set "prog%count%=%~1"
goto :eof
:MenueText
for /l %%m in (1,1,%Zeilen%) do (
set "MZeile%%m=."
set /a Nr=%%m
if !Nr! leq %count% set MZeile%%m=
if !Nr! leq %count% call :ProcessEntryForLine %%m
set /a Nr+=%Zeilen%
if !Nr! leq %count% call :ProcessEntryForLine %%m
set /a Nr+=%Zeilen%
if !Nr! leq %count% call :ProcessEntryForLine %%m
)
goto :eof
:ProcessEntryForLine
set "NrForm= %Nr%"
set "ProgForm=!prog%Nr%! "
set "MZeile%1=!MZeile%1!%NrForm:~-4%: %ProgForm:~0,19% "
goto :eof
:Fehler
echo.
echo.
echo Ungltige Auswahl - bitte Taste drcken und erneut versuchen...
pause>nul
goto :Menue
:Ende
cls
echo.
echo CD/DVD nicht im Laufwerk vergessen!
echo.
echo.
echo Bitte noch einen letzten Tastendruck ...
pause>nul
Grüße
bastla
P.S.: @Biber - Ja, ich weiß ...
Hallo Phlegma!
2 Meter wird auch die Erklärung nicht brauchen, und außerdem: Du wolltest es ja so.
Da ich die Ausgabe in 3 Spalten anordne, muss ich feststellen, wie viele Menü-Zeilen ich brauchen werde. Die Berechnung führt eigentlich ein "Aufrunden" durch (die Division alleine rundet nämlich ab).
Entspricht Biber's Vorschlag, genügend Zeilen im CMD-Fenster zur Verfügung zu stellen (bei Bedarf kann nach oben gescrollt werden).
Im Unterprogramm ":MenueText" werden die Menüzeilen erstellt und in Variable gespeichert - vergleichbar mit dem vorherigen Speichern der Programme.
Ich weiß schon, wie viele Zeilen es werden sollen, daher eine Zählschleife ...
ist eigentlich nicht nötig. In einer ersten Version hatte ich die Zeilenzahl fix mit 20 vorgegeben (damit hätte auch das "Standard"-CMD-Fester gereicht) - die erste Zeile hätte beim späteren "echo" dafür gesorgt, dass eine Leerzeile ausgegeben wird, wenn nicht genug Programme aufzulisten gewesen wären (kannst Du probieren, indem Du vor der Schleife ein "set /a Zeilen=20" einfügst und nur wenige Programme verwendest). Die zweite Zeile hätte den Punkt wieder gelöscht, wenn es doch keine Leerzeile werden sollte.
Da ich mit der Zeilennummer noch rechnen muss, wird diese in eine numerische Variable (Eintrags-Nummer) übernommen.
Für jede Spalte wird (wenn es noch Programmdaten gibt, festzustellen durch den Vergleich Eintrags-Nummer <= Programmanzahl) im Unterprogramm ":ProcessEntryForLine" ein Eintrag erzeugt, wobei sich die Eintrags-Nummer immer um die Zeilenzahl erhöhen muss.
Beispiel: Bei 16 Einträgen müssen 6 Zeilen erzeugt werden (siehe Formel oben), wobei in der ersten Spalte die Programme 1 bis 6 stehen, daneben 7 bis 12 - also jeweils um 6 (= Zeilenanzahl) mehr - und in der letzten Spalte 13 bis 16 (wieder um 6 mehr als in der Spalte davor).
Da diese Aufrufe alle in der Schleife erfolgen, muss mit "delayedexpansion" die jeweils aktuelle Eintrags-Nummer !Nr! gelesen werden. Würde ich %Nr% schreiben, wäre das Ergebnis immer 0 (weil nur beim Beginn der Schleife einmal der Wert von %Nr% ermittelt würde, und es da diese Variable noch nicht einmal gab).
Das Unterprogramm ":ProcessEntryForLine" hat eigentlich nur die Aufgabe, die Einträge zu formatieren und zu einer Zeile zusammenzufügen.
Zuerst werden vor die Nummer Leerstellen platziert (und nachher auf 4 Stellen rechtsbündig "zurechtgeschnitten") und an den Programmnamen ausreichend Leerstellen angehängt. Beim Zusammenfügen wird an den schon vorhandenen Teil der Zeile (bei der dritten Spalte etwa befinden sich schon die Einträge der ersten beiden Spalten in !MZeile%1!) der neue Eintrag angefügt, wobei durch die Längenangaben für Nummer (letzte 4 Stellen) und Text (erste 19 Stellen) für ein ordentliches Untereinanderschreiben gesorgt wird.
Zu !MZeile%1!: Da beim Aufruf des Unterprogramms die Zeilennummer als Parameter mitgegeben wurde, steht sie hier als %1 zur Verfügung.
Die Ausgabe des Menüs erfolgt einfach mit einer weiteren Zählschleife:
Gleiches Prinzip, nur dass eben hier direkt die Schleifenvariable %%n verwendet wird.
Um einem irrtümlichen Drücken der Eingabetaste vorzubeugen, wird %Nr% zunächst auf -1 gesetzt. Wenn %choice% leer bleibt, kann wegen des Fehlers (deshalb hier auch 2>nul) keine neue %Nr% (diese Variable hätte ich vielleicht besser %ANr% nennen sollen, da sie mit der anderen Variable %Nr% in :MenueText genau nichts zu tun hat) "berechnet" werden und mit der nachfolgenden Abfrage auf lss 0 wird der Fehler abgefangen. Wird allerdings ein Text eingegeben, so ergibt sich daraus eine %Nr% mit Wert 0 und das Programm wird beendet - hier ließe sich noch nachbessern, etwa mit: if %Nr% equ 0 if "%choice:~0,1%" neq "0" goto :Fehler
Sollten noch Fragen offen geblieben sein - Du weißt, wo Du mich findest ...
Grüße
bastla
P.S.: Ich finde es gut, dass Du überhaupt fragst ...
2 Meter wird auch die Erklärung nicht brauchen, und außerdem: Du wolltest es ja so.
set /a Zeilen=(%count%+2)/3
mode con lines=(%Zeilen%+5)
Im Unterprogramm ":MenueText" werden die Menüzeilen erstellt und in Variable gespeichert - vergleichbar mit dem vorherigen Speichern der Programme.
for /l %%m in (1,1,%Zeilen%) do (
set "MZeile%%m=."
...
if !Nr! leq %count% set MZeile%%m=
set /a Nr=%%m
if !Nr! leq %count% call :ProcessEntryForLine %%m
set /a Nr+=%Zeilen%
if !Nr! leq %count% call :ProcessEntryForLine %%m
set /a Nr+=%Zeilen%
if !Nr! leq %count% call :ProcessEntryForLine %%m
Beispiel: Bei 16 Einträgen müssen 6 Zeilen erzeugt werden (siehe Formel oben), wobei in der ersten Spalte die Programme 1 bis 6 stehen, daneben 7 bis 12 - also jeweils um 6 (= Zeilenanzahl) mehr - und in der letzten Spalte 13 bis 16 (wieder um 6 mehr als in der Spalte davor).
Da diese Aufrufe alle in der Schleife erfolgen, muss mit "delayedexpansion" die jeweils aktuelle Eintrags-Nummer !Nr! gelesen werden. Würde ich %Nr% schreiben, wäre das Ergebnis immer 0 (weil nur beim Beginn der Schleife einmal der Wert von %Nr% ermittelt würde, und es da diese Variable noch nicht einmal gab).
Das Unterprogramm ":ProcessEntryForLine" hat eigentlich nur die Aufgabe, die Einträge zu formatieren und zu einer Zeile zusammenzufügen.
set "NrForm= %Nr%"
set "ProgForm=!prog%Nr%! "
set "MZeile%1=!MZeile%1!%NrForm:~-4%: %ProgForm:~0,19% "
Zu !MZeile%1!: Da beim Aufruf des Unterprogramms die Zeilennummer als Parameter mitgegeben wurde, steht sie hier als %1 zur Verfügung.
Die Ausgabe des Menüs erfolgt einfach mit einer weiteren Zählschleife:
for /l %%n in (1,1,%Zeilen%) do echo!MZeile%%n!
Um einem irrtümlichen Drücken der Eingabetaste vorzubeugen, wird %Nr% zunächst auf -1 gesetzt. Wenn %choice% leer bleibt, kann wegen des Fehlers (deshalb hier auch 2>nul) keine neue %Nr% (diese Variable hätte ich vielleicht besser %ANr% nennen sollen, da sie mit der anderen Variable %Nr% in :MenueText genau nichts zu tun hat) "berechnet" werden und mit der nachfolgenden Abfrage auf lss 0 wird der Fehler abgefangen. Wird allerdings ein Text eingegeben, so ergibt sich daraus eine %Nr% mit Wert 0 und das Programm wird beendet - hier ließe sich noch nachbessern, etwa mit: if %Nr% equ 0 if "%choice:~0,1%" neq "0" goto :Fehler
Sollten noch Fragen offen geblieben sein - Du weißt, wo Du mich findest ...
Grüße
bastla
P.S.: Ich finde es gut, dass Du überhaupt fragst ...