texmex
Goto Top

Textfelder innerhalb einer Batch mit User-Angaben aktualisieren

Hallo!

Ich habe eine Batch-Datei erstellt, die dem User die Möglichkeit gibt, einen bestimmte Nummer aus einer Liste zu wählen. Doch diese Nummern müssten auch aktualisiert werden und genau da liegt das Problem...

Das Problem bei der ganzen Geschichte ist, dass diese Update-Funktion auf Variablen aufbaut und die Lösungsansätze, die ich in diesem Forum und auch via Google gefunden habe, funktionieren leider nicht bei mir...

Ich habe mir einen kleinen Druckassistenten gebastelt (in diesem Fall alpha.bat) und möchte via update.bat diese bearbeiten. Dabei soll der User selber aussuchen, welcher Auftrag aktualisiert werden soll und wie der neue Name dann lauten soll.

set "Datei=alpha.bat"  
set /p from="Welcher Auftrag soll ersetzt werden? Bitte eingeben:"  
set /p to="Welcher Auftrag soll dafuer eingesetzt werden? Bitte eingeben:"  
set "t=%temp%\text.tmp"  
if exist "%t%" del "%t%"  
for /f "usebackq delims=" %%i in ("%Datei%") do set "Line=%%i" & set Line=!Line:%from%=%to%! & echo !Line!>>"%t%"  
move /y "%t%" "%Datei%"  
echo Schritt 1/3 erledigt!
pause > nul

if %from% GEQ 81234567 set from01="Glas Wasser"&goto step2  
echo Es ist ein Fehler aufgetreten!
goto ende

:step2
echo Jetzt muss der Name eingegeben werden:
set "Datei=alpha.bat"  
echo Alter Auftragsname: %from01%
set /p to01="Neuer Auftragsname:"  
set "t=%temp%\text.tmp"  
if exist "%t%" del "%t%"  
for /f "usebackq delims=" %%i in ("%Datei%") do set "Line=%%i" & set Line=!Line:%from01%=%to%! & echo !Line!>>"%t%"  
move /y "%t%" "%Datei%"  

Dieser Code basiert auf einem Vorschlag von bastla, aber so will es nicht funktionieren, denn ich habe zuerst Fehlermeldungen bekommen, dass der bei %to% eingesetzte Wert nicht syntaktisch ausgelesen werden kann. Außerdem wird dann der gesamte Inhalt der alpha.bat gelöscht und stattdessen steht dort nur noch:

!Line!
!Line!
!Line!
usw....

Bei den eingesetzten Werten (also bei from/to) handelt es sich jeweils um rein numerische Werte (in diesem Fall 81234567), ich würde das Ganze aber dann auch nochmal gerne mit kurzen Begriffen (Bsp: Glas Wasser) nutzen können. Leider lässt sich das schlecht kombinieren, ich muss leider für jeden vorhandenen Auftrag eine if-Abfrage erstellen und dann via GEQ mit den vorhandenen Nummern vergleichen... Ist bei 20 Varianten etwas blöd, aber das sollte ja eigentlich funktionieren.

Es müsste doch eine allgemeine Lösung geben, bei der statt einem Haufen Datenmüll nur die entsprechende Stelle ausgewechselt wird, oder? Den Quelltext habe ich schließlich richtig kopiert und eingesetzt...

Content-Key: 169686

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

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

Member: Friemler
Friemler Jul 13, 2011 at 16:03:44 (UTC)
Goto Top
Hallo TexMex,

dass Dein Script nur Datenmüll ausspuckt liegt daran, dass Du den Befehl SetLocal EnableDelayedExpansion nicht in die erste Scriptzeile geschrieben hast. Wenn Du jetzt nicht weißt, was das ist, befrage Google zum Thema "verzögerte variablenerweiterung".

Ich würde das aber anders lösen. Statt die alpha.bat für jeden Begriff neu zu schreiben, würde ich den Begriff beim Aufruf als Parameter übergeben, z.B. so:
call alpha.bat "Glas Wasser"
Innerhalb von alpha.bat kannst du dann über die Parametervariable %1 auf den übergebenen Begriff zugreifen.

Da der Begriff hier ein Leerzeichen enthält, muss er in der Aufrufzeile in Anführungszeichen eingeschlossen werden. Um die innerhalb von alpha.bat wieder loszuwerden, musst Du den Ausdruck %~1 verwenden. Die Tilde entfernt die Anführungszeichen.

Da damit Deine Fragen aber sicherlich noch nicht beantwortet sind, ich aber auch Dein genaues Problem mit "Zahlen auswählen bzw. aktualisieren" nicht verstanden habe (dürfte bei der Beschreibung aber anderen auch so gehen face-wink ), wäre es am besten wenn Du zumindest nochmal Den Inhalt der alpha.bat postest und besser erklärst, was Du eigentlich erreichen willst.

Gruß
Friemler
Member: TexMex
TexMex Jul 13, 2011 at 20:54:59 (UTC)
Goto Top
Alles klar, Friemler. face-smile

Ich erkläre gerne den genauen Aufbau meiner Batch-Datei, werde aber auch nochmal morgen deinen Tipp mit "EnableDelayedExpansion" aufgreifen. Hatte daran nämlich gar nicht gedacht, weil ich diese Zeile bei einer weiteren Update-Anwendung (die aber andere Fehler aufweist und von daher ohnehin nicht relevant ist) eingebaut hatte.

Also, allgemein gibt es zwei Batch-Dateien, mit denen ich arbeite (bzw. arbeiten möchte):

In diesem Fall nennen wir sie:
auftrag.bat (statt wie oben alpha.bat)
update.bat (aus der der oben gezeigte Ausschnitt stammt)

auftrag.bat:
---
Mit der Datei "auftrag.bat" habe ich eine allgemeine Menü-Oberfläche, bei der der Benutzer aus verschiedenen Aufträgen den gewünschten raussucht. Das läuft über eine simple choice-Abfrage ab und erstellt dabei noch eine entsprechende Variable.
Ich nehme hier einfach wieder als Beispiel die Auftragsnummer 81234567, hinter welcher der Auftrag "Glas Wasser" steckt. Es gibt dann noch weitere Auftrage (81235678 Glas Cola; 81236789 Glas Limo)

In der Batch sieht das wie folgt aus:
set prod=8123
echo Auftrag waehlen
echo ----
echo.
echo [1] 81234567 Glas Wasser
echo.
echo [2] 81235678 Glas Cola
echo.
echo [3] 81236789 Glas Limo

choice /c:123 /n

if errorlevel 1 set print=4567 & goto pref
if errorlevel 2 set print=5678 & goto pref
if errorlevel 3 set print=6789 & goto pref

Die Variablen %prod% und %print% sind dazu da, dass ich auch andere Aufträge (z.B. 80001234) aus diesem Schema zusammensetzen kann. Für die oben erwähnte Auftragsgruppe (8123xxxx) erscheint diese Zweiteilung sinnlos, aber im Gesamtbild ergibt sie durchaus Sinn. Dieser Teil des Scripts funktioniert auch tadellos, tut hier also eigentlich nichts zur Sache, ich erwähne sie an dieser Stelle nur zur Erklärung.

So...

Jetzt möchte ich mit Hilfe der "update.bat" die Informationen in der "druck.bat" verändern bzw. aktualisieren.

Zum Beispiel soll dann aus der "81234567" und dem dazugehörigen "Glas Wasser" zum Beispiel "80001234" mit dem Namen "Tasse Tee" werden. Diese Änderung soll dann dauerhaft so hinterlegt werden, deswegen möchte ich eigenltich nicht auf den "call"-Befehl zurückgreifen, da er mir doch nur einen temporären Nutzen bringen würde.

Ich hatte es auch schon im Prinzip soweit eingetellt, dass man lediglich die entsprechende Nummer (also 81234567) eintippen konnte (ich habe für unsichere User auch die Möglichkeit eingebaut, dass sie aus einem Menü den entsprechenden Eintrag raussuchen konnten - wieder mit if-Anfrage, aber am Ende steht das selbe Ergebnis), das Script den Namen (also in diesem Fall "Glas Wasser") via if-Abfrage raussucht, anzeigt und dann wiederum die Möglichkeit zur Änderung bietet.

Aber wie bereits erwähnt wird bei mir trotz der Abfrage, welcher Auftrag geändert werden soll und auch die Eingabe und Erkennung funktioniert, einfach der gesamte Inhalt aus "druck.bat" gelöscht und dafür wird dann "!Line!" eingesetzt...

Ich hoffe, ich konnte jetzt erklären, wo das Problem liegt und was ich mit dieser Batch-Datei eigentlich erreichen möchte. Mir ist durchaus bewusst, dass diese ganzen Bezeichnungen und Nummern für Außenstehende kryptisch wirken. Aber ich kann garantieren, dass ich das Ganze noch erheblich erleichtert habe, da die tatsächlichen Artikelnummern und -bezeichnungen um einiges undurchsichtiger sind. face-wink
Member: Friemler
Friemler Jul 13, 2011 at 22:17:23 (UTC)
Goto Top
Hallo TexMex,

also dass der Ausschnitt aus der Auftrag.bat/Druck.bat (was denn nun? face-wink ) fehlerfrei funktioniert, kann ich noch nicht glauben. Die Abfrage if errorlevel 1 ist für alle Werte von ERRORLEVEL größer oder gleich 1 wahr. Die Abfragen für die Werte 2 und 3 werden nie ausgeführt.

Entweder Du schreibst if %errorlevel% equ 1 usw. oder Du drehst die Reihenfolge der drei Abfragen um und fängst mit if errorlevel 3 an, dann geht's auch.

So, und jetzt zu Deinem Vorhaben, mit einem Batchscript Wörter in einem anderen Batchscript auszutauschen und die Datei neu zu schreiben: Vergiss es face-sad

Beweis:
  1. Speichere den Code aus Deinem Eröffnungsposting als InFile.bat
  2. Speichere das folgende Script im selben Verzeichnis und starte es.
@echo off

setlocal enabledelayedexpansion

set "from=Datei"  
set "to=File"  
set "t=OutFile.bat"  

for /f "usebackq delims=" %%i in ("InFile.bat") do (  
  set "Line=%%i"  
  set "Line=!Line:%from%=%to%!"  
  >>"%t%" echo !Line!  
)

Es wird dadurch als Ausgabe eine Datei OutFile.bat erzeugt. Schau Dir in dieser Datei mal Zeile 6 und Zeile 20 genau an... - Datenmüll!

Das Problem mit Batchscript und dem verarbeiten von Dateien mit beliebigem Inhalt ist, dass Batchscript so einige Zeichen als Steuerzeichen interpretiert, wenn sie mit ECHO ausgegeben oder von Stringersetzungsausdrücken (Zeile 11 meines Scripts) verarbeitet werden.

Alternativen:
  1. VBScript lernen und eine Update.vbs schreiben.
  2. Eine Datei verwenden, die die Einträge für das Auswahlmenü enthält und nur diese mit der Update.bat bearbeiten. Die Auftrag.bat/Druck.bat ließt die anzuzeigenden Menüeinträge aus dieser Datei. Die Menüeinträge sollten am besten nur aus Buchstaben und Zahlen bestehen.

Das könnte so gehen:

  • Die Datei mit den Menüeinträgen (als Menu.txt speichern):
81234567:Glas Wasser
81235678:Glas Cola
81236789:Glas Limo

  • Die Auftrag.bat/Druck.bat:
@echo off & setlocal


set "MenuFile=Menu.txt"  


::Menü anzeigen
:InputLoop
cls
echo Auftrag wählen
echo ----
echo.

set /a Cntr=0

::Die Menüdatei einlesen und die enthaltenen Einträge darstellen
for /f "tokens=1,2* delims=:" %%a in ('findstr /n "^" "%MenuFile%"') do (  
  echo [%%a]  %%b %%c
  echo.
  set /a Cntr+=1
)

echo [E]  Ende
echo.

set "Item="  

::Benutzereingabe einlesen
set /p "Item="  

::E für Ende gedrückt? -> Beenden
if /i "%Item%" equ "E" exit /b  

::Wenn die Eingabe etwas anderes als Zahlen enthält, wiederholen
for /f "delims=0123456789" %%n in ("%Item%") do goto :InputLoop  

::Führende Nullen entfernen, sonst wird die Zahl als Oktalzahl aufgefasst
for /f "tokens=* delims=0" %%n in ("%Item%") do set "Item=%%n"  

::In Zahl konvertieren
set /a Item=Item

::Bei 0, nur ENTER gedrückt oder zu großen Zahlen, wiederholen
if %Item% lss 1 goto :InputLoop
if %Item% gtr %Cntr% goto :InputLoop

::Aus der Eingabe die Produktnummer aus der Menüdatei ermitteln
for /f "tokens=1,2 delims=:" %%a in ('findstr /n "^" "%MenuFile%"') do (  
  if %%a equ %Item% set "Prod=%%b"  
)

::Ab hier kann mit der Produktnummer gearbeitet werden
echo %Prod%
::
::Mach' was  
::
::Ende
exit /b

Damit kann die Menu.txt beliebig viele Einträge enthalten und die Variable Prod enthält gleich die vollständige Produktnummer. Allerdings muss jetzt bei der Eingabe ENTER gedrückt werden.

Wenn Du Dich fragst:
  • Warum setzt dieser Typ die Zuweisungen mit SET in Anführungszeichen? - So kann es nie passieren, das sich aus versehen ein Leerzeichen an den zuzuweisenden Wert anhängt; hat manche schon zur Verzweiflung gebracht.
  • Warum macht er das bei set /a Cntr=0 nicht? - Das ist wegen /a eine arithmetische Zuweisung (mit einem numerischen Wert). In diesem Fall würden versehentlich angehängte Leerzeichen ignoriert.

Übrigens: Du weißt schon, dass CHOICE unter XP nicht verfügbar ist?


Gruß
Friemler
Member: TexMex
TexMex Jul 14, 2011 at 14:58:59 (UTC)
Goto Top
Hey Friemler,

Stimmt, die choice-Abfrage, die ich dort oben gepostet habe, würde so nicht funktionieren. Da habe ich nicht genau hingeschaut und eine Abfrage aus einer alten (aber inhaltsgleichen) Sicherungskopie veröffentlicht...

Danke für deine umfangreiche Hilfe, leider funktioniert der zweite Teil deiner "Druck.bat" nicht so, wie gewollt. Ich habe dafür aber den ersten Teil in mein kleines Programm integriert, das macht den Quelltext erheblich übersichtlicher und ich konnte dadurch ja die ganzen Angaben in einer externen Datei speichern, auf die dann auch eine weitere Batch-Datei zugreifen kann.

Ich habe es jetzt etwas komplizierter, aber durchaus machbar gelöst. Die menu.txt ist ja relativ simpel aufgebaut, dementsprechend habe ich einfach eine Verknüpfung in die Batch-Datei integriert, damit der User selbst die Änderungen vornehmen kann. Ist nicht ganz optimal, aber immerhin funktioniert es.

Dass Choice unter XP nicht verfügbar ist, stellt kein Problem dar, da ich das Ganze eh nur auf Windows7-Rechnern laufen lasse.
Member: Friemler
Friemler Jul 14, 2011 at 15:24:57 (UTC)
Goto Top
Hallo TexMex,

Zitat von @TexMex:
leider funktioniert der zweite Teil deiner "Druck.bat" nicht so, wie gewollt.

was meinst Du damit genau? Die Prüfungen zum abfangen von ungültigen Eingaben oder das auslesen der Produktnummer aus der Menü-Datei?

Gruß
Friemler
Member: TexMex
TexMex Jul 19, 2011 at 08:08:49 (UTC)
Goto Top
Bei mir hat er eine Fehlermeldung angezeigt.

Aber ich konnte das Problem inzwischen lösen. Ich hatte lediglich deinen Programm-Code falsch integriert und wollte ihn mit einer anderen Schleife kombinieren. Das konnte natürlich nicht funktionieren.

Jetzt funktioniert alles! face-smile

Danke für die ganze Hilfe. face-wink