vasili
Goto Top

Konvertieren einer CSV Datei im Batch Betrieb

Inhaltliche Anpassung einer CSV Datei in eine neue CSV Datei.

Ich schlage mich seit geraumer Zeit mit Zwei Programmen herum.
Beide beherrschen CSV, nur leider kommt nichts brauchbares nach dem Export und Import heraus.

Das eine exportiert eine CSV Datei mit Semikolon als Trennzeichen.
Das andere Importiert mit Tabulator als Trennzeichen.
Beide verwenden keine Anführungszeichen zum Abgrenzen der Datenfelder.
So weit wäre es kein Problem aus a.csv die Datei b.csv zu machen.

Mir schwebt ein Skript vor mit folgender Nomenklatur Form vor.

Skript Eingabedatei.csv Ausgabedatei.csv Umwandlungsliste.

Leider bin ich mit Batch nicht sonderlich bewandert und Visual Basic ist mir leider vollkommen unbekannt.

In der Umwandlungsliste bräuchte ich folgende Art von Befehlen, die der Reihe nach abgearbeitet werden müssten, um die Daten anzupassen:

Optional könnte auch in der Umwandlungsliste Datei am Anfang die Namen der Dateien stehen, da diese ebenfalls immer gleich sind.
Und eventuell auch die jeweils benötigten Trennzeichen mit angeben.

Spalte x (x steht für Stelle 1 erste, ...) nach Spalte y verschieben.

Spalte x löschen.

Nach Spalte x leere Spalte einfügen.

Kopiere Spalte x und füge nach Spalte y ein

An Spalte x die Spalte Y dranhängen und dazwischen folgende Zeichen zwischen den Anführungszeichen einfügen einfügen " "

Bezeichnung der Spalte x ändern in "neuer Name"

Bereinige - Entferne leere Zeilen (nur Semikolons)


Diese Funktionen würden mir Genügen, denn mit diesen erledige ich es bisher immer per Hand.


Vielen Dank schon einmal in voraus.

Leider bin ich mit dem Skript selbst ein wenig überfordert.

Ich verwende Windows XP und mache dies fast jede Woche von Hand, um die aktuellen Adressen übertragen zu können.


Würde mich sehr um ein paar Hilfreiche Lösungsvorschläge freuen.

Content-ID: 110807

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

Ausgedruckt am: 15.11.2024 um 03:11 Uhr

76109
76109 08.03.2009 um 08:30:38 Uhr
Goto Top
Kommentar zwecks Übersicht entfernt!
76109
76109 08.03.2009 um 09:14:01 Uhr
Goto Top
Kommentar zwecks Übersicht entfernt!
Biber
Biber 08.03.2009 um 11:34:12 Uhr
Goto Top
Moin Vasili,

ich denke, es ist auch mit ein paar Zeilen Batch ohne den Schlenker über Excel möglich.
Warüm sollten wir mit einer elektronisch geregelten Schlagbohrmaschine hier Reißzwecken in die Pinnwand drücken?

Könntest Du bitte drei oder vier (stilisierte) Beispielzeilen der heutigen a.csv und b.csv hier posten und die gewünschten Ergebniszeilen der Kombi.csv?

Dann ist für alle nachvollziehbarer, worum es geht.

Danke
Biber
Vasili
Vasili 08.03.2009 um 13:13:00 Uhr
Goto Top
Also es ist eine csv Tabelle, die mit Semikolon getrennt ist.
Kann auch in den Einstellungen beim Export nichts anderes auswählen.

Diese möchte ich regelmäßig konvertieren, dass es im anderen Programm importiert werden kann.

Dieses hat Komma und Tab als Trennzeichen zur Auswahl, da aber in den Daten auch Kommatas vorkommen, bleibt nur der Tab als Trennzeichen übrig.

Leider exportiert das Programm nach jedem Buchstaben im Alphabet eine Leezeile mit lauter Semikolons, die nach dem Import immer an die 30 Sinnlose Einträge ergibt, wenn ich diese nicht einzeln lösche.

In der Ersten Zeile stehen die Zellennamen.
Leider werden viel mehr Zellen Exportiert, als benötigt und andere fehlen wiederum.
Deswegen benötige ich leere Zellen/Spalen an der richtigen Stelle mit der Korrekten Bezeichnung. Ferner möchte ich von den überzähligen, die ich behalten will im Kommentarfeld Zusammenfassen, indem ich Bsp. ein Leerzeichen oder Leerzeichen BIndestrich Leerzeichen einfüge. DIese bekommen aber dann gemeinsam als ein Feld auch wieder einen neuen Feldnamen Notizen.
Vasili
Vasili 08.03.2009 um 13:17:07 Uhr
Goto Top
Kann im exportierendem Programm leider nichts auswählen.

Ich mache es auch schon per Hand, nur ist es sehr aufwendig.


Wenn es einzelne Batchbefehle gäbe mit Anweisungen, die Operationen wie oben genannte ausführen könnten wäre es auch möglich eine Batchdatei zu schreiben, und diese dann einzeln abzuarbeiten, da ich die Spalten einzeln umsortieren muss . Kopieren, vereinigen und in der Ersten Zeile die Bezeichnungen Teilweise umbenennen muss.
Vasili
Vasili 08.03.2009 um 14:59:38 Uhr
Goto Top
ALso es sieht so aus:

out.csv

L;TPNr;Name;Vorname;Firma;Angelegt;L.Ums.;Tel.Privat;Tel.Gesch.;Mobiltelefon;Fax;Straße;PLZ;Ort;L.;E-Mail;M1L;QVM;QLM;QualVolumen;Struktur;Umsatz;Eigen;Promotion;Kunden
1;08154711;Hirsch;Harry;HH;01.01.2008;30;0190444444;0190111111;0190222222;0190333333;Polarstr. 24;88888;Polarkreis;DE;harry@rudyhirsch.de;5;6;7;8;9;10;11;12;13
;;;;;;;;;;;;;;;;;;;;;;;;
2;47110815;Muster;Max;MM;02.02.2008;40;0190666666;0190777777;0190888888;0190999999;Maxstr. 99;999999;Bibberstadt;DE;max@muster.de;14;15;16;17;18;19;20;21;22


Gruppe.csv

Vorname Nachname Anzeigename Spitzname Primäre E-Mail Sekundäre E-Mail Tel. dienstlich Tel. privat Fax-Nummer Pager-Nummer Mobil-Tel.-Nr. Privat: Adresse Privat: Adresse 2 Privat: Stadt Privat: Bundesland Privat: PLZ Privat: Land Dienstlich: Adresse Dienstlich: Adresse 2 Dienstlich: Stadt Dienstlich: Bundesland Dienstlich: PLZ Dienstlich: Land Arbeitstitel Abteilung Organisation Webseite 1 Webseite 2 Geburtsjahr Geburtsmonat Geburtstag Benutzerdef. 1 Benutzerdef. 2 Benutzerdef. 3 Benutzerdef. 4 Notizen
Harry Hirsch Harry Hirsch Harry Hirsch harry@rudyhirsch.de 0190111111 0190444444 0190333333 0190222222 Polarstr. 24 Polarkkreis 888888 DE 08154711 01.01.2008 1 30 – 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 – 13
Max Muster Max Muster Max Muster max@muster.de 0190777777 0190666666 0190999999 0190888888 Maxstr. 99 Bibberstadt 999999 DE 47110815 02.02.2008 2 40 - 14 - 15 - 16 - 17 - 18 - 19 - 20 - 21 – 22
bastla
bastla 08.03.2009 um 16:05:37 Uhr
Goto Top
Hallo Vasili und willkommen im Forum!!

Um die Dateiinhalte (insbes jenen von "Gruppe.csv") richtig "rüber zu bringen" (ich konnte keine TAB finden) solltest Du -Formatierung verwenden...

Grüße
bastla
Vasili
Vasili 08.03.2009 um 17:01:18 Uhr
Goto Top
Beim Einfügen hier sind die Tabs wohl verschwunden und durch Leerzeichen ersetzt worden. Ist deswegen etwas schwieriger nachzuvollziehen.

"L";"TPNr";"Name";"Vorname";"Firma";"Angelegt";"L.Ums.";"Tel.Privat";"Tel.Gesch.";"Mobiltelefon";"Fax";"Straße";"PLZ";"Ort";"L.";"E-Mail";"M1L";"QVM";"QLM";"QualVolumen";"Struktur";"Umsatz";"Eigen";"Promotion";"Kunden"
"1";"08154711";"Hirsch";"Harry";"HH";"39448";"30";"0190444444";"0190111111";"0190222222";"0190333333";"Polarstr. 24";"88888";"Polarkreis";"DE";"harry@rudyhirsch.de";"5";"6";"7";"8";"9";"10";"11";"12";"13"
;;;;;;;;;;;;;;;;;;;;;;;;
"2";"47110815";"Muster";"Max";"MM";"39480";"40";"0190666666";"0190777777";"0190888888";"0190999999";"Maxstr. 99";"99999";"Bibberstadt";"DE";"max@muster.de";"14";"15";"16";"17";"18";"19";"20";"21";"22"


"Vorname" "Nachname" "Anzeigename" "Spitzname" "Primäre E-Mail" "Sekundäre E-Mail" "Tel. dienstlich" "Tel. privat" "Fax-Nummer" "Pager-Nummer" "Mobil-Tel.-Nr." "Privat: Adresse" "Privat: Adresse 2" "Privat: Stadt" "Privat: Bundesland" "Privat: PLZ" "Privat: Land" "Dienstlich: Adresse" "Dienstlich: Adresse 2" "Dienstlich: Stadt" "Dienstlich: Bundesland" "Dienstlich: PLZ" "Dienstlich: Land" "Arbeitstitel" "Abteilung" "Organisation" "Webseite 1" "Webseite 2" "Geburtsjahr" "Geburtsmonat" "Geburtstag" "Benutzerdef. 1" "Benutzerdef. 2" "Benutzerdef. 3" "Benutzerdef. 4" "Notizen"
"Harry" "Hirsch" "Harry Hirsch" "Harry Hirsch" "harry@rudyhirsch.de" "0190111111" "0190444444" "0190333333" "0190222222" "Polarstr. 24" "Polarkkreis" "888888" "DE" "08154711" "39448" "1" "30 – 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 – 13"
"Max" "Muster" "Max Muster" "Max Muster" "max@muster.de" "0190777777" "0190666666" "0190999999" "0190888888" "Maxstr. 99" "Bibberstadt" "999999" "DE" "47110815" "39480" "2" "40 - 14 - 15 - 16 - 17 - 18 - 19 - 20 - 21 – 22"
bastla
bastla 08.03.2009 um 17:04:08 Uhr
Goto Top
Hallo Vasili!
Beim Einfügen hier sind die Tabs wohl verschwunden und durch Leerzeichen ersetzt worden
Deswegen der Hinweis auf eine passende (empfehlenswert: type="plain") ...

Grüße
bastla
Biber
Biber 08.03.2009 um 18:48:05 Uhr
Goto Top
Uuuups,

jetzt war ich nur mal kurz an der Weser spazieren und schon ist es hier einen halben Meter lang weitergegangen...

Okay, ich poste jetzt noch mal (ohne auf die beiden anderen Lösungswege einzugehen), wie ich herangehen würde.

Ausgangsüberlegung wäre für mich bei dieser Aufgabe, dass es weniger auf Kürze und Eleganz ankommt, sondern auf die Nachvollziehbarkeit und die Wartbarkeit auch durch einen ungeübteren Batchanwender.
Also würde ich doch erst mal die beiden Formate in einem "Schritt 0" per Batch aufdröseln lassen.

Das Ergebnis mit den beiden o.a. out.csv und gruppen.csv sieht so aus (wenn das Trennzeichen in der Gruppen.csv ein TAB wäre).

@echo off & setlocal
:: Header der out.csv in Variablen einlesen 
Set /p outcsvFlds=<out.csv
FOR /F "delims=; tokens=1-25" %%a in ("%outcsvFlds%") do (  
   Set "ocF_01=%%a"  & Set "ocF_02=%%b"   & Set "ocF_03=%%c"     
   Set "ocF_04=%%d"  & Set "ocF_05=%%e"   & Set "ocF_06=%%f"     
   Set "ocF_07=%%g"  & Set "ocF_08=%%h"   & Set "ocF_09=%%i"     
   Set "ocF_10=%%j"  & Set "ocF_11=%%k"   & Set "ocF_12=%%l"  
   Set "ocF_13=%%m"  & Set "ocF_14=%%n"   & Set "ocF_15=%%o"     
   Set "ocF_16=%%p"  & Set "ocF_17=%%q"   & Set "ocF_18=%%r"     
   Set "ocF_19=%%s"  & Set "ocF_20=%%t"   & Set "ocF_21=%%u"     
   Set "ocF_22=%%v"  & Set "ocF_23=%%w"   & Set "ocF_24=%%x"     
   Set "ocF_25=%%y"    
)   

:: Header der gruppen.csv in Variablen einlesen 
:: -------- Delims ist ein TAB
Set /p grpcsvFlds=<gruppen.csv

FOR /F "delims=	 tokens=1-25" %%a in ("%grpcsvFlds%") do (  
   Set "gcF_01=%%a"  & Set "gcF_02=%%b"   & Set "gcF_03=%%c"     
   Set "gcF_04=%%d"  & Set "gcF_05=%%e"   & Set "gcF_06=%%f"     
   Set "gcF_07=%%g"  & Set "gcF_08=%%h"   & Set "gcF_09=%%i"     
   Set "gcF_10=%%j"  & Set "gcF_11=%%k"   & Set "gcF_12=%%l"  
   Set "gcF_13=%%m"  & Set "gcF_14=%%n"   & Set "gcF_15=%%o"     
   Set "gcF_16=%%p"  & Set "gcF_17=%%q"   & Set "gcF_18=%%r"     
   Set "gcF_19=%%s"  & Set "gcF_20=%%t"   & Set "gcF_21=%%u"     
   Set "gcF_22=%%v"  & Set "gcF_23=%%w"   & Set "gcF_24=%%x"     
   Set "gcF_25=%%y"    
)   

:: Datenzeilen der out.csv in Variablen einlesen 
:: ---Delimiter ist hier das Semikolon      
FOR /F "delims=; tokens=1-25" %%a in (out.csv) do (  

 (echo %ocF_01%: [%%a]) & (Echo %ocF_02%: [%%b]) & (echo %ocF_03%: [%%c])
 (Echo %ocF_04%: [%%d]) & (Echo %ocF_05%: [%%e]) & (Echo %ocF_06%: [%%f])
 (Echo %ocF_07%: [%%g]) & (Echo %ocF_08%: [%%h]) & (Echo %ocF_09%: [%%i])
 (Echo %ocF_10%: [%%j]) & (Echo %ocF_11%: [%%k]) & (Echo %ocF_12%: [%%l])
 (Echo %ocF_13%: [%%m]) & (Echo %ocF_14%: [%%n]) & (Echo %ocF_15%: [%%o])
 (Echo %ocF_16%: [%%p]) & (Echo %ocF_17%: [%%q]) & (Echo %ocF_18%: [%%r])
 (Echo %ocF_19%: [%%s]) & (Echo %ocF_20%: [%%t]) & (Echo %ocF_21%: [%%u])
 (Echo %ocF_22%: [%%v]) & (Echo %ocF_23%: [%%w]) & (Echo %ocF_24%: [%%x])
 (Echo %ocF_25%: [%%y])
)

:: -------- als nächstes die Datenzeilen der Gruppen.csv
:: -------- Delimiter ist hier ein TAB      
FOR /F "delims=	 tokens=1-25" %%a in (gruppen.csv) do (  

 (echo %gcF_01%: [%%a]) & (Echo %gcF_02%: [%%b]) & (echo %gcF_03%: [%%c])
 (Echo %gcF_04%: [%%d]) & (Echo %gcF_05%: [%%e]) & (Echo %gcF_06%: [%%f])
 (Echo %gcF_07%: [%%g]) & (Echo %gcF_08%: [%%h]) & (Echo %gcF_09%: [%%i])
 (Echo %gcF_10%: [%%j]) & (Echo %gcF_11%: [%%k]) & (Echo %gcF_12%: [%%l])
 (Echo %gcF_13%: [%%m]) & (Echo %gcF_14%: [%%n]) & (Echo %gcF_15%: [%%o])
 (Echo %gcF_16%: [%%p]) & (Echo %gcF_17%: [%%q]) & (Echo %gcF_18%: [%%r])
 (Echo %gcF_19%: [%%s]) & (Echo %gcF_20%: [%%t]) & (Echo %gcF_21%: [%%u])
 (Echo %gcF_22%: [%%v]) & (Echo %gcF_23%: [%%w]) & (Echo %gcF_24%: [%%x])
 (Echo %gcF_25%: [%%y])
)
Nach diesem Klärungsschritt
  • lassen sich beide Format erstmal stressfrei lesen

Beispiel "Max Muster" in der out.csv...

...
L: [2]
TPNr: [47110815]
Name: [Muster]
Vorname: [Max]
Firma: [MM]
Angelegt: [02.02.2008]
L.Ums.: [40]
Tel.Privat: [0190666666]
Tel.Gesch.: [0190777777]
Mobiltelefon: [0190888888]
Fax: [0190999999]
Straße: [Maxstr. 99]
PLZ: [999999]
Ort: [Bibberstadt]
L.: [DE]
E-Mail: [max@muster.de]
M1L: [14]
QVM: [15]
QLM: [16]
QualVolumen: [17]
Struktur: [18]
Umsatz: [19]
Eigen: [20]
Promotion: [21]
Kunden: [22]
...versus Max Muster in der Gruppen.csv.
...
Vorname: [Max]
Nachname: [Muster]

Spitzname: [Max Muster ]
Primäre E-Mail: [max@muster.de ]
Sekundäre E-Mail: [0190777777]
Tel. dienstlich: [0190666666]
Tel. privat: [0190999999]
Fax-Nummer: [0190888888]
Pager-Nummer: [Maxstr. 99]
Mobil-Tel.-Nr.: [Bibberstadt]
Privat: Adresse: [999999]
Privat: Adresse 2: [DE]
Privat: Stadt: [47110815]
Privat: Bundesland: [02.02.2008]
Privat: PLZ: [2]
Privat: Land: [40]
Dienstlich: Adresse: [ - 14 - ]
Dienstlich: Adresse 2: [15 - ]
Dienstlich: Stadt: [16 - ]
Dienstlich: Bundesland: [17]
Dienstlich: PLZ: [ - 18 - ]
Dienstlich: Land: [19 - ]
Arbeitstitel: [20 - ]
Abteilung: [21 - ]

Der einzige noch nötige Schritt wäre,
  • FOR-Anweisungen 1 und 2 (Header out.csv und Header gruppen.csv) zu lassen wie sie sind.
  • FOR Anweisung 4 zu löschen oder davor ein goto :eof zu setzen
  • In FOR-Anweisung 3 statt der Ausgabe einzelner Felder pro Zeile eine ganze Zeile im gruppen.csv-Format zu ECHOen - vorzugsweise in eine neue .CSV-Datei.

Wenn bei diesem letzten Schritt z.B. die out-Variablen %ocF_03% ="Name" und %ocF_04% "Vorname" zusammengestöpselt werden sollen zu einem gruppen.csv-Feld %gcF_03%="Anzeigename", dann wäre eben die Teil-Anweisung an dieser Stelle:

echo ....... %vTab%%ocF_04% %ocF_03%%vtab%....... >>neuegruppen.csv

Unterstellt habe ich, dass in %vTab% ein TAB-Zeichen definiert wurde (Set "vTab={Tab-Taste}") .
Natürlich wäre auch ein expliziter Zwieschenschritt (den gcF_-Variablen erst den "richtigen" Inhalt der ocF_Variablen zuordnen möglich, wenn es der Übersicht dient.

Anzumerken ist nur noch, dass VOLLKOMMEN leere Sätze in der out.csv (also nur Semikola) von allein rausfallen bei meiner Mimik. (Rechts der FOR-Anweisung kommt nix an, keine Verarbeitung. As should do...)

Grüße
Biber
[Edit] Source um ein paar Kommentare ergänzt. [/Edit]
76109
76109 08.03.2009 um 19:17:43 Uhr
Goto Top
Hallo!

So geht's auch:
Option Explicit

Dim FileObj As New FileSystemObject 'VB-Editor Verweis include <Microsoft Scripting Runtime>  

Private Sub Workbook_Open()
    Call ConvertFile
    'ThisWorkbook.Close SaveChanges:=False  
End Sub

Function ConvertFile()
    Dim ix, ex, en, iPath As String, ePath As String
    Dim iFile As TextStream, eFile As TextStream
    
    On Error Resume Next
        
    iPath = ThisWorkbook.Path & "\pm.csv"  
    ePath = ThisWorkbook.Path & "\gruppe.csv"  
    
    en = Array("Vorname", "Nachname", "Anzeigename", "Spitzname", "Primäre E-Mail", _  
               "Sekundäre E-Mail", "Tel. dienstlich", "Tel. privat", "Fax-Nummer", _  
               "Pager-Nummer", "Mobil-Tel.-Nr.", "Privat: Adresse", "Privat: Adresse 2", _  
               "Privat: Stadt", "Privat: Bundesland", "Privat: PLZ", "Privat: Land", _  
               "Dienstlich: Adresse", "Dienstlich: Adresse 2", "Dienstlich: Stadt", _  
               "Dienstlich: Bundesland", "Dienstlich: PLZ", "Dienstlich: Land", _  
               "Arbeitstitel", "Abteilung", "Organisation", "Webseite 1", "Webseite 2", _  
               "Geburtsjahr", "Geburtsmonat", "Geburtstag", "Benutzerdef. 1", _  
               "Benutzerdef. 2", "Benutzerdef. 3", "Benutzerdef. 4", "Notizen")  
    
    
    Set iFile = FileObj.OpenTextFile(iPath)
    Set eFile = FileObj.CreateTextFile(ePath, True)
    
    If Err Then MsgBox "Datei nicht gefunden.", 48, "Fehler":  GoTo Ende  
    
    eFile.WriteLine Join(en, vbTab)
    iFile.SkipLine
    
    Do While iFile.AtEndOfStream = False
        ix = Split(iFile.ReadLine, ";")  
        If Not ix(0) = "" Then  
            ex = Array(ix(3), ix(2), ix(3) & ix(2), ix(3) & ix(2), ix(15), "", ix(8), _  
                       ix(7), ix(10), "", ix(9), ix(11), "", ix(13), "", ix(12), ix(14))  
            eFile.WriteLine Join(ex, vbTab)
        End If
    Loop
        
Ende:
    iFile.Close
    eFile.Close
    'Kill iPath 'Import-Datei löschen  
End Function



[Edit Biber] Habe den Code mal in Code-Tags gesetzt - sonst sieht noch mein Batch professioneller aus als dieser VBA-Schnipsel. *gg [/Edit}
bastla
bastla 08.03.2009 um 19:23:02 Uhr
Goto Top
@76109

Sieht gut aus face-smile ...

... nur bräuchtest Du dafür kein Excel/VBA, sondern könntest das auch gleich über VBS erledigen (inkl. Übergabe der Pfade als Aufrufparameter) ...

Grüße
bastla
76109
76109 08.03.2009 um 19:44:43 Uhr
Goto Top
Kommentar zwecks Übersicht entfernt!
76109
76109 08.03.2009 um 19:48:15 Uhr
Goto Top
Kommentar zwecks Übersicht entfernt!
Biber
Biber 08.03.2009 um 21:10:31 Uhr
Goto Top
Moin didi1954,

danke für die Blumen.
Wo finde ich eine Zusammenstellung der Batch-Befehle? Command> Help Batch gibt's nicht.
Dann versuch es erstmal mit einem einfachen HELP (ohne den Parameter Batch) oder einem HELP CMD.

Wenn Du dort ein bisschen geschnuppert hast-> dann mal in unserem Bereich "Batch & Shell" unter "Links" einem oder zwei Links auf professionelle Tutorials folgen. Oder unsere Eigenbau-Tutorials im gleichen Bereich anschauen.

Oder auch in den "Batch & Shell"-Beiträgen stöbern - insbesondere in denen, die irgendwann mal einen "Gelöst"-Haken bekommen haben.

Grüße
Biber
bastla
bastla 08.03.2009 um 21:14:30 Uhr
Goto Top
Hallo didi1954!
Du meinst wohl VB-Script. Oder?
Yep. Sieht eigentlich kaum anders aus als VBA:
Option Explicit

Dim ix, ex, en, iPath, ePath
Dim FileObj, iFile, eFile
Set FileObj = CreateObject("Scripting.FileSystemObject")  
    
'On Error Resume Next  
        
iPath = WScript.Arguments(0)
ePath = WScript.Arguments(1)
    
en = Array("Vorname", "Nachname", "Anzeigename", "Spitzname", "Primäre E-Mail", _  
           "Sekundäre E-Mail", "Tel. dienstlich", "Tel. privat", "Fax-Nummer", _  
           "Pager-Nummer", "Mobil-Tel.-Nr.", "Privat: Adresse", "Privat: Adresse 2", _  
           "Privat: Stadt", "Privat: Bundesland", "Privat: PLZ", "Privat: Land", _  
           "Dienstlich: Adresse", "Dienstlich: Adresse 2", "Dienstlich: Stadt", _  
           "Dienstlich: Bundesland", "Dienstlich: PLZ", "Dienstlich: Land", _  
           "Arbeitstitel", "Abteilung", "Organisation", "Webseite 1", "Webseite 2", _  
           "Geburtsjahr", "Geburtsmonat", "Geburtstag", "Benutzerdef. 1", _  
           "Benutzerdef. 2", "Benutzerdef. 3", "Benutzerdef. 4", "Notizen")  
    
    
Set iFile = FileObj.OpenTextFile(iPath)
Set eFile = FileObj.CreateTextFile(ePath, True)
    
If Err Then MsgBox "Datei nicht gefunden.", 48, "Fehler":  WScript.Quit 1 'Errorlevel setzen  
    
eFile.WriteLine Join(en, vbTab)
iFile.SkipLine
    
Do While iFile.AtEndOfStream = False
    ix = Split(iFile.ReadLine, ";")  
    If Not ix(0) = "" Then  
        ex = Array(ix(3), ix(2), ix(3) & ix(2), ix(3) & ix(2), ix(15), "", ix(8), _  
                   ix(7), ix(10), "", ix(9), ix(11), "", ix(13), "", ix(12), ix(14))  
        eFile.WriteLine Join(ex, vbTab)
    End If
Loop
        
iFile.Close
eFile.Close
'FileObj.DeleteFile iPath 'Import-Datei löschen  
Aufzurufen wäre das Script dann etwa so:
cscript //nologo C:\Scripts\ConvertCSV.vbs "D:\Ein-Pfad\pm.csv" "D:\Aus-Pfad\gruppe.csv"
wobei das "cscript / /nologo", v.a. bei Verwendung in einem Batch, dafür sorgt, dass die Konsolenversion des Interpreters verwendet wird - wenn Du es weg lässt, wird (defaultmäßig) "wscript.exe" verwendet, was in diesem konkreten Fall egal wäre.

Anmerkungen zum Code:
  • VBS lässt nur Deklarationen ohne Typ zu.
  • Parameter werden über "WScript.Arguments()" mit 0-basiertem Index übernommen.
  • "Sub" und "Function" gibt es, der Code muss aber nicht in einem "Sub" stehen.

Nachzulesen ist das Ganze am besten offline in der entsprechenden Doku "script56.chm" (gibt's auch in einer deutschen Fassung, zB bei dieseyer.de).
Ansonsten noch ein Hinweis: "On Error Resume Next" wäre mir bei dieser Aufgabenstellung zu riskant ...

Grüße
bastla
76109
76109 08.03.2009 um 21:19:33 Uhr
Goto Top
Kommentar zwecks Übersicht entfernt!
Biber
Biber 08.03.2009 um 21:47:18 Uhr
Goto Top
Moin didi1954,
Zitat von @76109:
Aber die Sache mit der Schlagbohrmaschine nehme ich dennoch persönlich.

Gruß Dieter
Ach was, das solltest Du nicht.
Es nimmt ja jeder von uns immer seine Lieblingstools oder Lieblingsküchenmesser, selbst wenn der Werkzeugkasten (respektive die Einbauküche) voll mit dem neuen bunten Schnickschnack aus der Funk- und Fernsehwerbung ist.

Ich versuche ja nur zu zeigen, dass es nicht ausschließlich auf die Möglichkeiten der Werkzeugs ankommt, sondern auch ein bisschen darauf ankommt, wie man/frau damit umgeht.

Aber ich bin mir Grenzen von Batchen durchaus bewusst - und ich würde auch umgekehrt nicht versuchen, mit einem Vorschlaghammer einen Zylinderkopf plan zu schleifen.
Obwohl... eigentlich müsste es gehen...*grübel*

Grüße
Biber
Vasili
Vasili 09.03.2009 um 04:01:34 Uhr
Goto Top
Danke, das Visual Basic Script hat mir letzt endlich weiter geholfen.
Hatte es noch etwas angepasst.
Nur verschwindet immer der erste Eintrag in der Liste.
Also erste Adresszeile kommt in der 2. nicht an.

Bei dem Batch kam ich nicht weiter, da keine Datei ausgegeben wurde, nur am Bildschirm.
Hier hat das modifizieren geklappt, habe noch nie VBS oder änliches bearbeitet.
Beim VB kamen bei der Ausführung Fehler und mit diesem und einem Start Batch geht es wunderbar.

Hier der verwendete Code:

Option Explicit

Dim ix, ex, en, iPath, ePath
Dim FileObj, iFile, eFile
Set FileObj = CreateObject("Scripting.FileSystemObject")

'On Error Resume Next

iPath = WScript.Arguments(0)
ePath = WScript.Arguments(1)

en = Array("Vorname", "Nachname", "Anzeigename", "Spitzname", _
"Primäre E-Mail", "Sekundäre E-Mail", "Tel. dienstlich", "Tel. privat", _
"Fax-Nummer", "Pager-Nummer", "Mobil-Tel.-Nr.", "Privat: Adresse", _
"Privat: Adresse 2", "Privat: Stadt", "Privat: Bundesland", "Privat: PLZ", _
"Privat: Land", "Dienstlich: Adresse", "Dienstlich: Adresse 2", "Dienstlich: Stadt", _
"Dienstlich: Bundesland", "Dienstlich: PLZ", "Dienstlich: Land", "Arbeitstitel", _
"Abteilung", "Organisation", "Webseite 1", "Webseite 2", _
"Geburtsjahr", "Geburtsmonat", "Geburtstag", "Benutzerdef. 1", _
"Benutzerdef. 2", "Benutzerdef. 3", "Benutzerdef. 4", "Notizen")


Set iFile = FileObj.OpenTextFile(iPath)
Set eFile = FileObj.CreateTextFile(ePath, True)

If Err Then MsgBox "Datei nicht gefunden.", 48, "Fehler": WScript.Quit 1 'Errorlevel setzen

eFile.WriteLine Join(en, vbTab)
iFile.SkipLine

Do While iFile.AtEndOfStream = False
ix = Split(iFile.ReadLine, ";")
If Not ix(0) = "" Then
ex = Array(ix(3), ix(2), ix(3) & " " & ix(2), ix(3) & " " & ix(2), _
ix(15), "", ix(8), ix(7), _
ix(10), "", ix(9), ix(11), _
"", ix(13), "", ix(12), _
ix(14), "", "", "", _
"", "", "", "", _
"", ix(4), "", "", _
"", "", "", ix(1), _
"", ix(0), ix(5), _
ix(6) & " - " & ix(16) & " - " & ix(17) & " - " & ix(18) & " - " _
& ix(19) & " - " & ix(20) & " - " & ix(21) & " - " & ix(22) & _
" - " & ix(23) & " - " & ix(24))
eFile.WriteLine Join(ex, vbTab)
End If
Loop

iFile.Close
eFile.Close
'FileObj.DeleteFile iPath 'Import-Datei löschen
bastla
bastla 09.03.2009 um 07:07:15 Uhr
Goto Top
Hallo Vasili!

Setze testweise vor die Zeile 29 ein "REM", also:
REM iFile.SkipLine
Bibers Batch war als "Hilfe zur Selbsthilfe" gedacht - das Schreiben in eine Datei war darin noch nicht vorgesehen, bedürfte aber nur einer kleinen Ergänzung der Art:
>>D:\Aus-Pfad\gruppe.csv
nach der letzten Klammer ...
Ansonsten nochmals die Bitte, beim Posten von Scripts, Dateiinhalten, etc so zu formatieren:
< code>
...
< /code>
wobei die Leerzeichen nach dem "<" jeweils weg zu lassen sind.

Grüße
bastla
Biber
Biber 09.03.2009 um 07:55:05 Uhr
Goto Top
Moin Vasili,
Bei dem Batch kam ich nicht weiter, da keine Datei ausgegeben wurde, nur am Bildschirm.
Sorry, der Beispielschnipsel sollte nur eine Skizze sein, die Dir ermöglicht, auch ohne tiefergehende Einarbeitung in das Thema Batch die erforderlichen Anpassssungen vorzunehmen. Damit Du Deine CSV-Konvertierung auch später selbst pflegen und warten (oder einfacher ausgedrückt: nachvollziehen und verstehen) kannst.

Möglicherweise muss ich an meinen Formulierungen noch ein bisschen arbeiten...

Aber -wie ich auch schon didi1954 geschrieben habe - die Wahl des Werkzeugs ist auch relativ beliebig.
Wenn Du die VBA/VBS-Varianten nachvollziehbar und lesbar findest und nach Deinen Bedürfnissen anpassen kannst, dann ist es doch auch gut.

Grüße
Biber
Vasili
Vasili 09.03.2009 um 15:44:35 Uhr
Goto Top
Mit dem REM vor die Skipline hatte nur zur Folge, dass die Kopfzeile mit den Original Feldnamen an 2. Stelle stand und die 2. Zeile vom Original auch weiterhin fehlt.
Wobei zu bemerken ist, das in dem ersten Datensatz (Zeile) ist das erste Feld leer, es sollte eigentlich den Wert 0 haben.

Weiteres Optimierung, damit ich nach Import nicht nach Dubletten suchen muss.

Ansonsten gibt es viele Duplikate, da manche Adressen wegen Gruppierungen mehrfach vorkommen.

Wie sieht es mit der Möglichkeit aus zu sortieren um dann die Dubletten zu eliminieren.

Muss man dann die Ausgabedatei erneut einlesen?

Danke noch einmal.
76109
76109 09.03.2009 um 15:50:10 Uhr
Goto Top
Hallo Vasili,

In der ersten Zeilen der Import-Datei die Feld- oder Spaltennamen überspringen.

SkipLine = eine Zeile überspringen.

Gruß Dieter
76109
76109 09.03.2009 um 16:09:28 Uhr
Goto Top
Hallo Vasili,

Den Original-Code in Excel getestet funkioniert.

Gruppe.csv

Zeile 1 = Vorname TAB Nachnahme TAB...
Zeile 2 = Harry TAB Hirsch TAB...
Zeile 3 = Max TAB Muster TAB...

Gruß Dieter
bastla
bastla 09.03.2009 um 16:24:12 Uhr
Goto Top
Hallo Vasilil!

Das "REM" war nur ein Versuch, da ich eine Originaldatei und vor allem die folgende Information nicht hatte:
Wobei zu bemerken ist, das in dem ersten Datensatz (Zeile) ist das erste Feld leer, es sollte eigentlich den Wert 0 haben.
Da im Script zur Verhinderung einer nur aus ";" bestehenden Zeile abgefragt wird, ob das erste Feld leer ist, wird natürlich ein derartiger Datensatz übersprungen. Um das zu unterbinden, könntest Du die Zeile 33 durch die folgende Zeile ersetzen:
If Trim(Join(ix)) <> "" Then
Grüße
bastla
76109
76109 09.03.2009 um 19:54:37 Uhr
Goto Top
Hallo Vasili,

Versuch bitte mal 2 Dinge:

1. Ziehe Deine Import-Datei mal in den Notpad-Editor und siehe nach ober der Text in der ersten Zeile ganz links steht.
2. Und/Oder füge folgendes in den Code ein:

ix = Split(iFile.ReadLine, ";")  
If UBound(ix) = -1 Then MsgBox "Ungültige ASCII-Zeichen..", 48, "Fehler": WScript.Quit 1 'Errorlevel setzen  
If Not ix(0) = "" Then  

Gruß Dieter
bastla
bastla 09.03.2009 um 20:19:07 Uhr
Goto Top
@76109
Sobald eine Datenzeile mit ";" beginnt, wird ix(0) leer sein und der Datensatz übersprungen werden, und für eine Leerzeile wird UBound(ix) den Wert -1 liefern ...

Beides sollte für die Variante
If Trim(Join(ix)) <> "" Then
kein Problem sein.

Grüße
bastla
76109
76109 09.03.2009 um 20:30:38 Uhr
Goto Top
Hallo Bastla,

Ja, eigentlich hast Du recht. Wollte es nur mal genau wissen.

Gruß Dieter
Vasili
Vasili 10.03.2009 um 02:06:27 Uhr
Goto Top
Danke, hatte den gewünschten Effekt gehabt.
Nun erscheint auch diese Zeile.

Hier noch ein Textschnipsel hoffentlich auch korrekt formatiert:

Do While iFile.AtEndOfStream = False
    ix = Split(iFile.ReadLine, ";")  
       If Trim(Join(ix)) <> "" Then  
        ex = Array(ix(3), ix(2), ix(3) & " " & ix(2), ix(3) & " " & ix(2), _  
                   ix(15), "", ix(8), ix(7), _  
                   ix(10), "", ix(9), ix(11), _  
                   "", ix(13), "", ix(12), _  
                   ix(14), "", "", "", _  
                   "", "", "", "", _  
                   "", ix(4), "", "", _  
                   "", "", "", ix(1), _  
                   "", (If ix(0) = "" Then "0" Else ix(0) End If), ix(5), _  
                   (If ix(6) = "-" Then "00.0000" Else ix(6) End If) & " - " & ix(16) & " - " & ix(17) & " - " & _  
                   ix(18) & " - " & ix(19) & " - " & ix(20) & " - " & _  
                   ix(21) & " - " & ix(22) & " - " & ix(23) & " - " & ix(24))  
        eFile.WriteLine Join(ex, vbTab)
    End If
Loop

Habe da noch zwei Probleme bei meiner Modifikation:
Mache jeweilsa eine If abfrage, ob leehr, dann eine 0 einfügen beim Felf ix(0)
und ebenso beim Feld ix(6) wenn dort anstatt einer Zahl wie Bsp. 01.2009 im
Ouellfeld nur ein - Bindestrich steht würde ich es gerne durch 00.000 ersetzten, dies klappt so aber nicht.

Was mache ich da falsch?!?
Vasili
Vasili 10.03.2009 um 02:16:54 Uhr
Goto Top
Hallo Bastla,

hat wunderbar geklappt.

Jetzt nur noch paar Feinheiten, habe es gerade gepostet.
Meine OIf Konstruktionen zum Korrigieren funktionieren leider überhaupt nicht.

Und da wäre noch das Dubletten-Problem, dass das Ausgabeprogramm vereinzelte Adressen da in Gruppen und Alphabetisch sortiert ist, diese mehrfach vorkommen.
Ca 10% kommen doppelt vor. Sind aber komplett identisch.

Grüße,
Vasili
bastla
bastla 10.03.2009 um 10:00:42 Uhr
Goto Top
Hallo Vasili!

Die Zeilen 4 bis 15 (Deines geposteten Schnipsesl - danke übrigens für die Formatierung face-smile) sollten eine Einheit (zu erkennen an den "_" am Ende) bilden und dürfen nicht unterbrochen werden, daher bereits vorher die Inhalte der Felder 0 und 6 anpassen:
Do While iFile.AtEndOfStream = False
    ix = Split(iFile.ReadLine, ";")  
    If Trim(Join(ix)) <> "" Then  
        If ix(0) = "" Then ix(0) = "0"  
        If ix(6) = "-" Then ix(6) = "00.0000"  
        ex = Array(ix(3), ix(2), ix(3) & " " & ix(2), ix(3) & " " & ix(2), _  
                   ix(15), "", ix(8), ix(7), _  
                   ix(10), "", ix(9), ix(11), _  
                   "", ix(13), "", ix(12), _  
                   ix(14), "", "", "", _  
                   "", "", "", "", _  
                   "", ix(4), "", "", _  
                   "", "", "", ix(1), _  
                   "", ix(0), ix(5), _  
                   ix(6) & " - " & ix(16) & " - " & ix(17) & " - " & ix(18) & " - " _  
                   & ix(19) & " - " & ix(20) & " - " & ix(21) & " - " & ix(22) & _  
                   " - " & ix(23) & " - " & ix(24))  
        eFile.WriteLine Join(ex, vbTab)
    End If
Loop
Hinsichtlich Sortierung bzw Duplikatsuche (und -entfernung):
  • Nach welchen Kriterien soll die Sortierung erfolgen?
  • Woran sind Duplikate zu erkennen (gesamter Satz identisch, nur zB gleiche Namen, Unterschiede Groß-/Kleinschreibung beachten)?

Beim Entfernen der doppelten Sätze könnte es sinnvoll sein, die entfernten Zeilen bis zum nächsten Durchlauf des Scripts in einer Protokolldatei zu speichern (besonders, wenn auch nicht in allen Feldern gleiche Sätze als "doppelt" angesehen werden können) - so gehen diese nicht sofort verloren.

Grüße
bastla
76109
76109 10.03.2009 um 16:17:52 Uhr
Goto Top
Hallo Zusammen,

Die sache mit der If-Anweisung im Array hat "bastla" ja schon geklärt.

Was die Dupletten und Sortierung angeht, vermute ich doch mal nach Namen. Oder?

Ich versuche mal in Schritt 1 erst die Dupletten mit "" zu kenzeichnen.

Dabei dachte ich daran, die gesamte Import-Datei in ein Array einzulesen und dann in einer Doppelschleife

Zeile1: ab Zeile 2 bis Ende Suchen/Vergleichen und mit "" kennzeichnen
Zeile2: ab Zeile 3 bis Ende Suchen/Vergleichen und mit "" kennzeichnen
usw.

Beim Vergleich, denke ich an Like-Operator, der Klein/Großschreibung nicht unterscheidet und zudem Jokerzeichen erlaubt.

Oder was meinst Du bastla?

Gruß Dieter
bastla
bastla 10.03.2009, aktualisiert am 18.10.2012 um 18:37:51 Uhr
Goto Top
Hallo didi1954!

Array: ja (oder "Disconnected Recordset" - Links dazu findest Du zB hier)

Wenn ohnehin auch sortiert werden soll, würde ich das zuerst erledigen - dann müssen nur mehr jeweils zwei aufeinander folgende Zeilen verglichen werden.

Grüße
bastla
76109
76109 10.03.2009 um 16:33:39 Uhr
Goto Top
Hallo bastla,

OK, das mit dem "Disconnected Recordset" schaue ich mir an.

Und ja stimmt, erst sortieren. Aber es können ja auch mehr als zwei Einträge gleich sein. Denke ich mal!

Aha, 10 % habe ich gerade weiter unten gelesen.

Gruß Dieter
bastla
bastla 10.03.2009 um 17:32:50 Uhr
Goto Top
Hallo didi1954!
Aber es können ja auch mehr als zwei Einträge gleich sein.
Die Strategie ist einfach: Behalte einen Eintrag, wenn er sich vom vorhergehenden unterscheidet - bei 5 gleichen Einträgen trifft dies nur auf den ersten zu ...

Grüße
bastla
76109
76109 10.03.2009 um 18:55:24 Uhr
Goto Top
Hallo bastla,

OK, Danke!

Ich hab's kapiert.

Aber mit dem ADO "Disconnected Recordset" bin ich im Moment etwas überfordert.

Weiß nicht, ob Vasili solange warten will, bis ich mir die Kenntnisse alle angeeignet habe.

Das mit dem VB-Recordset kriege ich noch hin, aber wie ich damit arbeite, muss ich erst noch rauskriegen.

Gruß Dieter

PS. Ich bin kein Profi und hätte daher auch nichts dagegen, wenn Du eine effiziente Lösung anbietest.
bastla
bastla 10.03.2009 um 22:52:09 Uhr
Goto Top
Hallo didi1954!

Profi bin ich auch nicht, und über die "Effizienz" lässt sich sicher diskutieren, aber einen Lösungsansatz kann ich anbieten:
Option Explicit

Dim ix, ex, en, iPath, ePath, aPath
Dim FileObj, iFile, eFile, aFile
Dim DataList, LastLine, ThisLine
Set FileObj = CreateObject("Scripting.FileSystemObject")  

iPath = WScript.Arguments(0) 'Eingabedatei  
ePath = WScript.Arguments(1) 'Ausgabedatei  
aPath = WScript.Arguments(2) 'Datei für ausgeschiedene Zeilen  

en = Array("Vorname", "Nachname", "Anzeigename", "Spitzname", _  
           "Primäre E-Mail", "Sekundäre E-Mail", "Tel. dienstlich", "Tel. privat", _  
           "Fax-Nummer", "Pager-Nummer", "Mobil-Tel.-Nr.", "Privat: Adresse", _  
           "Privat: Adresse 2", "Privat: Stadt", "Privat: Bundesland", "Privat: PLZ", _  
           "Privat: Land", "Dienstlich: Adresse", "Dienstlich: Adresse 2", "Dienstlich: Stadt", _  
           "Dienstlich: Bundesland", "Dienstlich: PLZ", "Dienstlich: Land", "Arbeitstitel", _  
           "Abteilung", "Organisation", "Webseite 1", "Webseite 2", _  
           "Geburtsjahr", "Geburtsmonat", "Geburtstag", "Benutzerdef. 1", _  
           "Benutzerdef. 2", "Benutzerdef. 3", "Benutzerdef. 4", "Notizen")  

Set iFile = FileObj.OpenTextFile(iPath)
If Err Then MsgBox "Datei nicht gefunden.", 48, "Fehler": WScript.Quit 1 'Errorlevel setzen  

'Datenbank erzeugen und öffnen  
Const adVarChar = 200
Const adFldIsNullable = 32
Const adInteger = 3

Set DataList = CreateObject("ADOR.Recordset")  
DataList.Fields.Append "Name", adVarChar, 64, adFldIsNullable     'Feldgröße (64 Zeichen) für "Nachname"+"Vorname" bei Bedarf anpassen  
DataList.Fields.Append "Zeile", adVarChar, 1024, adFldIsNullable  'Feldgröße (1024 Zeichen) für gesamte Ausgabezeile  
DataList.Open

'Bis auf die erste Zeile alle weiteren Zeilen aus CSV lesen und konvertieren  
iFile.SkipLine
Do While iFile.AtEndOfStream = False
    ix = Split(iFile.ReadLine, ";")  
    If Trim(Join(ix)) <> "" Then  
        If ix(0) = "" Then ix(0) = "0"  
        If ix(6) = "-" Then ix(6) = "00.0000"  
        'Neue Ausgabezeile erstellen  
        ex = Array(ix(3), ix(2), ix(3) & " " & ix(2), ix(3) & " " & ix(2), _  
                   ix(15), "", ix(8), ix(7), _  
                   ix(10), "", ix(9), ix(11), _  
                   "", ix(13), "", ix(12), _  
                   ix(14), "", "", "", _  
                   "", "", "", "", _  
                   "", ix(4), "", "", _  
                   "", "", "", ix(1), _  
                   "", ix(0), ix(5), _  
                   ix(6) & " - " & ix(16) & " - " & ix(17) & " - " & ix(18) & " - " _  
                   & ix(19) & " - " & ix(20) & " - " & ix(21) & " - " & ix(22) & _  
                   " - " & ix(23) & " - " & ix(24))  
        'Satz in Datenbank schreiben  
        DataList.AddNew
        DataList("Name") = LCase(ix(3) & " " & ix(2)) 'Sortierkriterium = Anzeigename (in Kleinbuchstaben)  
        DataList("Zeile") = Join(ex, vbTab)     'gesamte Ausgabezeile  
        DataList.Update
    End If
Loop
iFile.Close

'Ausgabedatei erzeugen und Kopfzeile schreiben  
Set eFile = FileObj.CreateTextFile(ePath, True)
eFile.WriteLine Join(en, vbTab)

'Datei für ausgeschiedene Zeilen erzeugen und Kopfzeile schreiben  
Set aFile = FileObj.CreateTextFile(aPath, True)
aFile.WriteLine Join(en, vbTab)

LastLine = "" 'Initialisierung "letzte geschriebene Zeile"  
DataList.Sort = "Name" 'Datenbank nach Feld "Name" sortieren  
DataList.MoveFirst 'zum ersten Datensatz  
Do Until DataList.EOF 'Schleife über alle Datensätze  
    ThisLine = DataList.Fields.Item("Zeile") 'Ausgabezeile aus Datenbank lesen  
    'Vergleich der gesamten Zeile ohne Berücksichtigung von Groß-/Kleinschreibung  
    If LCase(ThisLine) <> LCase(LastLine) Then 
        eFile.WriteLine ThisLine 'kein Duplikat - Zeile in Ausgabedatei schreiben  
        LastLine = ThisLine 'geschriebene Zeile merken  
    Else 'Duplikat gefunden  
        aFile.WriteLine ThisLine 'ausgeschiedene Zeile schreiben  
    End If
    DataList.MoveNext 'zum nächsten Datensatz  
Loop
eFile.Close
aFile.Close
'FileObj.DeleteFile iPath 'Import-Datei löschen  
Wie schon erwähnt halte ich es für sinnvoll, die ausgeschiedenen Zeilen (Duplikate) in einer Datei zu sammeln - diese ist als zusätzlicher Aufrufparameter anzugeben, daher also Start des Scripts zB so:
cscript //nologo C:\Scripts\ConvertCSV.vbs "D:\Ein-Pfad\pm.csv" "D:\Aus-Pfad\gruppe.csv" "D:\Aus-Pfad\ausgeschieden.csv"
Grüße
bastla

[Edit] Sortierkriterium auf "Anzeigename" = ix(3) & " " & ix(2) geändert [/Edit]
Biber
Biber 10.03.2009 um 23:13:31 Uhr
Goto Top
Moin bastla,

aus sportlichen Gründen spiele ich ja schon mit dem Gedanken, das Ganze (noch) mal funktional in Batch nachzubilden - eigentlich nur um zu überprüfen, ob denn da mehr oder weniger Zeilen rauskommen.
[ Gemeint sind natürlich lesbare/wartbare Zeilen, also keine drei FOR-Anweisungen hintereinander in einer 1867 Zeichen langen Zeile.]

Andererseits.... wenn es doch jetzt so langsam der End-Abnahme entgegenstrebt, sollte das ja auch reichen.

Ist jedenfalls sehr unterhaltsam, hier mitzulesen.

Grüße
Biber
bastla
bastla 10.03.2009 um 23:25:04 Uhr
Goto Top
@Biber
Sollte (wie fast immer) in Batch kürzer gehen (alleine beim Sortieren kannst Du schon eine Menge Zeilen einsparen) ...

Ist jedenfalls sehr unterhaltsam, hier mitzulesen.
... aber schon fast schwierig, den richtigen "Strang" zu finden.

Grüße
bastla
Vasili
Vasili 11.03.2009 um 12:34:37 Uhr
Goto Top
Hallo Basta,

danke für die Mühe und den Tipp zum Text-Formatieren hier zum Posten.
Habe aber paar Minuten gebraucht, bis ich es kapiert hatte, obwohl du es gut erklärt hattest.
Bei neuen Sachen glotzt man halt auch mal wie ein Auto und sieht den Wald vor lauter Bäumen nicht.
Habe im Augenblick selbst wenig Zeit, so dass es Zeit hat, das wichtigste tut ja nun. Werde gleich deine Verbesserung ausprobieren.

Zu den Dubletten. Die Zeilen, bzw. Datensätze sind Identisch. Und das entfernen würde das nachträgliche entfernen mir ersparen.

Zum sortieren, nach dem Anzeigenamen soll sortiert werden.

Vielen Dank
Vasili
Vasili
Vasili 11.03.2009 um 12:47:54 Uhr
Goto Top
Hallo Zusammen, insbesondere Dieter, Bastla und didi1954,

Ja ich kann warten, das wichtigste tut schon und wenn ich die Daten nicht täglich sonder wöchentlich aktualisiere dann lösche ich dies doppelten per Hand.

Grüße,
Vasili
Vasili
Vasili 11.03.2009 um 13:07:48 Uhr
Goto Top
Hallo Basta,

Danke vielmals, nach meinem ersten Test sieht alles Perfekt aus.

Vielen, dank nochmals.

Wenn mir innerhalb der nächsten Tage keine Fehler oder Probleme auftauchen dann schließe ich die Anfrage.

Grüße,
Vasili

PS.: was ist hier der Unterschied zwischen antworten und mit Zitat?
76109
76109 11.03.2009 um 16:46:43 Uhr
Goto Top
Hallo bastla,


face-smile Das sieht auch gut aus.

Ich habe da noch eine Funktion gefunden, die man zum ausfiltern verwenden könnte, wenn sie funktioniert.

nach ".Sort..." die Funktion ".AdvancedFilter..."

Deinen Code und die Filterfunktion versuche ich mal zu testen. Aber, wie auch Vasili, habe ich erst ab Freitag wieder mehr Zeit.

Grüße an bastla, Biber und Vasili

Dieter
bastla
bastla 11.03.2009 um 17:15:08 Uhr
Goto Top
Hallo Vasili!
PS.: was ist hier der Unterschied zwischen antworten und mit Zitat?
Beim Antworten "mit Zitat" wird der Kommentar, auf den geantwortet werden soll, zur Gänze als Zitat übernommen (einfach einmal ausprobieren).

Um nur einzelne Teile zu zitieren, die Zeile mit "> " (das Leerzeichen ist Absicht) beginnen und dahinter die zitierte Passage einfügen.

Grüße
bastla
Vasili
Vasili 11.03.2009 um 20:54:34 Uhr
Goto Top
Danke bastla, Dieter und all die Anderen.

Versuche es mal gleich

Um nur einzelne Teile zu zitieren, die Zeile mit "> " (das Leerzeichen ist Absicht) beginnen und dahinter die zitierte Passage einfügen.

Wenn geklappt hat, mann lernt ja nie aus. face-smile

Grüße,
Vasili
76109
76109 13.03.2009 um 12:11:17 Uhr
Goto Top
Zitat von @Biber:

Andererseits.... wenn es doch jetzt so langsam der End-Abnahme

Hallo Biber und Hallo bastla,

Nö, ein Ende ist noch nicht in Sicht.

Habe in euren Postfächern eine email-Kopie von Vasili abgelegt.

Gruß Dieter
76109
76109 18.03.2009 um 13:28:46 Uhr
Goto Top
HIER GEHT ES WEITER

Hallo,

hat ein bisschen gedauert. Die Handhabung mit den Geburtsdaten musste erst noch abgeklärt werden.
Die Suche nach Alternativen blieb bisher leider erfolglos. Dafür habe ich am 17.03. schon mal einen neuen
Programmcode entsprechend der aktuellen Gegebenheiten geschrieben. Kann aber vorweg schon sagen,
dass er noch nicht fertig ist. Es kommen noch komplexe Abgleich-Funktionen mit Thunderbird-Export hinzu.
D.h. Gruppen.Csv mit den nachträglich in Thunderbird eingefügten Einträge anhand von bestimmten
Bedingungen abzugleichen.


Aktuelle Funktion:

Daten aus den Dateien <PM-I.CSV> + <GEBURTSTAG.CSV> + <PM-DB.ADT> auslesen,
modifizieren und in Datei <GRUPPEN.CSV> schreiben

Daten-Duplikate in Datei <DUPLETTEN.CSV> schreiben


Besonderheit:

Die Datei <GEBURTSTAG.CSV> enthält immer nur aktuelle Geburtsdaten für 30 Tage
(Heute 30 Tage, Morgen 30 Tage usw.) D.h. die Geburtsdaten müssen in der Datenbank
anhand der eindeutigen TP-Nr in der Datei <PM-DB.ADT> gesammelt werden, wobei nur
noch nicht vorhandene Geburtsdaten übernommen werden. Die Daten werden anstatt im
XML im kürzeren ADTG-Format gespeichert.


Programmschritte:

1. Datenbank mit Geburtsdaten aktualisieren
2. Allgemeine Daten mit Geburtsdaten in den Recordset schreiben
3. Recordset sortiert in die Dateien <GRUPPEN.CSV> und <DUPLETTEN.CSV> exportieren.

Batch: cscript //nologo X:\Scripts\ConvertCSV.vbs

Die Batch ist nicht erforderlich, ConvertCVS kann direkt mit Doppelklick auf die Datei oder Verknüpfung gestartet werden.


Option Explicit

'Dateinamen hier festlegen  
Const GDbName = "\PM-DB.ADT"     'Export-Datei Datenbank gesammelte Geburtsdaten (Import GEBURTSTAG.CSV)  
Const DupName = "\DUPLETTEN.CSV"     'Export-Datei Duplikate (Import PM-I.CSV)  
Const ExpName = "\GRUPPEN.CSV"     'Export-Datei ohne Duplikate mit Geburtsdaten (Import PM-I.CSV + PM-DB.ADT)  
Const GebName = "\GEBURTSTAG.CSV"     'Import-Datei Geburtstage für 30 Tage  
Const ImpName = "\PM-I.CSV"     'Import-Datei Allgemeine Daten  

'ADO-Recordset  
Const adInteger = 3                 
Const adVarChar = 200
Const adOpenKeyset = 1
Const adPersistXML = 1
Const adPersistADTG = 0
Const adFldIsNullable = 32

Dim FileObj, ImpFile, ExpFile, DupFile, GebFile
Dim VbsPath, ImpPath, ExpPath, DupPath, GebPath, GDbPath
Dim ix, gx, expData, expFeld, DataList, GDbList, LastLine, ThisLine


'Main Begin  

    Set FileObj = CreateObject("Scripting.FileSystemObject")       'Bibliothek Dateifunktionen  

    VbsPath = FileObj.GetParentFolderName(Wscript.ScriptFullname)    'Dateipfad Script-Datei  


    'Dateipfad Konvertierungs-Dateien  
    GDbPath = VbsPath & GDbName
    DupPath = VbsPath & DupName
    ExpPath = VbsPath & ExpName
    GebPath = VbsPath & GebName
    ImpPath = VbsPath & ImpName

    
    'Feldnamen Export-Datei  
    expFeld = Array("Vorname", "Nachname", "Anzeigename", "Spitzname", _  
                    "Primäre E-Mail", "Sekundäre E-Mail", "Tel. dienstlich", "Tel. privat", _  
                    "Fax-Nummer", "Pager-Nummer", "Mobil-Tel.-Nr.", "Privat: Adresse", _  
                    "Privat: Adresse 2", "Privat: Stadt", "Privat: Bundesland", "Privat: PLZ", _  
                    "Privat: Land", "Dienstlich: Adresse", "Dienstlich: Adresse 2", "Dienstlich: Stadt", _  
                    "Dienstlich: Bundesland", "Dienstlich: PLZ", "Dienstlich: Land", "Arbeitstitel", _  
                    "Abteilung", "Organisation", "Webseite 1", "Webseite 2", _  
                    "Geburtsjahr", "Geburtsmonat", "Geburtstag", "Benutzerdef. 1", _  
                    "Benutzerdef. 2", "Benutzerdef. 3", "Benutzerdef. 4", "Notizen")  
    
    Call OpenGDbList      'Datenbank mit Geburtsdaten erzeugen/öffnen  
    
    'Neue Geburtsdaten in Datenbank übernehmen  
    If FileObj.FileExists(GebPath) Then    'Test ob neue Datei mit Geburtsdaten existiert  
        Set GebFile = FileObj.OpenTextFile(GebPath)  
        With GebFile    'Datei Zeilenweise einlesen und neue Daten in Datenbank schreiben  
           .SkipLine
            Do Until .AtEndOfStream
                ix = Split(.ReadLine, ";")  
                If Trim(Join(ix)) <> "" Then Call WriteGDbList  
            Loop
           .Close
        End With
        With GDbList    'Datenbank Geburtstage sortieren und speichern  
           .Sort = "TP-Nr"  
           .Save GDbPath, adPersistADTG
        End With
    End If

    Call OpenDataList    'Recordset für Allgemeine Daten erzeugen  
    
    Set ImpFile = FileObj.OpenTextFile(ImpPath)
    
    With ImpFile    'Daten einlesen und nach Export-Feldnamen sortiert in Recordset schreiben  
       .SkipLine
        Do Until .AtEndOfStream
            ix = Split(.ReadLine, ";")  
            If Trim(Join(ix)) <> "" Then  
                Call InitGebData
                If ix(0) = "" Then ix(0) = "0"  
                If ix(6) = "-" Then ix(6) = "00.0000"  
                expData = Array(ix(3), ix(2), ix(3) & " " & ix(2), ix(3) & " " & ix(2), _  
                                ix(15), "", ix(8), ix(7), ix(10), "", ix(9), ix(11), "", ix(13), "", _  
                                ix(12), ix(14), "", "", "", "", "", "", "", "", ix(4), "", "", gx(2), _  
                                gx(1), gx(0), ix(1), "", ix(0), ix(5), _  
                                ix(6) & " ; " & ix(16) & " ; " & ix(17) & " ; " & ix(18) & " ; " & _  
                                ix(19) & " ; " & ix(20) & " ; " & ix(21) & " ; " & ix(22) & " ; " & _  
                                ix(23) & " ; " & ix(24))  
                Call WriteDataList
            End If
        Loop
       .Close
    End With
    
    Set ExpFile = FileObj.CreateTextFile(ExpPath, True)
    ExpFile.WriteLine Join(expFeld, vbTab)   'Feldnamen speichern  
    
    Set DupFile = FileObj.CreateTextFile(DupPath, True)
    DupFile.WriteLine Join(expFeld, vbTab)   'Feldnamen speichern  
    
    With DataList   'Daten aus Recordset in Export-Datei und Duplikate-Datei schreiben  
        LastLine = ""  
       .Sort = "Name"  
       .MoveFirst
        Do Until DataList.EOF
            ThisLine = .Fields("Zeile")  
            If StrComp(ThisLine, LastLine, vbTextCompare) Then
                ExpFile.WriteLine ThisLine
                LastLine = ThisLine
            Else
                DupFile.WriteLine ThisLine
            End If
           .MoveNext
        Loop
    End With
    
    ExpFile.Close:  DupFile.Close:  DataList.Close:  GDbList.Close   'Objecte schließen  
    
    With FileObj
        '.DeleteFile GebPath: .DeleteFile ImpPath   'Dateien löschen  
    End With

    WScript.Quit 0 'Errorlevel setzen  

'Main End  


Private Sub OpenDataList()  'ADO-Recordset erzeugen  
    Set DataList = CreateObject("ADOR.Recordset")  
    With DataList.Fields
        .Append "Name", adVarChar, 64, adFldIsNullable  
        .Append "Zeile", adVarChar, 1024, adFldIsNullable  
         DataList.Open
    End With
End Sub

Private Sub WriteDataList() 'In ADO-Recordset schreiben  
    With DataList
        .AddNew
        .Fields("Name") = LCase(ix(3) & " " & ix(2))  
        .Fields("Zeile") = Join(expData, vbTab)  
        .Update
    End With
End Sub

Private Sub OpenGDbList()   'Datenbank Geburtsdaten erzeugen/öffnen  
    Set GDbList = CreateObject("ADOR.Recordset")  
    If FileObj.FileExists(GDbPath) Then
        With GDbList
            .CursorType = adOpenKeyset
            .Open GDbPath
        End With
    Else
        With GDbList.Fields
            .Append "TP-Nr", adVarChar, 24, adFldIsNullable  
            .Append "Datum", adVarChar, 16, adFldIsNullable  
             GDbList.Open
        End With
    End If
End Sub

Private Sub WriteGDbList()  'Geburtsdaten in Datenbank schreiben (nur neue Einträge)  
    With GDbList
        If .RecordCount Then
            .MoveFirst
            .Find = "TP-Nr = " & ix(3)  
             If Not .EOF Then Exit Sub
        End If
       .AddNew
       .Fields("TP-Nr") = ix(3)  
       .Fields("Datum") = ix(1)  
       .Update
    End With
End Sub

Private Sub InitGebData()   'Geburtsdaten in Datenbank suchen und auslesen  
    Dim datum
    gx = Array("", "", "")  
    With GDbList
        If .RecordCount Then
            .MoveFirst
            .Find = "TP-Nr = " & ix(1)  
             If Not .EOF Then
                datum = Split(.Fields("Datum"), ".")  
                If UBound(datum) = 2 Then gx = datum
             End If
        End If
    End With
End Sub


Gruß Dieter

PS. Hier noch ein interessanter Link für ADO-Basiswissen auf Deutsch
http://www.activevb.de/tutorials/tut_adokurs/adokurs.html
Vasili
Vasili 20.03.2009 um 22:26:57 Uhr
Goto Top
Hallo an Alle,

Danke für alles noch einmal.

Euer
Vasili