rexx3r
Goto Top

Auswahlliste automatisch erstellen

Hi,

ich möchte per Batch-Datei Unterordner erstellen. Dafür sollen die Namen der Übergeordneten Ordner erst per Eingabe der ersten 3 Buchstaben aufgelistet werden - mit Nummerierung. Aus dieser Liste soll man dann per Eingabe der Nummer den Entsprechenden Namen auswählen können.
Das entscheidende Problem ist die Nummerierung zu erzeugen und dann daraus eine Auswahl zu erstellen.

Dazu habe ich schon folgenden Code:
Echo Bitte keine Leerzeichen verwenden!!!
SET /P Ziel=Bitte Kundennamen eingeben (ersten 3 Buchstaben)...:
Echo.
Echo Liste der Verzeichnisse mit "%Ziel%":  
DIR /b /o /ad "P:Anfragen\%Ziel:~0,3%*.*" 2>nul || Echo -Das Kundenverzeichnis existiert noch nicht!-  
Echo.
Set /P Ziel=Bitte vollstaendigen Kundennamen eingeben ...:
SET Zielpfad=P:Anfragen
if defined AngNr (set AngNr=%AngNr%.0) else (set AngNr=%AngNralt%)
set verzeichnis=%Zielpfad%\%Ziel%
if exist %verzeichnis%
ul (goto istda) else (goto istnichtda)

Vielen Dank schonmal im Vorraus für eure Hilfe


MfG
ReXx3r

Content-Key: 63332

Url: https://administrator.de/contentid/63332

Printed on: April 19, 2024 at 20:04 o'clock

Member: bastla
bastla Jul 09, 2007, updated at Oct 18, 2012 at 16:32:11 (UTC)
Goto Top
Hallo ReXx3r und willkommen im Forum!

Etwas Ähnliches hatten wir hier ...

Grüße
bastla
Member: ReXx3r
ReXx3r Jul 09, 2007 at 12:14:51 (UTC)
Goto Top
Hi,
erstmal danke für die Antwort

aufgrund meiner beschränkten Batch Kenntnisse weiß ich nicht genau wie ich die Abfrage nach den Anfangsbuchstaben der Ordnernamen hinbekomme, zumal die auf einem anderen Laufwerk liegen.
Desweiteren möchte ich nur eine Spalte haben.

Ich hab schonmal bischen am Code gebastelt, hab aber keine Ahnung ob ich damit richtig liege:
::------------------------------------------------------------------------------------Abschnitt Verzeichnis prüfen
::          Abfrage Kundenname und Anzeige der Verzeichnisse (Vergleich der ersten 3 Buchstaben)
::

Echo Bitte keine Leerzeichen verwenden!!!
SET /P Ziel=Bitte Kundennamen eingeben (ersten 3 Buchstaben)...:
Echo.
Echo Liste der Verzeichnisse mit "%Ziel%":  
DIR /b /o /ad "P:\Anfragen\%Ziel:~0,3%*.*" 2>nul || Echo -Das Kundenverzeichnis existiert noch nicht!-  

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%
call :MenueText
mode con lines=(%Zeilen%+5)


:Menue
cls
for /l %%n in (1,1,%Zeilen%) do echo!MZeile%%n!
echo.
echo.
set /p choice=  Gib die Nummer des Kunden an (0 fr 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

if defined AngNr (set AngNr=%AngNr%.0) else (set AngNr=%AngNralt%)
set verzeichnis=%Zielpfad%\%Ziel%
if exist %verzeichnis%\nul (goto istda) else (goto istnichtda)

: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=%NrForm:~-4%: %ProgForm:"  
goto :eof
Was sich mir nicht erschließt sind folgende Zeilen, wäre nett wenn mir diese jmd erklären könnte:
for /f "delims=;" %%i in ('dir /b /a-d') do if "%%i" neq "%~nx0" call :setprog "%%i"  
if %count% EQU 0 goto :eof
wieso ist der if Ausdruck hier 3 mal da? Und was bedeutet das leq?
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
)
und noch eins: Wieso ist nach jedem Programmteil ein goto :eof (heißt doch eigtl Ende der Batchdatei?)


MfG
ReXx3r
Member: miniversum
miniversum Jul 09, 2007 at 13:08:21 (UTC)
Goto Top
Also mal von deinem Grundbatch ausgehend würd ichs so machen:
@echo off
setlocal enabledelayedexpansion
Echo Bitte keine Leerzeichen verwenden!!!
SET "Zielpfad=P:\Anfragen"  
SET /P Ziel=Bitte Kundennamen eingeben (ersten 3 Buchstaben)...:
Echo.
Echo Liste der Verzeichnisse mit "%Ziel%":  

set nr=0
for /F "delims=" %%a in ('DIR /b /on /ad "%Zielpfad%\%Ziel:~0,3%*.*" 2>nul || Echo -Das Kundenverzeichnis existiert noch nicht!-') do (  
set /a nr+=1
echo !nr! %%a
)

Echo.
Set /P Ziel=Bitte Wählen ...:

set "shift="  
if %Ziel% gtr 1 set /a shift=%Ziel%-1
set "Ziel="  
for /F "skip=%shift% delims=" %%a in ('DIR /b /on /ad "%Zielpfad%\%Ziel:~0,3%*.*"') do if not defined Ziel set Ziel=%%a  

echo ausgewählter Kundenname: %Ziel%

miniversum
Member: ReXx3r
ReXx3r Jul 09, 2007 at 14:07:22 (UTC)
Goto Top
Danke miniversum, aber irgendwie funktioniert deine Variante nicht,
kann das sein dass das daran liegt dass du mehrere Befehle in der For schleife hast?

Abgesehen davon dass ich schon paar Fehler korigieren musste:
SET Zielpfad=##red|"##P:\Anfragen"  
und diese
set "shift="  
set "Ziel="  
kann man auch nicht so stehen lassen oder?

MfG
ReXx3r
Member: miniversum
miniversum Jul 09, 2007 at 14:45:49 (UTC)
Goto Top
Mein Code war ungetestet. Ändere die Forschleife mal um:
for /F "delims=" %%a in ('DIR /b /on /ad "%Zielpfad%\%Ziel:~0,3%*.*" 2^>nul ^|^| Echo -Das Kundenverzeichnis existiert noch nicht!-') do (
dann sollte es gehen.
Die set anweisungen stimmen so.

miniversum
Member: bastla
bastla Jul 09, 2007 at 17:21:47 (UTC)
Goto Top
Hallo ReXx3r!

Falls Du noch interessiert bist:
@echo off & setlocal enabledelayedexpansion
::------------------------------------------------------------------------------------Abschnitt Verzeichnis prüfen
::          Abfrage Kundenname und Anzeige der Verzeichnisse (Vergleich der ersten 3 Buchstaben)
::
cls
set "Zielpfad=P:\Anfragen"  
set /a count=0

set /P Ziel=Bitte Kundennamen eingeben (erste 3 Buchstaben)...:
set Ziel=%Ziel: =%

for /f "delims=" %%i in ('dir /b /o /ad "%Zielpfad%\%Ziel:~0,3%*.*" 2^>nul') do (  
	set /a count+=1
	set "Verz!count!=%%i"  
	set "NrForm=   !count!"  
	set "MZeile!count!=!NrForm:~-4!: %%i"  
)
if %count% equ 0 Echo -Das Kundenverzeichnis existiert noch nicht!- & goto :istnichtda

:Menue
cls
echo.
echo Liste der Verzeichnisse mit "%Ziel%":  
echo.
for /l %%n in (1,1,%count%) do echo!MZeile%%n!
echo.
echo.
set /p choice=Gib die Nummer des Kunden an (0 fr 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

::Was Du mit AngNr etc vorhast, kann ich nicht erkennen ...
::if defined AngNr (set AngNr=%AngNr%.0) else (set AngNr=%AngNralt%)
set "verzeichnis=%Zielpfad%\!Verz%Nr%!"  
if not exist "%verzeichnis%\" goto :istnichtda  
echo.
echo.
echo Kundenverzeichnis: %verzeichnis%
:: was halt
:: noch so
:: anliegt ...
goto :eof

:istnichtda
echo.
echo.
echo Verzeichnis %verzeichnis% nicht gefunden.
goto :eof

:Fehler
echo.
echo.
echo Bitte nur 0 bis %count% verwenden . . .
echo.
pause
goto :Menue

:Ende
echo.
echo.
echo Programm beendet
goto :eof
Ich hab' das Ganze etwas entschlackt und auf eine Spalte reduziert, aber die Formatierung der Nummern (mit führenden Leerstellen, um sie rechtsbündig untereinander zu schreiben) noch beibehalten.

Zu Deinen Fragen:
for /f "delims=;" %%i in ('dir /b /a-d') do if "%%i" neq "%~nx0" call :setprog "%%i"  
Diese "for"-Zeile hatte die Aufgabe, alle Dateien des aktuellen Ordners mit Ausnahme der Batchdatei selbst ("%~nx0") in die Liste aufzunehmen - dafür wurde ein Unterprogramm verwendet. Beim Aufruf des Unterprogramms wurde der Dateiname als Parameter mitgeliefert. Im Unterprogramm wurde ua ein Zähler %count% jeweils um 1 erhöht.
if %count% EQU 0 goto :eof
Falls nach Durchlaufen der Schleife der Zähler immer noch auf 0 stand, konnte der Batch beendet werden (da keine Dateien gefunden worden waren).

wieso ist der if Ausdruck hier 3 mal da? Und was bedeutet das leq?
3 Spalten - 3 Unterprogrammaufrufe zur Formatierung und vollständigen Erstellung der Menüzeile.
"leq" steht für "less or equal" oder auch "<=": Solange noch nicht alle %count% Einträge in den Menüzeilen erfasst waren, musste das Unterprogramm noch aufgerufen werden.

Wieso ist nach jedem Programmteil ein goto :eof (heißt doch eigtl Ende der Batchdatei?)
Da jedes Unterprogramm als eigene "Batchdatei" aufgefasst werden kann (früher musste dafür tatsächlich jeweils eine eigene Datei existieren, jetzt genügt eine Sprungmarke), bedeutet das einfach "Ende des Unterprogramms - Rücksprung zum aufrufenden Programm" (vergleichbar einer "Return"-Anweisung in älterem BASIC).
Vielleicht noch abschließend zum Unterschied zu miniversum's Ansatz: In meiner Variante werden die gefundenen Verzeichnisse in einer Art "Array" vorweg gespeichert (die Menüzeilen übrigens auch - bei nur einer Spalte schon fast Luxus face-wink). Das Array wird simuliert, indem die Variablennamen laufend nummeriert werden, also %Verz1%, %Verz2%, ..., %Verz%Nr%%. Wie ersichtlich ist, wäre der letzte Name nicht richtig zu interpretieren (worauf soll sich das "%" nach "Verz" beziehen), daher wird mit der "delayed expansion" die Auswertung der Variable %Nr% vorweg erlaubt, und erst danach (verzögert) wird dann zB %Verz12% durch den gespeicherten Inhalt ersetzt. Die dafür nötige Schreibweise sieht eben so aus: !Verz%Nr%! - das "!" ersetzt das äußere "%".

Ein weiterer Grund für das "enabledelayedexpansion" ist die Tatsache, dass in der "for"-Schleife eine Auswertung der Variablen nur am Anfang erfolgen würde - zB das Erhöhen der Variable %count% würde so immer nur zum Wert 1 führen (zu Beginn der Schleife war %count% 0, und bei jedem Schleifendurchlauf würde wieder dieser Wert 0 als Variableninhalt angenommen) - die "verzögerte Variablenerweiterung" bewirkt, dass Änderungen des Variableninhaltes auch innerhalb der Schleife "gesehen" werden - deshalb !count!.

Grüße
bastla
Member: ReXx3r
ReXx3r Jul 10, 2007 at 07:39:17 (UTC)
Goto Top
Hi bastla,

DANKE DANKE DANKE

mit deiner Version gehts wunderbar.
Zwei Sachen noch:
1. Wie füge ich einen letzten Menüpunkt ein, mit dem man einen neuen Kunden anlegt?
Habs schonmal probiert aber nicht richtig hinbekommen:
:Menue
echo.
echo Liste der Verzeichnisse mit "%Ziel%":  
echo.
for /l %%n in (1,1,%count%) do echo!MZeile%%n!
set /a count=%count%+1
echo!NrForm:~4!:  %count%: Neuen Kunden anlegen
echo.
echo.
set /p choice=Gib die Nummer des Kunden an (0 fr Ende):
set /a Nr=-1
set /a Nr=%choice% 2>nul
if %Nr% = %count% goto :neuerkunde
und
:neuerkunde
set /p verzeichnis = Neuen Kundennamen eingeben...:
goto istnichtda
2. Was ist der Unterschied zwischen "goto kdnr" und "goto :kdnr"?

MfG
ReXx3r
Member: ReXx3r
ReXx3r Jul 10, 2007 at 07:44:37 (UTC)
Goto Top
Bei deiner Version zeigt der mir als Nummerierung immer 0 an.

Aber die von bastla funktioniert ja jetzt face-smile

trotzdem Danke für deine Mühe
Member: bastla
bastla Jul 10, 2007 at 11:05:30 (UTC)
Goto Top
Hallo ReXx3r!

Für den besonderen Menüpunkt "Neuen Kunden anlegen" würde ich keine (immer wieder variierende) Nummer verwenden, sondern einfach den Buchstaben "N" anbieten, etwa:
:Menue
cls
echo.
echo Liste der Verzeichnisse mit "%Ziel%":  
echo.
for /l %%n in (1,1,%count%) do echo!MZeile%%n!
echo.
echo.
<b>set /p choice=Gib die Nummer des Kunden an (N fr "Neuer Kunde", 0 fr Ende):   
if /i %choice:~0,1%==N goto :NeuerKunde</b>
set /a Nr=-1
set /a Nr=%choice% 2>nul
if %Nr% equ 0 goto :Ende
...
und zB
:NeuerKunde
cls
echo.
echo Anlage neuer Kunde
echo.
echo.
set Verzeichnis=
set /p Verzeichnis=Neuen Kundennamen eingeben...:

::falls keine Eingabe
if not defined Verzeichnis goto :Fehler

set "Verzeichnis=%Zielpfad%\%Verzeichnis%"  
md "%Verzeichnis%"  
::und weiter ...
goto :Bearbeitung
Natürlich würde sich anbieten, vor dem Erstellen des Verzeichnisses den neuen Kundennamen etwas genauer zu überprüfen (bereits vorhanden, nicht zulässige Sonderzeichen, ...).

Was ist der Unterschied zwischen "goto kdnr" und "goto :kdnr"?
Bei "goto", soweit ich weiß, eigentlich keiner - sehr wohl aber bei "call" - daher habe ich mir den Doppelpunkt einfach angewöhnt ...

Grüße
bastla
Member: miniversum
miniversum Jul 10, 2007 at 11:08:36 (UTC)
Goto Top
Immer 0 ?
Aber du hast das
setlocal enabledelayedexpansion
ganz oben nicht vergessen?

miniversum
Member: ReXx3r
ReXx3r Jul 10, 2007 at 11:54:19 (UTC)
Goto Top
Natürlich habe ich das nicht vergessen, der Fehler muss also woanders liegen
Member: bastla
bastla Jul 10, 2007, updated at Jan 30, 2014 at 19:40:47 (UTC)
Goto Top
Hallo Ihr Beiden!

Nur als Anmerkung: miniversum's Variante (mit der geänderten "for"-Zeile) funktioniert bei mir, bis auf die Tatsache, dass die Variable %Ziel% für verschiedenste Zwecke verwendet werden soll (und damit etwas überfordert wird face-wink):
...
Set /P Ziel=Bitte Wählen ...:

set "shift="  
if %Ziel% gtr 1 set /a shift=%Ziel%-1
set "Ziel="  
for /F "skip=%shift% delims=" %%a in ('DIR /b /on /ad "%Zielpfad%\%<b>Ziel</b>:~0,3%*.*"') do if not defined Ziel set Ziel=%%a  
...
Wenn also für die Eingabe der Auswahl und für das gesuchte Verzeichnis andere Variablen verwendet werden, klappt's.

Grüße
bastla
Member: ReXx3r
ReXx3r Jul 10, 2007 at 13:54:38 (UTC)
Goto Top
so Danke an euch beide, vor allem bastla face-smile

Programm ist fertig und läuft

MfG
ReXx3r