Batch - Set Variable in einer FOR Schleife
Hallo.
Ich bin Anfänger und habe ein Problem in einem kleinen Sicherungsjob von Access DB.
Vielleicht könnt ihr mir helfen meine Batch zu optimieren.
Folgendes:
Ich möchte verschiedene Access Dateien auf ein ext. Laufwerk sichern und gleichzeitig komprimieren.
In einer Batch trage ich die Dateinamen und Pfade als Variable ein. Auch um die Batch klein zu halten.
Jetzt möchte ich mir für die Punkte 1, 4 und 5 (Beschreibung im Code) das Einfügen der Befehlszeilen für weitere Dateien (möglich datei001-datei999) sparen.
D.h. die Variablen "dateiNNN" und "dateiNNNp" sollten nacheinander abgearbeitet werden.
Soll heißen, nur eine Befehlszeile pro Verarbeitungs-Punkt für alle Variablen.
Verständlich genug?
Ist das möglich? Habe soetwas noch nicht gemacht.
Die For Schleife habe ich im Internet gefunden, komme aber mit den Erklärungen der Parameter nicht klar.
Hier der Code:
Wie lässt sich das optimieren?????
Vielen Dank und Gruß.
Ich bin Anfänger und habe ein Problem in einem kleinen Sicherungsjob von Access DB.
Vielleicht könnt ihr mir helfen meine Batch zu optimieren.
Folgendes:
Ich möchte verschiedene Access Dateien auf ein ext. Laufwerk sichern und gleichzeitig komprimieren.
In einer Batch trage ich die Dateinamen und Pfade als Variable ein. Auch um die Batch klein zu halten.
Jetzt möchte ich mir für die Punkte 1, 4 und 5 (Beschreibung im Code) das Einfügen der Befehlszeilen für weitere Dateien (möglich datei001-datei999) sparen.
D.h. die Variablen "dateiNNN" und "dateiNNNp" sollten nacheinander abgearbeitet werden.
Soll heißen, nur eine Befehlszeile pro Verarbeitungs-Punkt für alle Variablen.
Verständlich genug?
Ist das möglich? Habe soetwas noch nicht gemacht.
Die For Schleife habe ich im Internet gefunden, komme aber mit den Erklärungen der Parameter nicht klar.
Hier der Code:
@echo off
set access="c:\Programme\Microsoft Office\Office12\MSACCESS.EXE"
set cziel=s:\AccessDBs
rem datei000 = Zu sichernde Datei
rem datei000p = Quellpfad der Datei
set datei001=AccessDB1.mdb
set datei001p=C:\Verz1\...\
set datei002=AccessDB2.mdb
set datei002p=C:\Verz2\...\
set datei003=AccessDB3.mdb
set datei003p=C:\Verz3\...\
set datei004=AccessDB4.mdb
set datei004p=C:\Verz4\...\
echo . Verarbeitung beginnt
echo ---------------------------------------------------------------
echo .
echo . 1. Sammeln und Sichern ALLER ACCESS DBs
echo ===============================================================
copy %datei001p%%datei001% %CZIEL%\
copy %datei002p%%datei002% %CZIEL%\
copy %datei003p%%datei003% %CZIEL%\
copy %datei004p%%datei004% %CZIEL%\
echo . 2. Gesicherte Access DBs komprimieren
echo ===============================================================
FOR %%a IN ("%CZIEL%\*.mdb") DO %ACCESS% %%a /compact
echo . 3. Access2007 Sicherheitswarunung unterdruecken (Prog. reg.exe)
echo ===============================================================
reg add "HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Access\Security" /v VBAWarnings /t REG_DWORD /d 1 /f
echo . 4. Registry Pfad anlegen (Prog. AddPath1.1), damit Access Runtime arbeiten kann (Prog. BoxWech2 erledigt den OK Klick)
echo Voraussetzung fuer Punkt 5
echo =======================================================================================================
addpath /Path %datei001p%
addpath /Path %datei002p%
addpath /Path %datei003p%
addpath /Path %datei004p%
echo . 5. Access DB im Quelllaufwerk komprimieren (statt "Rueck"copy)
echo ===============================================================
%access% %datei001p%%datei001% /compact
%access% %datei002p%%datei002% /compact
%access% %datei003p%%datei003% /compact
%access% %datei004p%%datei004% /compact
pause
Wie lässt sich das optimieren?????
Vielen Dank und Gruß.
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Kommentar vom Moderator Biber am 25.05.2011 um 19:49:38 Uhr
Respekt. Der erste Beitrag eines neuen Mitglieds und Batch-Anfängers - super.
Herzlichst willkommen im Forum.
Herzlichst willkommen im Forum.
Content-ID: 166906
Url: https://administrator.de/forum/batch-set-variable-in-einer-for-schleife-166906.html
Ausgedruckt am: 22.04.2025 um 01:04 Uhr
18 Kommentare
Neuester Kommentar
Hallo Lox0805 und willkommen im Forum!
Wirf doch mal einen Blick in die "Nachbarschaft" ...
Grüße
bastla
Wirf doch mal einen Blick in die "Nachbarschaft" ...
Grüße
bastla

moin und willkommen,
Gruß
Edit
In deinem Script fängst du ab 30 - genauer Zeile 32 mit dem comprimieren an.
Erst an Zeile 35 ff. klemmst du die Warnungen ab.
Und dann nochmal ab 50.
Access "Scripten" ist schon komplex genug - mach es dir nicht so kompiziert.
/Edit
- wieso nimmst du diesen Counter?
- Nimm eine Steuerdatei für die Dateien und packe die nicht in die batch rein.
for /f %%a in (laufwerk:\pfad\dateiliste.txt) do call :processlines %%a
- Dann mußt du vorher sicherstellen, dass es keine ldb zur Mdb gibt, bzw. sicherstellen, dass die mdb nicht geöffnet ist.
- ein reines compact - damit habe ich meine besten Erfahrungen gesammelt - pack ein repair dazu - besser ist das
- dann auch diese Batch am sinnvollsten auf dem Fileserver laufen lassen - Daten oder Netzwerkfehler kommt ganz gerne bei sowas und da braucht man es nicht wirklich.
- deinen Schritt 5 kann ich nicht nachvollziehen - warum zweimal comprimieren, statt einmal und dann die Dateigröße vergleichen und bei nicht identischer Dateigröße zurück zum Server kopieren?
Gruß
Edit
In deinem Script fängst du ab 30 - genauer Zeile 32 mit dem comprimieren an.
Erst an Zeile 35 ff. klemmst du die Warnungen ab.
Und dann nochmal ab 50.
Access "Scripten" ist schon komplex genug - mach es dir nicht so kompiziert.
/Edit

Salü,
jetzt machst du mal 3 Sachen...
in dem Zustand ungetesteter schnippsel - der ähnlich bei mir läuft
Gruß
jetzt machst du mal 3 Sachen...
- Tief luft holen
- den Grünen haken wieder weg
- und nochmal von vorne das ganze.
- zu "theoretisch" nicht offen - falls eine DB eine eingebundene Tabelle einer anderen DB hat - ist die andere auch offen - obwohl es keine LDB dazu gibt.
in dem Zustand ungetesteter schnippsel - der ähnlich bei mir läuft
:parameter
set access="c:\Programme\Microsoft Office\Office12\MSACCESS.EXE"
set "cred= /user username /pwd password"
set cziel=s:\AccessDBs
:schleife
rem in die Klammern die DBs reinmalen
for %%a in (C:\Verz1\.1.mdb\;C:\Verz2\2.mdb;C:\Verz3\3.mdb) do call :bastla %~dpna
goto eof
:bastla
echo . Sammeln und Sichern ALLER AKTIVEN ACCESS DBs - die teoretisch nicht offen sind.
if exist %1.ldb echo Datei %1 offen>>errorlog.txt
if not exist %1.ldb (
echo ob oder ob nicht - jedesmal der Pfad neu gesetzt werden muß und du das ganze towuhabu überhaupt brauchst - entscheidest du - ich brauch das nicht.
%access% %1.mdb %cred% /repair
%access% %1.mdb %cred% /compact
copy %1 %cziel%\
)
eof
Gruß

Salü
Gruß
- nein - ich habe versucht - zwischen Tür und Angel aus deinem verschiedenen Ansätzen und meinem Script etwas zu zaubern - das aus einem Guss ist.
- Wie geschrieben - jeder hat seine Ideen und sieht seine Probleme, die ein anderer Weg hätte....
- ich gebe den originalen dateien auf dem Share z.B eine andere Suffix und kopiere eine wartedummy mdb dahin, damit ich sicher sein kann - das während des Jobs keiner drankommt.
- in einem anderen Script - das auf einer anderen Kiste läuft - prüfe ich, ob nach 3 Stunden alle Dateien wieder "echt" sind - also wieder gegen die wartedummy ausgetauscht wurden - sind Sie das nicht - kicke ich das "erste" Script, Access - hole die umgesuffixten mdbs wieder zurück und schick mir ne Mail.
- dann schreibt ja keiner, dass du es haaaaaargenauso machen mußt - da da geht auch...
for %%a in (
c:\script\
%windir%
c:\
) do echo %%a
pause
C:\>C:\script\test\forbeispiel.cmd
C:\>for %a in (c:\script\ C:\WINDOWS c:\) do echo %a
C:\>echo c:\script\
c:\script\
C:\>echo C:\WINDOWS
C:\WINDOWS
C:\>echo c:\
c:\
C:\>pause
Drücken Sie eine beliebige Taste . . .
- Dann und das ist Geschmackssache - ich mag es nicht, wegen einer neuen Datei oder einer, die nicht mehr abgearbeitet werden soll, das Script anzufassen und so dessen Dateidatum zu verändern.
- Läuft bei mir aus irgendeinem Grund etwas nicht mehr und ich sehe - die cmd wurde verändert - hab ich erstmal ein Problem - oder besser eine falsche Fährte, wenns doch was anderes war.
Gruß

Zitat von @Lox0805:
Hallo.
Ich hab jetzt folgendes probiert, und scheitere daran, dass irgend etwas an Deinem ungetestetem Script nicht stimmt...
Die forbeispiel.cmd funktioniert bei mir auch, jedoch wenn ich im eigentlichen Script "%~dpna" hinzufüge geht die
Dos Box auf und wieder schnell zu.
Da helfen auch keine Pausen... ich seh nix.
Außerdem habe ich versucht den Code zu erweitern.
Da ich immernoch den Dateipfad UND den Dateinamen als Variable brauche habe im Internet geschaut und etwas gefunden.
Hierbei soll der Pfad angeblich vom Dateinamen getrennt werden. :wunschdenk:
Nur weiß ich nicht, ob ich es richtig anwende.
Was sagst Du dazu????
Zwischen Tür und Angel und irgenwie schon wieder ungetestet und leicht krumm...Hallo.
Ich hab jetzt folgendes probiert, und scheitere daran, dass irgend etwas an Deinem ungetestetem Script nicht stimmt...
Die forbeispiel.cmd funktioniert bei mir auch, jedoch wenn ich im eigentlichen Script "%~dpna" hinzufüge geht die
Dos Box auf und wieder schnell zu.
Da helfen auch keine Pausen... ich seh nix.
Außerdem habe ich versucht den Code zu erweitern.
Da ich immernoch den Dateipfad UND den Dateinamen als Variable brauche habe im Internet geschaut und etwas gefunden.
Hierbei soll der Pfad angeblich vom Dateinamen getrennt werden. :wunschdenk:
Nur weiß ich nicht, ob ich es richtig anwende.
rem ungetstete Script immer ohne @echo off
:parameter
set access="c:\Programme\Microsoft Office\Office12\MSACCESS.EXE"
set cziel=s:\AccessDBs
:schleife
for %%a in (
c:\Verz1\Access_DB1.mdb
c:\Verz2\Access_DB2.mdb
) do call :bastla %~dpna %~dpa %~nxa
goto eof
:bastla
if exist %1.ldb echo Datei %1 offen >>%cziel%\errorlog.txt
if not exist %1.ldb (
set sPATH=%2
set sFILE=%3
set Path=%sPath:"=%
set File=%sFile:"=%
echo %access% %1.mdb /repair
echo %access% %1.mdb /compact
echo copy %1 %cziel%\
copy %Path%\%File% %cziel%\
)
eof
pause
>
Was sagst Du dazu????
Aus dem bauch heraus...
Starte eine Dosbox und dort wirfst du die Batch rein - nicht per doppleklickeritis starten - dann siehst du auch - wo er kleben bleibt...
Gruß
edit @Friemler
@ TO:
Der einzige Punkt, wo du %Path%\%File% benutzt ist doch copy %Path%\%File% %cziel%\
Das ist doch bereits %1
Hallo Lox0805,
beim Batchscript debuggen
Daten, die sich irgendwann mal ändern könnten (z.B. die Pfade zu den MDB's) am Anfang des Scripts in eine Variable schreiben (sozusagen einen Konfigurationsblock). In den Kopf der
Sowas wie
lässt sich zu
zusammenfassen, ließt sich besser.
Ist unnötig. Evtl. vorhandene Anführungszeichen wurden schon von den
Gruß
Friemler
beim Batchscript debuggen
@echo off
raus- Script aus einem Konsolenfenster starten
Daten, die sich irgendwann mal ändern könnten (z.B. die Pfade zu den MDB's) am Anfang des Scripts in eine Variable schreiben (sozusagen einen Konfigurationsblock). In den Kopf der
FOR
-Schleife kommt dann die Variable. Erspart später unnötige Sucherei im Quellcode.Sowas wie
sFILE=%%~ni%%~xi
sFILE=%%~nxi
set Path=%sPath:"=%
set File=%sFile:"=%
SET
-Befehlen in den beiden FOR
-Schleifen davor entfernt.Gruß
Friemler
@t-mo & Friemler: Amen. 
Da im Unterprogramm ja (derzeit) de facto nur eine Aktion erfolgt, wenn keine ".ldb" existiert, würde ich das eher so anlegen
oder ganz auf das (@T-Mo: originell benannte
) Unterprogramm verzichten ...
Grüße
bastla
Da im Unterprogramm ja (derzeit) de facto nur eine Aktion erfolgt, wenn keine ".ldb" existiert, würde ich das eher so anlegen
@echo on & setlocal
:parameter
set access="c:\Programme\Microsoft Office\Office12\MSACCESS.EXE"
set cziel=s:\AccessDBs
for %%a in (
c:\Verz1\Access_DB1.mdb
c:\Verz2\Access_DB2.mdb
) do if exist "%%~dpna.ldb" (
echo Datei %%a offen >>%cziel%\errorlog.txt
) else (
call :bastla "%%a"
)
pause
goto :eof
:bastla
rem %access% %1 /repair
rem %access% %1 /compact
copy %1 %cziel%\
goto :eof
Grüße
bastla
@Lox0805
BTW: Da Du das ganze in einer Klammer abgehandelt hast, wäre auch noch "delayedExpansion" für die Verwendung der Variablen erforderlich ...
Grüße
bastla
ist ungültig: %~dpna
Ist ja auch ein Batch - daher: %%~dpnaNein, die brauche den Pfad UND Pfad mit Dateiname.... einmal für die Runtime (die erwartet einen in der Registry den Pfad ohne Dateinamen) und dann für die anderen Jobs.
... aber wozu in eigenen Variablen?BTW: Da Du das ganze in einer Klammer abgehandelt hast, wäre auch noch "delayedExpansion" für die Verwendung der Variablen erforderlich ...
Grüße
bastla
Hallo Lox0805,
das bezog sich auf die Zeilen 23-27 in Deinem letzten Code-Posting.
ist eine Ersetzung von allen
Außerdem überschreibst Du damit die interne
Da diese Zuweisungen in einem geklammerten Befehlsblock stehen, der ausgeführt wird, wenn
wahr ist, und Du die veränderten Variableninhalte im selben Block verwenden willst, müsstest Du, wie bastla schon bemerkte, dafür die verzögerte Variablenerweiterung aktivieren und benutzen. Wenn Dir der Begriff nichts sagt, bitte mal danach googeln.
Gruß
Friemler
das bezog sich auf die Zeilen 23-27 in Deinem letzten Code-Posting.
set Path=%sPath:"=%
"
durch nichts.Außerdem überschreibst Du damit die interne
PATH
-Variable von CMD, verwende besser einen anderen Namen.Da diese Zuweisungen in einem geklammerten Befehlsblock stehen, der ausgeführt wird, wenn
if not exist %1.ldb
Gruß
Friemler
Hallo Lox0805!
Zum Thema "delayedExpansion" findest Du im Forum jede Menge - nicht zuletzt auch in Friemlers Tutorial zur FOR-Schleife ...
Grüße
bastla
? Ich brauche Pfad UND Pfad mit Dateiname .
Das habe ich ja auch nicht bezweifelt - nur, dass Du dafür eigene Variablen benötigen würdest, sehe ich eigentlich nicht::bastla
echo Machwas mit "%~dp1"
echo und jetzt mit "%~nx1"
rem %access% %1 /repair
rem %access% %1 /compact
copy %1 %cziel%\
goto :eof
Grüße
bastla