goodbytes
Goto Top

Umkonvertieren von ASKII-Dateien per vbs

Hallo,
ich muss Teile aus einer ASKII-Datei, welche Semikolon als Trennzeichen hat, bestimmte Felder in eine neue Datei in ein anderes Format konvertieren, da sich die Releasestände von einem Programm stark unterscheiden.

Die Zieldatei hat keine Trennzeichen, eine neue Spalte beginnt jeweils ab einer genau definierten Stelle. Das heisst, man müsste den Inhalt immer mit Leerzeichen auffüllen, damit ich exakt auf die definierte Spaltenbreite komme.

Hier ein Beispiel aus der Quelldatei (ist eine Zeile, also keine Zeilenumbrüche):

RDAGTK;01;20081103;0556;0000001;0068658;B2318N3301; ;          ;UNTERD.SCHLAURA14;                 ;0000006498;EUR;1;0;04; ;0000000000;001;0000000280;0000001452;510;M; ;    ;1;4;4;   ; ;M;RA;14;

Hier das gleiche Beispiel aus der Zieldatei:

0110     M00000001B2318N3301   E44010400064981UNTERD.SCHLAURA14            510M

Man sieht auch, dass in der Zieldatei auch nicht alle Informationen aus der Quelldatei benötigt werden.
(Die 0110 steht immer davor.)

Torsten

Content-ID: 101849

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

Ausgedruckt am: 22.11.2024 um 15:11 Uhr

bastla
bastla 14.11.2008 um 13:21:55 Uhr
Goto Top
Hallo TorstenB!

Wäre es wohl von Dir zuviel verlangt, die Zusammensetzung der neuen Datei genau zu beschreiben (Stellenanzahl bzw Positionen, Herkunftsspalte - stammt etwa das erste "M" aus der Spalte 23 oder 31, woher kommt das "E" vor 44010.. sowie 44010 selbst? - etc)?

Grüße
bastla
goodbytes
goodbytes 14.11.2008 um 14:48:33 Uhr
Goto Top
Hallo bastla,

hast natürlich recht, dass ich da natürlich noch eine genauere Beschreibung nachliefern sollte ...

Ich werd mich mal am Wochenende ransetzen, heute schaffe ich`s leider nicht mehr.

Vielen Dank erstmal, dass du helfen willst ...

Bis dann erstmal ein schönes Wochenende !!! face-smile

Torsten
talkinghands
talkinghands 14.11.2008 um 19:12:59 Uhr
Goto Top
Hi Torsten,

das sollte Dir ungefähr eine Ahnung geben wie man mit so etwas via VB Script umgeht.

 
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
WindowTitle = "CSV Dateien wandeln"  
ExportDirectory = ".\OUTPUT\"   ' Export Verzeichnis  
export_datei  = "OUTPUT.TXT"    ' Exportdatei  

If fso.FolderExists(ExportDirectory) = False Then 
   Set makedir = fso.CreateFolder(ExportDirectory)   ' Verzeichnis neu anlegen  
End If
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

ExportFileOpen
MainControl
ExportFileClose

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
' "TES"  = die ersten 3 Zeichen der zu verarbeitenden Datei  
' "TXT"  = Datei Extension der zu verarbeitenden Datei  
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
Sub MainControl
   BoxText = "Die Exportdatei:"&vbCRLF &vbCRLF &ExportDirectory&export_datei &vbCRLF  
   BoxText = Boxtext & "wird jetzt erstellt !"  
   MeineVar = MsgBox(BoxText,vbInformation, WindowTitle)   ' Statusfenster  
   For each fl in fs
      Datei = fl.name
      If Left(UCase(datei),3)="TES" and Right(UCase(datei),3)="TXT" Then  
         mk_export
      End If
   Next
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
Sub mk_export
   Set FileIn  = FSO.OpenTextFile( datei, 1 )    ' Datei zum Lesen öffnen   
   Do While Not (FileIn.atEndOfStream)    ' wenn Datei nicht zu Ende ist, weiter machen  
      LOGTXT = FileIn.Readline    ' eine Zeile lesen  
      schreib_neu
   Loop
   FileIn.Close
   Set FileIn  = nothing 
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
Sub schreib_neu
   cString = UCase(LOGTXT)
   intpos = InStr(cString,";")    ' Feld 1 des Original Datensatzes  

   cString = Right(cString,Len(cString)-intpos)
   intpos = InStr(cString,";")    ' Feld 2 des Original Datensatzes  

   cString = Right(cString,Len(cString)-intpos)
   intpos = InStr(cString,";")    ' Feld 3 des Original Datensatzes  

   cString = Right(cString,Len(cString)-intpos)
   intpos = InStr(cString,";")    ' Feld 4 des Original Datensatzes etc.  

   cString = Right(cString,Len(cString)-intpos)
   intpos = InStr(cString,";")  
   Dsatz_Neu = "0110      M" & Left(cString,intpos-1)    ' Feld 1 + 2 neuer Datensatz  

   cString = Right(cString,Len(cString)-intpos)
   intpos = InStr(cString,";")  

   cString = Right(cString,Len(cString)-intpos)
   intpos = InStr(cString,";")  
   Dsatz_Neu = Dsatz_Neu & Left(cString,intpos-1) & "    E"    ' nächstes Feld neuer Datensatz  

   BoxText = Dsatz_Neu
   RechOut.Write( BoxText )    ' neuen Datensatz in Datei schreiben  
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
Sub ExportFileOpen
   Set RechOut  = FSO.OpenTextFile( ExportDirectory & export_datei , 2, true)
  ' Exportdatei zum Schreiben öffnen; 2: immer neu anlegen  
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
Sub ExportFileClose
   RechOut.Close
   Set RechOut  = nothing
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  


Gruss

Matthias
Biber
Biber 14.11.2008 um 19:44:12 Uhr
Goto Top
@talkinghands
<nur halb OT>
Ich bin ja nur Gast in diesem Teil des Forums und WEIT davon entfernt, VBScript für eine strukturierte Sprche zu halten.
Noch weniger halte ich mich für übertrieben ordnungsliebend (dafür könnte ich Zeugen benennen!).

Aber diese Art von Freistil bei der Variablen-Benamsung

  • mal "WindowTitle" oder "ExportDirectory"
  • mal "cString" und "intpos"
  • mal "meineVar" und "LOGTXT"
  • mal "Dsatz_Neu" und "export_Datei"

das bitte nicht unbedingt einem Neu-Einsteiger so vormachen.
</nur halb OT>

Grüße
Biber
talkinghands
talkinghands 15.11.2008 um 04:00:35 Uhr
Goto Top
@Torsten
Ich habe das Ganze etwas abgespeckt und dem Verwendungszweck näher gebracht .


'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   
Dim WSHShell, fso, f, fs
Dim Datei, Text, FileIn, FileOut, LOGTXT, RechOut
Set WSHShell = WScript.CreateObject("WScript.Shell")  
Set fso      = WScript.CreateObject("Scripting.FileSystemObject")  
Set f        = fso.GetFolder(".")  
' aktuelles Verzeichnis in dem dieses Script ausgeführt wird  
Set fs       = f.Files
' alle Dateien  

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

MainControl

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
' angenommen der Name der Importdatei sei "test.txt"  
' dann ist der Name der Exportdatei "_test.txt"  
' "TES"  = die ersten 3 Zeichen der zu verarbeitenden Datei  
' "TXT"  = Datei Extension der zu verarbeitenden Datei  
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
Sub MainControl
   For each fl in fs
      Datei = fl.name
      If Left(UCase(datei),3)="TES" and Right(UCase(datei),3)="TXT" Then  
         ExportFileOpen
         mk_export
         ExportFileClose
      End If
   Next
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
Sub mk_export
   Set FileIn  = FSO.OpenTextFile( datei, 1 )
   ' Datei zum Lesen öffnen   
   Do While Not (FileIn.atEndOfStream)    
   ' wenn Datei nicht zu Ende ist, weiter machen  
      LOGTXT = FileIn.Readline
      ' eine Zeile lesen  
      schreib_neu
   Loop
   FileIn.Close
   Set FileIn  = nothing 
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
Sub schreib_neu
   Dim intpos(33)
   ' insgesamt 33 Felder in der CSV Datei  
   cString = UCase(LOGTXT)
   For i = 1 to 33
      intpos(i) = InStr(cString,";")  
      ' Feld 5 des Original Datensatzes etc..  
      If i =  5 Then Feld05 = Left(cString,intpos(i)-1)
      If i =  7 Then Feld07 = Left(cString,intpos(i)-1)
      If i = 12 Then Feld12 = Left(cString,intpos(i)-1)
      If i = 15 Then Feld15 = Left(cString,intpos(i)-1)
      If i = 31 Then Feld31 = Left(cString,intpos(i)-1)
      'MsgBox Left(cString,intpos(i)-1) & " Zähler "&i &" Position "& intpos(i)  
      ' wenn MsgBox nicht mehr notwendig ist - einfach auskommentieren  
      cString = Right(cString,Len(cString)-intpos(i))
      ' den String linksseitig kürzen  
   Next
   dSatz_neu = "0110     " & Feld31 & Feld05 & Feld07 &"   " & Feld15 & Feld12  
   ' hier werden die einzelnen Felder in der erforderlichen Reihenfolge zusammen gesetzt  
   ' die Leerzeichen müssen an der entsprechenden Stelle eingefügt werden  
   RechOut.Write( dSatz_neu )    ' neuen Datensatz in Datei schreiben  
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
Sub ExportFileOpen
   Set RechOut  = FSO.OpenTextFile( "_"&Datei, 2, true)  
  ' Exportdatei zum Schreiben öffnen; 2: immer neu anlegen  
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
Sub ExportFileClose
   RechOut.Close
   Set RechOut  = nothing
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

Gruss

Matthias
bastla
bastla 15.11.2008 um 16:31:34 Uhr
Goto Top
@talkinghands

Da hast Du ja ein ganzes Programm daraus gemacht ...

... als Script (und zur Umwandlung nur einer Datei) sollte es auch etwas knapper gehen (wobei ohnehin fast die Hälfte auf das Dateihandling entfällt, was sich bei Start über einen Batch noch deutlich reduzieren ließe):
If WScript.Arguments.Count > 0 Then 'Quelldatei als Parameter übergeben?  
    Source = WScript.Arguments(0)
Else
    WScript.Echo "Bitte das Script mit Angabe der Quelldatei aufrufen!" & vbCrLf & vbCrLF & _  
	    "Beispiel: " & vbCrLF & "cscript //nologo """ & WScript.ScriptFullName & """ ""D:\ASCII-Dateien\Eine ASCII-Datei.txt"""  
	WScript.Quit 1
End If

Set fso = WScript.CreateObject("Scripting.FileSystemObject")  
If Not fso.FileExists(Source) Then 'Quell-Datei nicht vorhanden?  
    WScript.Echo "Die Quelldatei """ & Source & """ konnte nicht gefunden werden."  
	WScript.Quit 1
End If

'Zieldatei (durch Anfügen von "-neu" an den Quelldateinamen) festlegen  
Target = fso.GetParentFolderName(Source) & fso.GetBaseName(Source) & "-neu." & fso.GetExtensionName(Source)  

Data = Split(fso.OpenTextFile(Source).ReadAll, vbCrLf) 'gesamte Datei in Array einlesen  
DataNew = "" 'neuen Dateiinhalt in dieser Variablen erstellen  
		
For Each Line In Data 'alle Zeilen der aktuellen Datei bearbeiten  
    'Zeile in Felder zerlegen (Trennzeichen = ";"), die Nummerierung der Felder beginnt bei 0  
    Fields = Split(Line, ";")   
			
    'In den folgenden Zeilen ist jeweils die gewünschte Stellenanzahl  
    'je Feld (als Beispiel wurde durchgehend 12 verwendet) festzulegen,  
    'wobei jedes Feld linksbündig übernommen wird.  
    LineNew = "0110     " & _  
        Left(Trim(Fields(30)) & Space(12), 12) & _
        Left(Trim(Fields(4))  & Space(12), 12) & _
        Left(Trim(Fields(6))  & Space(12), 12) & _
        Left(Trim(Fields(14)) & Space(12), 12) & _
        Left(Trim(Fields(11)) & Space(12), 12)

    'neue Zeile an neuen Dateiinhalt anfügen  
    DataNew = DataNew & vbCrLf & LineNew 
Next

'gesamten neuen Dateiinhalt in Zieldatei schreiben  
fso.CreateTextFile(Target, True).Write Mid(DataNew, 3)
Aufgerufen werden kann das Script per Commandline (Beispiel dafür wird angezeigt, wenn das Script ohne Parameter gestartet wird) oder einfach durch Ziehen der Quelldatei auf die Scriptdatei.

Grüße
bastla
talkinghands
talkinghands 15.11.2008 um 18:00:17 Uhr
Goto Top
@bastla

das kleine Script hat ja nur 79 Zeilen und ist ein wenig strukturiert.
Ich denke, das macht es für den Leser der Zeilen verständlicher.

Das Script ist so konzipiert, dass mehrere Dateien abgearbeitet werden können.


Anhand deiner Herangehensweise sieht er doch auf welch verschiedene Arten man an eine solche Aufgabe lösen kann. Und ich selbst kann dabei auch etwas durch deinen Lösungsvorschlag lernen.

Gruss

Matthias
bastla
bastla 15.11.2008 um 18:20:13 Uhr
Goto Top
@talkinghands
Natürlich kein Einwand gegen Strukturierung - ich neige einfach nur dazu, für ein "Script" wenig Aufwand zu treiben (auch, da wegen des geringen Umfanges der Überblick nicht so schnell verloren geht), und daher zB auf unnötige Variablen (und deren Deklaration face-wink) zu verzichten ("LineNew" ist die Ausnahme und soll tatsächlich der Übersichtlichkeit dienen).

Findest Du meinen Ansatz oben schwer verständlich?
(Mich selbst stören daran die Kommentarzeilen ... face-wink)

Grüße
bastla
talkinghands
talkinghands 15.11.2008 um 19:47:57 Uhr
Goto Top
@bastla

Nein, der Code ist gut verständlich für mich.
Wirklich effizient und minimal.
Da kann man sich was dabei abgucken face-smile

ciao

Matthias
goodbytes
goodbytes 16.11.2008 um 13:31:22 Uhr
Goto Top
Hallo ihr Beiden,
sorry, dass ich mich jetzt erst melde. Hatte das Wochenende ziemlich viel um die Ohren (und meine zwei kleinen Stöpsel haben mich zusätzlich noch ziemlich viel Nerven gekostet).

Ich würde mal sagen, dass ich es mal mit euren (eigentlich schon fertigen Skripten) in den nächsten Tagen mal probiere. Erst mal in Ruhe im Zug zur Arbeit in ausgedruckter Form durcharbeiten. Allein die Lösung ist ja nicht Alles; ich möchte es ja auch verstehen und was draus lernen. face-smile

Dann meld ich mich auf jeden Fall, wenn`s läuft, oder ich noch Fragen habe.

Vielen Dank erst einmal an euch !!! face-smile

Torsten
goodbytes
goodbytes 21.11.2008 um 07:45:42 Uhr
Goto Top
Hallo,
leider habe ich festgestellt, dass ich um ein Update auf die neue Version doch nicht herum komme.

Das von bastla am Anfang erwähnte (und sich auch ständig ändernde) "E44010..." ist für die alte Version unbedingt erforderlich, wird aber in der neuen Version nicht mitgeliefert.

Leider ist es nicht möglich die tatsächliche Bedeutung dieses Wertes herauszubekommen. Selbst der Hersteller der Software hüllt sich darüber in Schweigen. Klar - er will ja auch das neue Produkt verkaufen...

Auf jeden Fall habe ich viel von euch über das Umkonvertieren von ASKII-Dateien gelernt; so was benötige ich immer wieder.

Vielen vielen Dank an euch und ein schönes Wochenende !!! face-smile

Torsten