christiankarl
Goto Top

CSV Datei per Batch erweitern

Hallo an das Forum, vielleicht kann mir einer von Euch weiterhelfen.

Ich habe eine CSV Datei mit ";" getrennten Zeichen

Diese hat u.a. folgenden "Spaltenüberschriften"
Service & ISBNNummer

Test;Test2;Test3;.....;Service;...;Test20;ISBNNummer;Test23
2;aaa;123;.....;C22222;...;11111;10000;Test23
3;bbb;456;.....;C33333;...;22222;20000;Test23
Nun möchte ich erreichen, dass eine weitere Spalte hinzugefügt wird "Steuersatz"
Test;Test2;Test3;.....;Service;...;Test20;ISBNNummer;Test23;Steuersatz
darunter sollen die Werte aus Service & ISBNNummer zusammengefasst werden, getrennt mit einem "-"
Test;Test2;Test3;.....;Service;...;Test20;ISBNNummer;Test23;Steuersatz
2;aaa;123;.....;C22222;...;11111;10000;Test23;C22222-10000
3;bbb;456;.....;C33333;...;22222;20000;Test23;C33333-20000
manuell in Excel ist dieses für mich kein Problem, nur soll dieses per VBS Script oder Batch laufen
ohne das ein anderes Problem noch manuell eingegriffen werden muss.

Ich kenne mich in der Programmierung nicht aus, vielleicht kann mir hier jemand helfen.

Schönen Gruß

Content-Key: 206191

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

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

Member: bastla
bastla May 07, 2013 at 18:37:52 (UTC)
Goto Top
Hallo christiankarl und willkommen im Forum!

Grundsätzlich sollte das mit einem VBScript keine große Sache sein - allerdings bräuchte ich dazu eine Satzbeschreibung (bzw zumindest die Spaltennummern der beiden relvanten Felder - diese werden ja wohl immer gleich bleiben) ...

Grüße
bastla
Member: rubberman
rubberman May 07, 2013 at 21:29:33 (UTC)
Goto Top
Hallo christiankarl, willkommen im Forum.

Wie bastla schon angemerkt hat, ist das recht gut per VBScript zu lösen.

*.vbs
Option Explicit

Const strCSVPath = "test.csv"  
Const strColSrv  = "Service"  
Const strColISBN = "ISBNNummer"  
Const strColNew  = "Steuersatz"  

Const ForReading = 1
Const ForWriting = 2

Dim objFSO, objFile, objStream, aLine, i, idxService, idxISBN, sNewContent

Set objFSO = CreateObject("Scripting.FileSystemObject")  
If objFSO.FileExists(strCSVPath) Then
  Set objFile = objFSO.GetFile(strCSVPath)
  If objFile.Size > 0 Then
    Set objStream = objFile.OpenAsTextStream(ForReading)
    aLine = Split(objStream.ReadLine, ";")  
    If UBound(aLine) = -1 Then
      MsgBox "Die CSV Datei beginnt mit einer Leerzeile.", vbCritical Or vbSystemModal, "Fehler"  
      WScript.Quit
    End If
    If aLine(UBound(aLine)) <> strColNew Then
      idxService = -1
      idxISBN = -1
      For i = 0 To UBound(aLine)
        If aLine(i) = strColSrv Then idxService = i
        If aLine(i) = strColISBN Then idxISBN = i
      Next
      If idxService > -1 And idxISBN > -1 Then
        sNewContent = Join(aLine, ";") & ";" & strColNew  
        While Not objStream.AtEndOfStream
          aLine = Split(objStream.ReadLine, ";")  
          If UBound(aLine) = i - 1 Then
            sNewContent = sNewContent & vbNewLine & Join(aLine, ";") & ";" & aLine(idxService) & "-" & aLine(idxISBN)  
          Else
            MsgBox "Zeile mit Anzahl Elementen ungleich Überschrift gefunden.", vbCritical Or vbSystemModal, "Fehler"  
            WScript.Quit
          End If
        Wend
        objStream.Close
        Set objStream = objFile.OpenAsTextStream(ForWriting)
        objStream.Write sNewContent
        objStream.Close
      Else
        MsgBox "Überschrift """ & strColSrv & """ und/oder """ & strColISBN & """ nicht gefunden.", vbCritical Or vbSystemModal, "Fehler"  
        WScript.Quit
      End If
    Else
      MsgBox "Überschrift """ & strColNew & """ existiert bereits.", vbCritical Or vbSystemModal, "Fehler"  
      WScript.Quit
    End If
  Else
    MsgBox "Die CSV Datei hat keinen Inhalt.", vbCritical Or vbSystemModal, "Fehler"  
    WScript.Quit
  End If
Else
  MsgBox "Die CSV Datei konnte nicht gefunden werden.", vbCritical Or vbSystemModal, "Fehler"  
  WScript.Quit
End If

Grüße
rubberman
Member: bastla
bastla May 07, 2013 updated at 21:40:53 (UTC)
Goto Top
Hallo rubberman!

Dass Du gleich die Luxus-Variante auspackst ... face-wink

Falls das Script auch unattended verwendet werden soll, wäre "WScript.Echo" anstelle von "MsgBox" vorteilhaft, und dann würde ich den jeweiligen Fehler auch durch
WScript.Quit <Fehlernummer>
als Errorlevel zurückgeben ...

Grüße
bastla
Member: christiankarl
christiankarl May 08, 2013 updated at 07:08:33 (UTC)
Goto Top
Hallo rubberman, Hallo Bastla,

vielen Dank für die Rückmeldung und für das deutlich und ausführliche Script.
Trotz, dass in der ersten Zeile die Werte Service & ISBNNummer vorhanden
und darunterliegende Werte alle gefüllt sind erscheint der Hinweis

"Zeile mit Anzahl Elementen ungleich Überschrift gefunden"

Vielleicht kann hier nochmal jemand drüber schauen

Danke schön, Christian
Mitglied: 76109
76109 May 08, 2013 updated at 09:03:30 (UTC)
Goto Top
Hallo christiankarl!

Das soll heißen, dass die CSV-Datei eine (oder mehrere) Zeilen enthält, in denen die Anzahl der Trennzeichen (;) nicht mit der Anzahl Trennzeichen in der Überschriftzeile übereinstimmt... Kann sich aber auch um eine Leerzeile (vermutlich am Dateiende) handeln ?

Ersetze mal Codezeile 36 (Else) durch:
ElseIf UBound(aLine) > -1 Then 
Dadurch werden Leerzeilen ignoriert...

Gruß Dieter
Member: christiankarl
christiankarl May 08, 2013 at 09:29:57 (UTC)
Goto Top
Hallo Dieter,

vielen Dank für den Hinweis,
genau das war es gewesen, hier war eine Leerzeile am ende mit enthalten gewesen.

Gruß
Christian
Member: christiankarl
christiankarl May 08, 2013 updated at 11:35:46 (UTC)
Goto Top
Hallo,
ich hatte zu diesem Problem ein weiteres aufgemacht,
auf Anraten sollte ich die Frage aber hier mit einfügen

in der CSV Datei stehen an unterschiedlichen Stellen Wörter mit APP@

Test;STOAPP@DE1234;
Test2;CAROAPP@DE748;
Test3;MARIAPP@KU1234;
ect.

Nun möchte ich erreichen, dass die gesamte Datei durchsucht wird und sobald der String APP@ vorhanden ist, dieser vor dem Wert APP alles stehen lässt

Test;STO;
Test2;CAR;
Test3;MAR;
ect.

Kann hier bestehendes Skript noch erweitert werden?

Gruß
Christian
Member: bastla
bastla May 08, 2013 at 13:48:07 (UTC)
Goto Top
Hallo christiankarl!

Ungetesteter Ansatz: Füge nach Zeile 6
Const strDelim = "APP@"  
und zwischen Zeile 34 und 35
For j = 0 To UBound(aLine)
    iPos = InStr(aLine(j), strDelim)
    If iPos > 0 Then aLine(j) = Left(aLine(j), iPos - 1)
Next
ein.

Grüße
bastla
Member: christiankarl
christiankarl May 08, 2013 at 14:13:10 (UTC)
Goto Top
Hallo Bastla,

ich habe deinen Ansatz eingebunden,
leider ändert er die Werte nicht ab

Option Explicit

Const strCSVPath = "global.csv"  
Const strColSrv  = "Service"  
Const strColISBN = "ISBNNummer"  
Const strColNew  = "ref"  
Const strDelim   = "app@"  

Const ForReading = 1
Const ForWriting = 2

Dim objFSO, objFile, objStream, aLine, i, idxService, idxISBN, sNewContent, j, iPos

Set objFSO = CreateObject("Scripting.FileSystemObject")  
If objFSO.FileExists(strCSVPath) Then
  Set objFile = objFSO.GetFile(strCSVPath)
  If objFile.Size > 0 Then
    Set objStream = objFile.OpenAsTextStream(ForReading)
    aLine = Split(objStream.ReadLine, ";")  
    If UBound(aLine) = -1 Then
      MsgBox "Die CSV Datei beginnt mit einer Leerzeile.", vbCritical Or vbSystemModal, "Fehler"  
      WScript.Quit
    End If
    If aLine(UBound(aLine)) <> strColNew Then
      idxService = -1
      idxISBN = -1
      For i = 0 To UBound(aLine)
        If aLine(i) = strColSrv Then idxService = i
        If aLine(i) = strColISBN Then idxISBN = i
      Next
      If idxService > -1 And idxISBN > -1 Then
        sNewContent = Join(aLine, ";") & ";" & strColNew  
        While Not objStream.AtEndOfStream
        For j = 0 To UBound(aLine)
            iPos = InStr(aLine(j), strDelim)
            If IPos > 0 Then aLine(j) = Left(aLine(j), iPos -1)
        next
        aLine = Split(objStream.ReadLine, ";")  
          If UBound(aLine) = i - 1 Then
            sNewContent = sNewContent & vbNewLine & Join(aLine, ";") & ";" & aLine(idxService) & aLine(idxISBN)  
          ElseIf UBound(aLine) > -1 Then 
            MsgBox "Zeile mit Anzahl Elementen ungleich Überschrift gefunden.", vbCritical Or vbSystemModal, "Fehler"  
            WScript.Quit
          End If
        Wend
        objStream.Close
        Set objStream = objFile.OpenAsTextStream(ForWriting)
        objStream.Write sNewContent
        objStream.Close
      Else
        MsgBox "Überschrift """ & strColSrv & """ und/oder """ & strColISBN & """ nicht gefunden.", vbCritical Or vbSystemModal, "Fehler"  
        WScript.Quit
      End If
    Else
      MsgBox "Überschrift """ & strColNew & """ existiert bereits.", vbCritical Or vbSystemModal, "Fehler"  
      WScript.Quit
    End If
  Else
    MsgBox "Die CSV Datei hat keinen Inhalt.", vbCritical Or vbSystemModal, "Fehler"  
    WScript.Quit
  End If
Else
  MsgBox "Die CSV Datei konnte nicht gefunden werden.", vbCritical Or vbSystemModal, "Fehler"  
  WScript.Quit
End If

Kannst du hier nochmal drüberschauen?
Vielen Dank für die vielen Hilfen.

Gruß
Christian
Member: bastla
bastla May 08, 2013 at 14:32:28 (UTC)
Goto Top
Hallo christiankarl!

Der zweite Codeteil sollte nach der ursprünglichen Zeile 34, also
If UBound(aLine) = i - 1 Then
rein ...

Damit sowohl "app@" als auch "APP@" erkannt werden, verwende
iPos = InStr(1, aLine(j), strDelim, vbTextCompare)
als Ersatz meiner Zeile 2 von oben ...

Grüße
bastla
Member: christiankarl
christiankarl May 08, 2013 updated at 14:56:39 (UTC)
Goto Top
Hallo Bastla;

Danke nochmal für die Rückmeldung.

Beim weiteren Ausführen erscheint nun ein Windows Script Host Error

Zeile 37
Zeichen 9
Fehler Typen unverträglich. '[STRING. "cad"]"
Code 800A000D

Der Wert cad steht in der 2 Zeile der CSV Datei, direkt als erster Wert.
Der Wert mit "app@" kommt erst in den anderen Bereichen,
vielleicht hilft der Hinweis: Der zu korrigierende Wert "app@" ist im Bereich mit der Überschrift "KBANT" zu finden

Gruß
Christian
Member: bastla
bastla May 08, 2013 at 14:57:33 (UTC)
Goto Top
Hallo christiankarl!

Was steht denn in der Zeile 37?

Grüße
bastla
Member: christiankarl
christiankarl May 08, 2013 at 15:09:38 (UTC)
Goto Top
Anbei Codezeile 35 - 39

35          If UBound(aLine) = i - 1 Then
36		  For j = 0 To UBound(aLine)
37              iPos = InStr(1, aLine(j), strDelim, vbTextCompare)
39              If iPos > 0 Then aLine(j) = Left(aLine(j), iPos - 1)
40      Next

Gruß
Christian
Member: bastla
bastla May 08, 2013 at 15:42:16 (UTC)
Goto Top
Hallo christiankarl!

Mit Deinen oben ansatzweise geposteten Testdaten (ergänzt um Einträge der Art "STOAPP@DE1234") und dieser Script-Version
Option Explicit

Const strCSVPath = "global.csv"  
Const strColSrv  = "Service"  
Const strColISBN = "ISBNNummer"  
Const strColNew  = "ref"  
Const strDelim   = "app@"  

Const ForReading = 1
Const ForWriting = 2

Dim objFSO, objFile, objStream, aLine, i, idxService, idxISBN, sNewContent, j, iPos

Set objFSO = CreateObject("Scripting.FileSystemObject")  
If objFSO.FileExists(strCSVPath) Then
  Set objFile = objFSO.GetFile(strCSVPath)
  If objFile.Size > 0 Then
    Set objStream = objFile.OpenAsTextStream(ForReading)
    aLine = Split(objStream.ReadLine, ";")  
    If UBound(aLine) = -1 Then
      MsgBox "Die CSV Datei beginnt mit einer Leerzeile.", vbCritical Or vbSystemModal, "Fehler"  
      WScript.Quit
    End If
    If aLine(UBound(aLine)) <> strColNew Then
      idxService = -1
      idxISBN = -1
      For i = 0 To UBound(aLine)
        If aLine(i) = strColSrv Then idxService = i
        If aLine(i) = strColISBN Then idxISBN = i
      Next
      If idxService > -1 And idxISBN > -1 Then
        sNewContent = Join(aLine, ";") & ";" & strColNew  
        While Not objStream.AtEndOfStream
          aLine = Split(objStream.ReadLine, ";")  
          If UBound(aLine) = i - 1 Then
            For j = 0 To UBound(aLine)
              iPos = InStr(1, aLine(j), strDelim, vbTextCompare)
              If IPos > 0 Then aLine(j) = Left(aLine(j), iPos -1)
            Next
            sNewContent = sNewContent & vbNewLine & Join(aLine, ";") & ";" & aLine(idxService) & aLine(idxISBN)  
          ElseIf UBound(aLine) > -1 Then 
            MsgBox "Zeile mit Anzahl Elementen ungleich Überschrift gefunden.", vbCritical Or vbSystemModal, "Fehler"  
            WScript.Quit
          End If
        Wend
        objStream.Close
        Set objStream = objFile.OpenAsTextStream(ForWriting)
        objStream.Write sNewContent
        objStream.Close
      Else
        MsgBox "Überschrift """ & strColSrv & """ und/oder """ & strColISBN & """ nicht gefunden.", vbCritical Or vbSystemModal, "Fehler"  
        WScript.Quit
      End If
    Else
      MsgBox "Überschrift """ & strColNew & """ existiert bereits.", vbCritical Or vbSystemModal, "Fehler"  
      WScript.Quit
    End If
  Else
    MsgBox "Die CSV Datei hat keinen Inhalt.", vbCritical Or vbSystemModal, "Fehler"  
    WScript.Quit
  End If
Else
  MsgBox "Die CSV Datei konnte nicht gefunden werden.", vbCritical Or vbSystemModal, "Fehler"  
  WScript.Quit
End If
läuft das bei mir fehlerfrei (und erfolgeich) ...

Sollte der Fehler bei Dir weiterhin auftreten, poste bitte Deine "global.csv" (auf die relevanten Zeilen reduziert und ggf anonymisiert) in "Code"-Formatierung.

Grüße
bastla
Member: christiankarl
christiankarl May 09, 2013 at 08:21:42 (UTC)
Goto Top
Hallo Bastla,

vielen dank für die Rückmeldung.
komisch, nun geht's bei mir auch.
Ich danke dir für die hilfreiche Unterstützung.

wünsche ein schönen Feiertag
Member: rubberman
rubberman May 10, 2013 at 11:00:52 (UTC)
Goto Top
[OT]
@ bastla und Dieter

Danke für die (Kurz-)Urlaubsvertretung. Ist normalerweise nicht meine Art ein Stück Code in die Welt zu werfen und mich dann nicht mehr darum zu kümmern ... face-wink

Grüße
rubberman
[/OT]
Member: bastla
bastla May 10, 2013 at 11:25:33 (UTC)
Goto Top
Hallo rubberman!

Aber gerne - wenn's Dich nicht stört, dass ich an Deinem Code rumpfusche ... face-wink

Grüße
bastla
Mitglied: 76109
76109 May 10, 2013 at 22:10:37 (UTC)
Goto Top
Hallo rubberman!

Ebenfalls gerneface-wink

Bin ja auch froh, wenn ich Unterstützung bekomme und habe auch grundsätzlich nichts dagegen, wenn ihr in meinen Codes rumpfuschtface-smile

Gruß Dieter