phino-edv
Goto Top

Textdateien automatisiert umschreiben bzw. umformatieren

Hallo zusammen,
ich habe mal wieder ein für mich unlösbares Problem:

Ich erhalte aus einer Warenwirtschaft eine Datei, die für die Kassenpogrammierung bestimmt ist. Die Daten sind in einer Textdatei enthalten, die im Edior wie folgt aussieht:

101,9980015,(12),'NAT.BERNST.KÄSTCH.'
101,9980015,(12:2),'99800154'
101,9980015,(14),
101,9980015,(13),253.00
101,9980015,(13:4),149.00
101,9980015,(422),0
101,9980015,(425),0
101,9980015,(451),0
101,9980015,(16),1
101,9980015,(470),0

Zur Erklärung: 101 ist das Steuerzeichen für die Artikelnummer, (12) ist das Zeichen für die Bezeichnung und (13) leitet den Preis ein.
Dieses sind die Daten nur einem einzigen Artikel. Insgesamt sind es ca. 6.500, d.h. 65.000 Zeilen. Hier sind nun diverse Informationen enthalten, die einerseits nicht benötigt werden, andererseits auch nicht verarbeitet werden können.
Benötigt werden nur die Zeilen 1 und 4.
Weiterhin stimmen die Steuerzeichen nicht. Auch diese müssen geändert werden.

Herauskommen muss folgendes Format:

Die Zeile

100,0,1,1;10,1;24,A

muss in der ausgegebenen Datei in der ersten Zeile stehen (einmalig, nicht vor jedem Artikel). Erst dann folgen die Artikelzeilen:


101,9980015,1,"NAT.BERNST.KÄSTCH.";2,01;3,253

Steuerzeichen hier: 101 - Artikelnumer,
1 - Bezeichnung
2,01 - taucht in jeder Zeile auf und muss nich geändert werden
3 - Preis

Probleme:
Die Artikelnummern können in der Länge zwischen 4 und 7 Stellen variieren, die Bezeichnung kann eine beliebige Länge haben.

Diese Aufgabe müsste eigentlich durch Suchen und Ersetzen zu lösen sein, da sie aber täglich ausgeführt wird (aber nicht immer in diesem Umfang, es können auch mal nur 50 Artikel sein Das Format bleibt immer gleich) sollte die Umwandlung automatisiert sein. Ich suche also nach einem Tool, das ich in eine Batchdatei einbinden kann und das dann automatisch die Umwandlung in einer Datei abspeichert. Auch eine reine Batch-Datei zum Umwandeln würde mir weiterhelfen.


Hier ein Beispiel für eine fertige Export-Datei:

100,0,1,1;10,1;24,A
101,0100000,1,"";2,01;3,1
101,0100007,1,"NAT. BERNST. ANH. D-OESE";2,01;3,7
101,0100009,1,"NAT. BERNST. ANH.";2,01;3,9
101,0100011,1,"NAT. BERNST. ANH.";2,01;3,11
101,0100013,1,"NAT. BERNST. ANH.";2,01;3,13
101,0100015,1,"NAT. BERNST. ANH.";2,01;3,15
101,0100017,1,"NAT. BERNST. ANH.";2,01;3,17
101,0100019,1,"NAT. BERNST. ANH.";2,01;3,19


Leider kenne ich mich in Sachen Programmierung oder Batch-Erstellung überhaupt nicht aus.
Ich bin für jede Hilfe dankbar, die Ihr mir geben könnt.

LG
Philipp

Content-Key: 85018

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

Ausgedruckt am: 28.03.2024 um 11:03 Uhr

Mitglied: Biber
Biber 08.04.2008 um 22:14:35 Uhr
Goto Top
Moin phino-edv,

danke, dass Du mit so viel Sorgfalt das Problem beschrieben hast.

Dennoch sind mir zwei bis drei Detail unklar bzw. unlogisch.
  • im Output trennst Du die "Elemente" mal mit ";" und mal mit ",". Tippfehler?
  • der Preis (Beispiel 253.00) wird im Output ganzzahlig rausgedrückt (253). Tippfehler?
  • wenn letzteres kein Tippfehler: Runden oder Abschneiden? Is' ja auch bares Geld
  • weiteres Detail: ist es denn weiter automatisierbar? Automatisch bestimmte Dateinamen rein, andere raus.... per Taskplaner o.ä. jeden Tag nachmittags um 21h oder so?

Okay, die erste schnelle Skizze als Batch (obwohl ich es eher als Oneliner vom CMD-Prompt abfeuern würde):
::-------snipp phino.cmd
@echo off & if "%~1"=="" (echo Syntax: %0 Indatei [^>Outdatei]) && goto :eof  
if not exist "%~1" (echo Inputdatei "%~1" nicht gefunden!) && goto :eof  
echo 100,0,1,1;10,1;24,A
for /f "delims=,' tokens=1-4" %%a in ('findstr "(12) (13)" "%~1"') do (  
    If "%%c"=="(12)" @echo\|set /p=%%a,%%b,1,"%%d",2,01,  
    If "%%c"=="(13)" @for /f "delims=." %%i in ("%%d") do echo %%i  
)

Der wird so aufgerufen (erstmal VOM CMD-PROMPT!)
>e:\schnipsel\phino PhinoIn.txt
100,0,1,1;10,1;24,A
101,9980015,1,"NAT.BERNST.KÄSTCH.",2,01,253  
101,9980015,1,"NAT.BERNST.KÄSTCH.",2,01,253  
101,9980015,1,"NAT.BERNST.KÄSTCH.",2,01,253  
..und liefert abgebildetes Ergebnis.
Als Inputdatei PhinoIn.txt habe ich dreimal dieselben 10 Zeilen untereinanderkopiert.

Später mal soll das Ergebnis umgeleitet werden in eine Outputdatei, erstmal reicht der Bildschirm.

Grüße
Biber
Mitglied: phino-edv
phino-edv 09.04.2008 um 01:56:42 Uhr
Goto Top
Hi Biber,
cool, das Problem scheint ja lösbar zu seinface-smile Auch wenn ich in dem Quelltext kein Wort verstehe...

Zu den offenen Fragen:
Es sind keine Tippfehler - keine Ahnung, warum das so aufgebaut ist, aber die Enddatei enthält tatsächlich sowohl ";" als auch "," als Trennzeichen. Es könnte wohl sein, dass man das ändern könnte, aber in dieser Form weis ich, dass es funktioniert.

Die Preise müssen nicht gerundet werden, da es keine Artikel mit Centbeträgen gibt, es sind immer ganze Euro.

Ich erzähl dann auch noch kurz etwas zur Geschichte dieses Problems:
Ich habe einen Kunden, der von der Sage KHK ClassicLine 2000 auf AFS SQL-Manager 8 mit Vectron-Modul umgestiegen ist. Dieses Vectron-Modul erzeugt die Ausgangsdatei. Als erstes einen kompletten Stand, sobald der einmal erstellt ist, werden nur noch neu angelegte Artikel übergeben (Jeweils in einer neuen Datei, dazu gleich mehr). Diese Datei landet auf dem Server in einem einstellbaren Ordner.

Nun gibt es auch noch den "Kassen-PC", auf dem der Vectron-Commander (in Version 2.xx - ein DOS-Programm, ca. 10 Jahre alt - kein Support mehr) installiert ist. Auf diesem PC wird manuell eine Batch-Datei ausgeführt, die die Datei vom Server (Netzlaufwerk) in den Ordner c:\cm kopiert und in "kas001.imp" umbenannt.
Sobald nun der Vectron Commander gestartet wird, liest er diese Datei automatisch ein und versendet Sie nachts per 56k Modem an die Kassen. Dabei wird die Import-Datei gelöscht und in die interne Datenbank des Vectron geschrieben. Aus diesem Grund wird immer eine neue Datei erstellt, wenn die Artikeldaten exportiert werden.

Bisher wurde die Exportdatei durch die ClassicLine erstellt und hatte das Format, das ich nun gerne wieder erreichen möchte. Leider gibt es in der AFS keine Möglichkeit, die Datei anzupassen, daher mein Problem. Die Datei muss nun also auf dem Weg vom Server auf den Kassen-PC umgewandelt werden, damit der Vectron-Commander seine gewohnte Struktur wiederfindet.

So, und nun ab zu Bett. Aber vielen Dank schonmal, ich kann heute Nacht sehr viel beruhigter schlafenface-smile

LG
Philipp
Mitglied: Biber
Biber 09.04.2008 um 08:24:47 Uhr
Goto Top
Moin phino-edv,

Auch wenn ich in dem Quelltext kein Wort verstehe...
sorry, dass ich Dir gestern so unkommentiert irgendwelchen kryptischen Code vor die Füße geworfen habe... ein bisschen kann ich noch Licht ins Dunkle bringen.

::-------snipp phino.cmd
@echo off & if "%~1"=="" (echo Syntax: %0 Indatei [^>Outdatei]) && goto :eof
Bringt Hinweis "Syntax phino Indatei [>Outdatei]", falls ohne parameter gerufen und beendet den Batch
if not exist "%~1" (echo Inputdatei "%~1" nicht gefunden!) && goto :eof
Bringt Hinweis "Inputdatei x:\whatever.imp nicht gefunden, wenn es diese nicht gibt und endet.
echo 100,0,1,1;10,1;24,A
Schreibt/ECHOd die "Kopfzeile"
for /f "delims=,' tokens=1-4" %%a in ('findstr "(12) (13)" "%~1"') do (
Das 'Findstr "(12) (13)" siebt alle Zeilen mit dem String "(12)" bzw. "(13)" aus der Inputdatei %1.
Jede Zeile wird schon mal in Tokens (Satzteile) zerlegt. Als Trenner zwischen den "Worten" gelten Komma und einfaches Anführungszeichen ("delims=,' ").
Mach einfach ein findStr "(12) (13)" c:\cm\kas001.imp am CMD-Prompt zum Verständnis.

If "%%c"=="(12)" @echo\|set /p=%%a,%%b,1,"%%d",2,01,
Wenn es eine Zeile mit dem dritten Token "(12)" ist, also die mit ArtikelBez, dann ...
--> ECHO Token1, Token2, 1,"Token4,2,01, [ohne Zeilenumbruch am Ende]
If "%%c"=="(13)" @for /f "delims=." %%i in ("%%d") do echo %%i
Wenn es eine Zeile mit dem dritten Token "(13)" ist, also die mit Preis, dann ...
--> ECHO den Preis = viertes Token - ohne alles nach dem "."/ohne ".00"
)
Klammer zu, Ende der FOR /F-Anweisung.
Im Stück also
::-------snipp phino.cmd
@echo off & if "%~1"=="" (echo Syntax: %0 Indatei [^>Outdatei]) && goto :eof  
if not exist "%~1" (echo Inputdatei "%~1" nicht gefunden!) && goto :eof  
echo 100,0,1,1;10,1;24,A
for /f "delims=,' tokens=1-4" %%a in ('findstr "(12) (13)" "%~1"') do (  
    If "%%c"=="(12)" @echo\|set /p=%%a,%%b,1,"%%d",2,01,  
    If "%%c"=="(13)" @for /f "delims=." %%i in ("%%d") do echo %%i  
)
Das wäre nur die Proof-of-Concept-Skizze -
wenn Du die auf die 6000 Artikel-Datei anwendest mit "phino c:\cm\kas001.imp >c:\out\outdatei.exp",
dann siehst Du ja zwei Minuten keine Bewegung auf dem Bildschirm und keine Erfolgsmeldung. Das verunsichert... face-wink

Aber zum Testen reichts erstmal.

Grüße
Biber
Mitglied: phino-edv
phino-edv 09.04.2008 um 11:36:42 Uhr
Goto Top
Hey,
DU BIST EIN GENIE!!!
Es klappt einwandfrei. Ich musste nur noch 2 Kommas gegen Semicolon tauschen und das Steuerzeichen für den Preis einfügen.
Das habe aber sogar ich hinbekommmenface-smile
Vielen, vielen Dank dafür. Ich werde es gleich morgen testen und Dir dann Bescheid geben, ob der Praxistest geklappt hat.
LG
Philipp
Mitglied: phino-edv
phino-edv 15.04.2008 um 13:42:34 Uhr
Goto Top
Hallo Biber,
hier nun also die versprochene Rückmeldung:

ES LÄUFT ABSOLUT SPITZE !!!

Die Kassen nehmen die Artikel ohne weiteres an und funktionierne einwandfrei.
Nocheinmal vielen Dank dafür...
Umso mehr schäme ich mich, gleich mit dem nächsten Problem zu kommenface-sad
Es passt aber haargenau hier rein, von daher habe ich kein neues Thema eröffnet.
Es ist an und für sich das gleiche Problem, nur einfacher und umgekehrt. Ich bekomme also von den Kassen eine Textdatei zurück. Diese Datei hat folgenden Inhalt (ist ein Beispiel-Auszug):

Zeile mit Inahlt a
2,1,1,8/77
6,1,31,0/77
6,1,64,7/77
Zeile mit Inhalt b
2,1,1,44/1277.5
6,1,31,0/1277.5
.
.
.
Zeile mit Inhalt g
6,1,31,0/1277.5

Die Zeilen, die nur einen Punkt enthalten, stehen nur als Platzhalter für weiteren Inhalt da. Ich muss nun die rot gefärbten Zeilen ändern. Insgesamt gibt es davon bis zu 7 Stk, es kann aber vorkommen, dass weniger dieser Zeilen auftauchen (wenn z.B. nicht alle Kassen auf den Abruf reagiert haben). Die Zeileninhalte sind im Prinzip die Kassnennamen.
Je nach Inhalt müssen die Zeilen gegen einen festen Text erstzt werden.
Im Prinzip also:

- Suche Zeile mit Inhalt a
- Ersetze Ziele mit Inhalt neu-a, wenn nicht vorhanden, überspringe und
- Suche Zeile mit Inhalt b
- Ersetze Zeile mit Inhalt neu-b, wenn nicht...
und so weiter bis Zeile mit Inhalt g.
Die anderen Daten müssen natürlich erhalten bleibenface-smile
Es wäre super, wenn Du da auch noch einen Tip für mich hast (oder auch jemand anderesface-smile)

Liebe Grüße
Philipp
Mitglied: Biber
Biber 16.04.2008 um 08:59:51 Uhr
Goto Top
Moin phino-edv,

das würde ich so skizzieren:
:: ---snipp VonnerKasse.cmd
@echo off & setlocal
::------##Hier anpassen:###
set "InDatei=%temp%\vonnerkasse.txt"  
set "ToRepl1=Zeile mit Inahlt a"  
set "NewTxt1=Neuer Inhalt kasse a"  
set "ToRepl2=Zeile mit Inhalt b"  
set "NewTxt2=Neuer Inhalt Kasse b"  
REM usw usw.
::------##Bis hier anpassen:###
for /f "delims=" %%i in (%InDatei%) do set "line=%%i" & call:ProcessLine  
goto :eof

:ProcessLine
 if "%line%"=="%ToRepl1%" (echo %Newtxt1%) && goto :eof   
 if "%line%"=="%ToRepl2%" (echo %Newtxt2%) && goto :eof  
 REM usw
 Echo %line%
 goto :eof
 :: ---snapp VonnerKasse.cmd

Auf Deinen oben angedeuteten Dateiausschnitt angewandt:
>type %temp%\vonnerkasse.txt
Zeile mit Inahlt a
2,1,1,8/77
6,1,31,0/77
6,1,64,7/77
Zeile mit Inhalt b
2,1,1,44/1277.5
6,1,31,0/1277.5
.
.
.
Zeile mit Inhalt g
6,1,31,0/1277.5

>e:\schnipsel\VonnerKasse.cmd
Neuer Inhalt kasse a
2,1,1,8/77
6,1,31,0/77
6,1,64,7/77
Neuer Inhalt Kasse b
2,1,1,44/1277.5
6,1,31,0/1277.5
.
.
.
Zeile mit Inhalt g
6,1,31,0/1277.5

Grüße
Biber
Mitglied: phino-edv
phino-edv 16.04.2008 um 11:54:00 Uhr
Goto Top
Hey Biber,
das ging schnell.. Ja, und wieder das gleiche Ergebnis. ES LÄUFT.
Ich danke Dir ganz herzlich.
LG
Philipp