Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

Konvertieren einer CSV Datei im Batch Betrieb

Frage Entwicklung Batch & Shell

Mitglied: Vasili

Vasili (Level 1) - Jetzt verbinden

08.03.2009, aktualisiert 18.10.2012, 10234 Aufrufe, 48 Kommentare

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.
48 Antworten
Mitglied: 76109
08.03.2009 um 08:30 Uhr
Kommentar zwecks Übersicht entfernt!
Bitte warten ..
Mitglied: 76109
08.03.2009 um 09:14 Uhr
Kommentar zwecks Übersicht entfernt!
Bitte warten ..
Mitglied: Biber
08.03.2009 um 11:34 Uhr
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
Bitte warten ..
Mitglied: Vasili
08.03.2009 um 13:13 Uhr
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.
Bitte warten ..
Mitglied: Vasili
08.03.2009 um 13:17 Uhr
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.
Bitte warten ..
Mitglied: Vasili
08.03.2009 um 14:59 Uhr
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
Bitte warten ..
Mitglied: bastla
08.03.2009 um 16:05 Uhr
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 Code-Formatierung verwenden...

Grüße
bastla
Bitte warten ..
Mitglied: Vasili
08.03.2009 um 17:01 Uhr
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"
Bitte warten ..
Mitglied: bastla
08.03.2009 um 17:04 Uhr
Hallo Vasili!
Beim Einfügen hier sind die Tabs wohl verschwunden und durch Leerzeichen ersetzt worden
Deswegen der Hinweis auf eine passende Formatierungsmöglichkeit (empfehlenswert: type="plain") ...

Grüße
bastla
Bitte warten ..
Mitglied: Biber
08.03.2009 um 18:48 Uhr
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).

01.
@echo off & setlocal 
02.
:: Header der out.csv in Variablen einlesen  
03.
Set /p outcsvFlds=<out.csv 
04.
FOR /F "delims=; tokens=1-25" %%a in ("%outcsvFlds%") do ( 
05.
   Set "ocF_01=%%a"  & Set "ocF_02=%%b"   & Set "ocF_03=%%c"    
06.
   Set "ocF_04=%%d"  & Set "ocF_05=%%e"   & Set "ocF_06=%%f"    
07.
   Set "ocF_07=%%g"  & Set "ocF_08=%%h"   & Set "ocF_09=%%i"    
08.
   Set "ocF_10=%%j"  & Set "ocF_11=%%k"   & Set "ocF_12=%%l" 
09.
   Set "ocF_13=%%m"  & Set "ocF_14=%%n"   & Set "ocF_15=%%o"    
10.
   Set "ocF_16=%%p"  & Set "ocF_17=%%q"   & Set "ocF_18=%%r"    
11.
   Set "ocF_19=%%s"  & Set "ocF_20=%%t"   & Set "ocF_21=%%u"    
12.
   Set "ocF_22=%%v"  & Set "ocF_23=%%w"   & Set "ocF_24=%%x"    
13.
   Set "ocF_25=%%y"   
14.
)    
15.
 
16.
:: Header der gruppen.csv in Variablen einlesen  
17.
:: -------- Delims ist ein TAB 
18.
Set /p grpcsvFlds=<gruppen.csv 
19.
 
20.
FOR /F "delims=	 tokens=1-25" %%a in ("%grpcsvFlds%") do ( 
21.
   Set "gcF_01=%%a"  & Set "gcF_02=%%b"   & Set "gcF_03=%%c"    
22.
   Set "gcF_04=%%d"  & Set "gcF_05=%%e"   & Set "gcF_06=%%f"    
23.
   Set "gcF_07=%%g"  & Set "gcF_08=%%h"   & Set "gcF_09=%%i"    
24.
   Set "gcF_10=%%j"  & Set "gcF_11=%%k"   & Set "gcF_12=%%l" 
25.
   Set "gcF_13=%%m"  & Set "gcF_14=%%n"   & Set "gcF_15=%%o"    
26.
   Set "gcF_16=%%p"  & Set "gcF_17=%%q"   & Set "gcF_18=%%r"    
27.
   Set "gcF_19=%%s"  & Set "gcF_20=%%t"   & Set "gcF_21=%%u"    
28.
   Set "gcF_22=%%v"  & Set "gcF_23=%%w"   & Set "gcF_24=%%x"    
29.
   Set "gcF_25=%%y"   
30.
)    
31.
 
32.
:: Datenzeilen der out.csv in Variablen einlesen  
33.
:: ---Delimiter ist hier das Semikolon       
34.
FOR /F "delims=; tokens=1-25" %%a in (out.csv) do ( 
35.
 
36.
 (echo %ocF_01%: [%%a]) & (Echo %ocF_02%: [%%b]) & (echo %ocF_03%: [%%c]) 
37.
 (Echo %ocF_04%: [%%d]) & (Echo %ocF_05%: [%%e]) & (Echo %ocF_06%: [%%f]) 
38.
 (Echo %ocF_07%: [%%g]) & (Echo %ocF_08%: [%%h]) & (Echo %ocF_09%: [%%i]) 
39.
 (Echo %ocF_10%: [%%j]) & (Echo %ocF_11%: [%%k]) & (Echo %ocF_12%: [%%l]) 
40.
 (Echo %ocF_13%: [%%m]) & (Echo %ocF_14%: [%%n]) & (Echo %ocF_15%: [%%o]) 
41.
 (Echo %ocF_16%: [%%p]) & (Echo %ocF_17%: [%%q]) & (Echo %ocF_18%: [%%r]) 
42.
 (Echo %ocF_19%: [%%s]) & (Echo %ocF_20%: [%%t]) & (Echo %ocF_21%: [%%u]) 
43.
 (Echo %ocF_22%: [%%v]) & (Echo %ocF_23%: [%%w]) & (Echo %ocF_24%: [%%x]) 
44.
 (Echo %ocF_25%: [%%y]) 
45.
46.
 
47.
:: -------- als nächstes die Datenzeilen der Gruppen.csv 
48.
:: -------- Delimiter ist hier ein TAB       
49.
FOR /F "delims=	 tokens=1-25" %%a in (gruppen.csv) do ( 
50.
 
51.
 (echo %gcF_01%: [%%a]) & (Echo %gcF_02%: [%%b]) & (echo %gcF_03%: [%%c]) 
52.
 (Echo %gcF_04%: [%%d]) & (Echo %gcF_05%: [%%e]) & (Echo %gcF_06%: [%%f]) 
53.
 (Echo %gcF_07%: [%%g]) & (Echo %gcF_08%: [%%h]) & (Echo %gcF_09%: [%%i]) 
54.
 (Echo %gcF_10%: [%%j]) & (Echo %gcF_11%: [%%k]) & (Echo %gcF_12%: [%%l]) 
55.
 (Echo %gcF_13%: [%%m]) & (Echo %gcF_14%: [%%n]) & (Echo %gcF_15%: [%%o]) 
56.
 (Echo %gcF_16%: [%%p]) & (Echo %gcF_17%: [%%q]) & (Echo %gcF_18%: [%%r]) 
57.
 (Echo %gcF_19%: [%%s]) & (Echo %gcF_20%: [%%t]) & (Echo %gcF_21%: [%%u]) 
58.
 (Echo %gcF_22%: [%%v]) & (Echo %gcF_23%: [%%w]) & (Echo %gcF_24%: [%%x]) 
59.
 (Echo %gcF_25%: [%%y]) 
60.
)
Nach diesem Klärungsschritt
  • lassen sich beide Format erstmal stressfrei lesen

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

01.
... 
02.
L: [2] 
03.
TPNr: [47110815] 
04.
Name: [Muster] 
05.
Vorname: [Max] 
06.
Firma: [MM] 
07.
Angelegt: [02.02.2008] 
08.
L.Ums.: [40] 
09.
Tel.Privat: [0190666666] 
10.
Tel.Gesch.: [0190777777] 
11.
Mobiltelefon: [0190888888] 
12.
Fax: [0190999999] 
13.
Straße: [Maxstr. 99] 
14.
PLZ: [999999] 
15.
Ort: [Bibberstadt] 
16.
L.: [DE] 
17.
E-Mail: [max@muster.de] 
18.
M1L: [14] 
19.
QVM: [15] 
20.
QLM: [16] 
21.
QualVolumen: [17] 
22.
Struktur: [18] 
23.
Umsatz: [19] 
24.
Eigen: [20] 
25.
Promotion: [21] 
26.
Kunden: [22]
...versus Max Muster in der Gruppen.csv.
01.
... 
02.
Vorname: [Max] 
03.
Nachname: [Muster] 
04.
 
05.
Spitzname: [Max Muster ] 
06.
Primäre E-Mail: [max@muster.de ] 
07.
Sekundäre E-Mail: [0190777777] 
08.
Tel. dienstlich: [0190666666] 
09.
Tel. privat: [0190999999] 
10.
Fax-Nummer: [0190888888] 
11.
Pager-Nummer: [Maxstr. 99] 
12.
Mobil-Tel.-Nr.: [Bibberstadt] 
13.
Privat: Adresse: [999999] 
14.
Privat: Adresse 2: [DE] 
15.
Privat: Stadt: [47110815] 
16.
Privat: Bundesland: [02.02.2008] 
17.
Privat: PLZ: [2] 
18.
Privat: Land: [40] 
19.
Dienstlich: Adresse: [ - 14 - ] 
20.
Dienstlich: Adresse 2: [15 - ] 
21.
Dienstlich: Stadt: [16 - ] 
22.
Dienstlich: Bundesland: [17] 
23.
Dienstlich: PLZ: [ - 18 - ] 
24.
Dienstlich: Land: [19 - ] 
25.
Arbeitstitel: [20 - ] 
26.
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]
Bitte warten ..
Mitglied: 76109
08.03.2009 um 19:17 Uhr
Hallo!

So geht's auch:
01.
Option Explicit 
02.
 
03.
Dim FileObj As New FileSystemObject 'VB-Editor Verweis include <Microsoft Scripting Runtime> 
04.
 
05.
Private Sub Workbook_Open() 
06.
    Call ConvertFile 
07.
    'ThisWorkbook.Close SaveChanges:=False 
08.
End Sub 
09.
 
10.
Function ConvertFile() 
11.
    Dim ix, ex, en, iPath As String, ePath As String 
12.
    Dim iFile As TextStream, eFile As TextStream 
13.
     
14.
    On Error Resume Next 
15.
         
16.
    iPath = ThisWorkbook.Path & "\pm.csv" 
17.
    ePath = ThisWorkbook.Path & "\gruppe.csv" 
18.
     
19.
    en = Array("Vorname", "Nachname", "Anzeigename", "Spitzname", "Primäre E-Mail", _ 
20.
               "Sekundäre E-Mail", "Tel. dienstlich", "Tel. privat", "Fax-Nummer", _ 
21.
               "Pager-Nummer", "Mobil-Tel.-Nr.", "Privat: Adresse", "Privat: Adresse 2", _ 
22.
               "Privat: Stadt", "Privat: Bundesland", "Privat: PLZ", "Privat: Land", _ 
23.
               "Dienstlich: Adresse", "Dienstlich: Adresse 2", "Dienstlich: Stadt", _ 
24.
               "Dienstlich: Bundesland", "Dienstlich: PLZ", "Dienstlich: Land", _ 
25.
               "Arbeitstitel", "Abteilung", "Organisation", "Webseite 1", "Webseite 2", _ 
26.
               "Geburtsjahr", "Geburtsmonat", "Geburtstag", "Benutzerdef. 1", _ 
27.
               "Benutzerdef. 2", "Benutzerdef. 3", "Benutzerdef. 4", "Notizen") 
28.
     
29.
     
30.
    Set iFile = FileObj.OpenTextFile(iPath) 
31.
    Set eFile = FileObj.CreateTextFile(ePath, True) 
32.
     
33.
    If Err Then MsgBox "Datei nicht gefunden.", 48, "Fehler":  GoTo Ende 
34.
     
35.
    eFile.WriteLine Join(en, vbTab) 
36.
    iFile.SkipLine 
37.
     
38.
    Do While iFile.AtEndOfStream = False 
39.
        ix = Split(iFile.ReadLine, ";") 
40.
        If Not ix(0) = "" Then 
41.
            ex = Array(ix(3), ix(2), ix(3) & ix(2), ix(3) & ix(2), ix(15), "", ix(8), _ 
42.
                       ix(7), ix(10), "", ix(9), ix(11), "", ix(13), "", ix(12), ix(14)) 
43.
            eFile.WriteLine Join(ex, vbTab) 
44.
        End If 
45.
    Loop 
46.
         
47.
Ende: 
48.
    iFile.Close 
49.
    eFile.Close 
50.
    'Kill iPath 'Import-Datei löschen 
51.
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}
Bitte warten ..
Mitglied: bastla
08.03.2009 um 19:23 Uhr
@76109

Sieht gut aus ...

... 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
Bitte warten ..
Mitglied: 76109
08.03.2009 um 19:44 Uhr
Kommentar zwecks Übersicht entfernt!
Bitte warten ..
Mitglied: 76109
08.03.2009 um 19:48 Uhr
Kommentar zwecks Übersicht entfernt!
Bitte warten ..
Mitglied: Biber
08.03.2009 um 21:10 Uhr
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
Bitte warten ..
Mitglied: bastla
08.03.2009 um 21:14 Uhr
Hallo didi1954!
Du meinst wohl VB-Script. Oder?
Yep. Sieht eigentlich kaum anders aus als VBA:
01.
Option Explicit 
02.
 
03.
Dim ix, ex, en, iPath, ePath 
04.
Dim FileObj, iFile, eFile 
05.
Set FileObj = CreateObject("Scripting.FileSystemObject") 
06.
     
07.
'On Error Resume Next 
08.
         
09.
iPath = WScript.Arguments(0) 
10.
ePath = WScript.Arguments(1) 
11.
     
12.
en = Array("Vorname", "Nachname", "Anzeigename", "Spitzname", "Primäre E-Mail", _ 
13.
           "Sekundäre E-Mail", "Tel. dienstlich", "Tel. privat", "Fax-Nummer", _ 
14.
           "Pager-Nummer", "Mobil-Tel.-Nr.", "Privat: Adresse", "Privat: Adresse 2", _ 
15.
           "Privat: Stadt", "Privat: Bundesland", "Privat: PLZ", "Privat: Land", _ 
16.
           "Dienstlich: Adresse", "Dienstlich: Adresse 2", "Dienstlich: Stadt", _ 
17.
           "Dienstlich: Bundesland", "Dienstlich: PLZ", "Dienstlich: Land", _ 
18.
           "Arbeitstitel", "Abteilung", "Organisation", "Webseite 1", "Webseite 2", _ 
19.
           "Geburtsjahr", "Geburtsmonat", "Geburtstag", "Benutzerdef. 1", _ 
20.
           "Benutzerdef. 2", "Benutzerdef. 3", "Benutzerdef. 4", "Notizen") 
21.
     
22.
     
23.
Set iFile = FileObj.OpenTextFile(iPath) 
24.
Set eFile = FileObj.CreateTextFile(ePath, True) 
25.
     
26.
If Err Then MsgBox "Datei nicht gefunden.", 48, "Fehler":  WScript.Quit 1 'Errorlevel setzen 
27.
     
28.
eFile.WriteLine Join(en, vbTab) 
29.
iFile.SkipLine 
30.
     
31.
Do While iFile.AtEndOfStream = False 
32.
    ix = Split(iFile.ReadLine, ";") 
33.
    If Not ix(0) = "" Then 
34.
        ex = Array(ix(3), ix(2), ix(3) & ix(2), ix(3) & ix(2), ix(15), "", ix(8), _ 
35.
                   ix(7), ix(10), "", ix(9), ix(11), "", ix(13), "", ix(12), ix(14)) 
36.
        eFile.WriteLine Join(ex, vbTab) 
37.
    End If 
38.
Loop 
39.
         
40.
iFile.Close 
41.
eFile.Close 
42.
'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
Bitte warten ..
Mitglied: 76109
08.03.2009 um 21:19 Uhr
Kommentar zwecks Übersicht entfernt!
Bitte warten ..
Mitglied: Biber
08.03.2009 um 21:47 Uhr
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
Bitte warten ..
Mitglied: Vasili
09.03.2009 um 04:01 Uhr
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
Bitte warten ..
Mitglied: bastla
09.03.2009 um 07:07 Uhr
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
Bitte warten ..
Mitglied: Biber
09.03.2009 um 07:55 Uhr
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
Bitte warten ..
Mitglied: Vasili
09.03.2009 um 15:44 Uhr
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.
Bitte warten ..
Mitglied: 76109
09.03.2009 um 15:50 Uhr
Hallo Vasili,

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

SkipLine = eine Zeile überspringen.

Gruß Dieter
Bitte warten ..
Mitglied: 76109
09.03.2009 um 16:09 Uhr
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
Bitte warten ..
Mitglied: bastla
09.03.2009 um 16:24 Uhr
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
Bitte warten ..
Mitglied: 76109
09.03.2009 um 19:54 Uhr
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:

01.
ix = Split(iFile.ReadLine, ";") 
02.
If UBound(ix) = -1 Then MsgBox "Ungültige ASCII-Zeichen..", 48, "Fehler": WScript.Quit 1 'Errorlevel setzen 
03.
If Not ix(0) = "" Then
Gruß Dieter
Bitte warten ..
Mitglied: bastla
09.03.2009 um 20:19 Uhr
@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
Bitte warten ..
Mitglied: 76109
09.03.2009 um 20:30 Uhr
Hallo Bastla,

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

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

Hier noch ein Textschnipsel hoffentlich auch korrekt formatiert:

01.
Do While iFile.AtEndOfStream = False 
02.
    ix = Split(iFile.ReadLine, ";") 
03.
       If Trim(Join(ix)) <> "" Then 
04.
        ex = Array(ix(3), ix(2), ix(3) & " " & ix(2), ix(3) & " " & ix(2), _ 
05.
                   ix(15), "", ix(8), ix(7), _ 
06.
                   ix(10), "", ix(9), ix(11), _ 
07.
                   "", ix(13), "", ix(12), _ 
08.
                   ix(14), "", "", "", _ 
09.
                   "", "", "", "", _ 
10.
                   "", ix(4), "", "", _ 
11.
                   "", "", "", ix(1), _ 
12.
                   "", (If ix(0) = "" Then "0" Else ix(0) End If), ix(5), _ 
13.
                   (If ix(6) = "-" Then "00.0000" Else ix(6) End If) & " - " & ix(16) & " - " & ix(17) & " - " & _ 
14.
                   ix(18) & " - " & ix(19) & " - " & ix(20) & " - " & _ 
15.
                   ix(21) & " - " & ix(22) & " - " & ix(23) & " - " & ix(24)) 
16.
        eFile.WriteLine Join(ex, vbTab) 
17.
    End If 
18.
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?!?
Bitte warten ..
Mitglied: Vasili
10.03.2009 um 02:16 Uhr
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
Bitte warten ..
Mitglied: bastla
10.03.2009 um 10:00 Uhr
Hallo Vasili!

Die Zeilen 4 bis 15 (Deines geposteten Schnipsesl - danke übrigens für die Formatierung ) 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:
01.
Do While iFile.AtEndOfStream = False 
02.
    ix = Split(iFile.ReadLine, ";") 
03.
    If Trim(Join(ix)) <> "" Then 
04.
        If ix(0) = "" Then ix(0) = "0" 
05.
        If ix(6) = "-" Then ix(6) = "00.0000" 
06.
        ex = Array(ix(3), ix(2), ix(3) & " " & ix(2), ix(3) & " " & ix(2), _ 
07.
                   ix(15), "", ix(8), ix(7), _ 
08.
                   ix(10), "", ix(9), ix(11), _ 
09.
                   "", ix(13), "", ix(12), _ 
10.
                   ix(14), "", "", "", _ 
11.
                   "", "", "", "", _ 
12.
                   "", ix(4), "", "", _ 
13.
                   "", "", "", ix(1), _ 
14.
                   "", ix(0), ix(5), _ 
15.
                   ix(6) & " - " & ix(16) & " - " & ix(17) & " - " & ix(18) & " - " _ 
16.
                   & ix(19) & " - " & ix(20) & " - " & ix(21) & " - " & ix(22) & _ 
17.
                   " - " & ix(23) & " - " & ix(24)) 
18.
        eFile.WriteLine Join(ex, vbTab) 
19.
    End If 
20.
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
Bitte warten ..
Mitglied: 76109
10.03.2009 um 16:17 Uhr
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
Bitte warten ..
Mitglied: bastla
10.03.2009, aktualisiert 18.10.2012
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
Bitte warten ..
Mitglied: 76109
10.03.2009 um 16:33 Uhr
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
Bitte warten ..
Mitglied: bastla
10.03.2009 um 17:32 Uhr
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
Bitte warten ..
Mitglied: 76109
10.03.2009 um 18:55 Uhr
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.
Bitte warten ..
Mitglied: bastla
10.03.2009 um 22:52 Uhr
Hallo didi1954!

Profi bin ich auch nicht, und über die "Effizienz" lässt sich sicher diskutieren, aber einen Lösungsansatz kann ich anbieten:
01.
Option Explicit 
02.
 
03.
Dim ix, ex, en, iPath, ePath, aPath 
04.
Dim FileObj, iFile, eFile, aFile 
05.
Dim DataList, LastLine, ThisLine 
06.
Set FileObj = CreateObject("Scripting.FileSystemObject") 
07.
 
08.
iPath = WScript.Arguments(0) 'Eingabedatei 
09.
ePath = WScript.Arguments(1) 'Ausgabedatei 
10.
aPath = WScript.Arguments(2) 'Datei für ausgeschiedene Zeilen 
11.
 
12.
en = Array("Vorname", "Nachname", "Anzeigename", "Spitzname", _ 
13.
           "Primäre E-Mail", "Sekundäre E-Mail", "Tel. dienstlich", "Tel. privat", _ 
14.
           "Fax-Nummer", "Pager-Nummer", "Mobil-Tel.-Nr.", "Privat: Adresse", _ 
15.
           "Privat: Adresse 2", "Privat: Stadt", "Privat: Bundesland", "Privat: PLZ", _ 
16.
           "Privat: Land", "Dienstlich: Adresse", "Dienstlich: Adresse 2", "Dienstlich: Stadt", _ 
17.
           "Dienstlich: Bundesland", "Dienstlich: PLZ", "Dienstlich: Land", "Arbeitstitel", _ 
18.
           "Abteilung", "Organisation", "Webseite 1", "Webseite 2", _ 
19.
           "Geburtsjahr", "Geburtsmonat", "Geburtstag", "Benutzerdef. 1", _ 
20.
           "Benutzerdef. 2", "Benutzerdef. 3", "Benutzerdef. 4", "Notizen") 
21.
 
22.
Set iFile = FileObj.OpenTextFile(iPath) 
23.
If Err Then MsgBox "Datei nicht gefunden.", 48, "Fehler": WScript.Quit 1 'Errorlevel setzen 
24.
 
25.
'Datenbank erzeugen und öffnen 
26.
Const adVarChar = 200 
27.
Const adFldIsNullable = 32 
28.
Const adInteger = 3 
29.
 
30.
Set DataList = CreateObject("ADOR.Recordset") 
31.
DataList.Fields.Append "Name", adVarChar, 64, adFldIsNullable     'Feldgröße (64 Zeichen) für "Nachname"+"Vorname" bei Bedarf anpassen 
32.
DataList.Fields.Append "Zeile", adVarChar, 1024, adFldIsNullable  'Feldgröße (1024 Zeichen) für gesamte Ausgabezeile 
33.
DataList.Open 
34.
 
35.
'Bis auf die erste Zeile alle weiteren Zeilen aus CSV lesen und konvertieren 
36.
iFile.SkipLine 
37.
Do While iFile.AtEndOfStream = False 
38.
    ix = Split(iFile.ReadLine, ";") 
39.
    If Trim(Join(ix)) <> "" Then 
40.
        If ix(0) = "" Then ix(0) = "0" 
41.
        If ix(6) = "-" Then ix(6) = "00.0000" 
42.
        'Neue Ausgabezeile erstellen 
43.
        ex = Array(ix(3), ix(2), ix(3) & " " & ix(2), ix(3) & " " & ix(2), _ 
44.
                   ix(15), "", ix(8), ix(7), _ 
45.
                   ix(10), "", ix(9), ix(11), _ 
46.
                   "", ix(13), "", ix(12), _ 
47.
                   ix(14), "", "", "", _ 
48.
                   "", "", "", "", _ 
49.
                   "", ix(4), "", "", _ 
50.
                   "", "", "", ix(1), _ 
51.
                   "", ix(0), ix(5), _ 
52.
                   ix(6) & " - " & ix(16) & " - " & ix(17) & " - " & ix(18) & " - " _ 
53.
                   & ix(19) & " - " & ix(20) & " - " & ix(21) & " - " & ix(22) & _ 
54.
                   " - " & ix(23) & " - " & ix(24)) 
55.
        'Satz in Datenbank schreiben 
56.
        DataList.AddNew 
57.
        DataList("Name") = LCase(ix(3) & " " & ix(2)) 'Sortierkriterium = Anzeigename (in Kleinbuchstaben) 
58.
        DataList("Zeile") = Join(ex, vbTab)     'gesamte Ausgabezeile 
59.
        DataList.Update 
60.
    End If 
61.
Loop 
62.
iFile.Close 
63.
 
64.
'Ausgabedatei erzeugen und Kopfzeile schreiben 
65.
Set eFile = FileObj.CreateTextFile(ePath, True) 
66.
eFile.WriteLine Join(en, vbTab) 
67.
 
68.
'Datei für ausgeschiedene Zeilen erzeugen und Kopfzeile schreiben 
69.
Set aFile = FileObj.CreateTextFile(aPath, True) 
70.
aFile.WriteLine Join(en, vbTab) 
71.
 
72.
LastLine = "" 'Initialisierung "letzte geschriebene Zeile" 
73.
DataList.Sort = "Name" 'Datenbank nach Feld "Name" sortieren 
74.
DataList.MoveFirst 'zum ersten Datensatz 
75.
Do Until DataList.EOF 'Schleife über alle Datensätze 
76.
    ThisLine = DataList.Fields.Item("Zeile") 'Ausgabezeile aus Datenbank lesen 
77.
    'Vergleich der gesamten Zeile ohne Berücksichtigung von Groß-/Kleinschreibung 
78.
    If LCase(ThisLine) <> LCase(LastLine) Then  
79.
        eFile.WriteLine ThisLine 'kein Duplikat - Zeile in Ausgabedatei schreiben 
80.
        LastLine = ThisLine 'geschriebene Zeile merken 
81.
    Else 'Duplikat gefunden 
82.
        aFile.WriteLine ThisLine 'ausgeschiedene Zeile schreiben 
83.
    End If 
84.
    DataList.MoveNext 'zum nächsten Datensatz 
85.
Loop 
86.
eFile.Close 
87.
aFile.Close 
88.
'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]
Bitte warten ..
Mitglied: Biber
10.03.2009 um 23:13 Uhr
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
Bitte warten ..
Mitglied: bastla
10.03.2009 um 23:25 Uhr
@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
Bitte warten ..
Mitglied: Vasili
11.03.2009 um 12:34 Uhr
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
Bitte warten ..
Mitglied: Vasili
11.03.2009 um 12:47 Uhr
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
Bitte warten ..
Mitglied: Vasili
11.03.2009 um 13:07 Uhr
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?
Bitte warten ..
Mitglied: 76109
11.03.2009 um 16:46 Uhr
Hallo bastla,


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
Bitte warten ..
Mitglied: bastla
11.03.2009 um 17:15 Uhr
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
Bitte warten ..
Mitglied: Vasili
11.03.2009 um 20:54 Uhr
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.

Grüße,
Vasili
Bitte warten ..
Mitglied: 76109
13.03.2009 um 12:11 Uhr
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
Bitte warten ..
Mitglied: 76109
18.03.2009 um 13:28 Uhr
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.

01.
Batch: cscript //nologo X:\Scripts\ConvertCSV.vbs 
02.
 
03.
Die Batch ist nicht erforderlich, ConvertCVS kann direkt mit Doppelklick auf die Datei oder Verknüpfung gestartet werden. 
04.
 
05.
 
06.
Option Explicit 
07.
 
08.
'Dateinamen hier festlegen 
09.
Const GDbName = "\PM-DB.ADT"     'Export-Datei Datenbank gesammelte Geburtsdaten (Import GEBURTSTAG.CSV) 
10.
Const DupName = "\DUPLETTEN.CSV"     'Export-Datei Duplikate (Import PM-I.CSV) 
11.
Const ExpName = "\GRUPPEN.CSV"     'Export-Datei ohne Duplikate mit Geburtsdaten (Import PM-I.CSV + PM-DB.ADT) 
12.
Const GebName = "\GEBURTSTAG.CSV"     'Import-Datei Geburtstage für 30 Tage 
13.
Const ImpName = "\PM-I.CSV"     'Import-Datei Allgemeine Daten 
14.
 
15.
'ADO-Recordset 
16.
Const adInteger = 3                  
17.
Const adVarChar = 200 
18.
Const adOpenKeyset = 1 
19.
Const adPersistXML = 1 
20.
Const adPersistADTG = 0 
21.
Const adFldIsNullable = 32 
22.
 
23.
Dim FileObj, ImpFile, ExpFile, DupFile, GebFile 
24.
Dim VbsPath, ImpPath, ExpPath, DupPath, GebPath, GDbPath 
25.
Dim ix, gx, expData, expFeld, DataList, GDbList, LastLine, ThisLine 
26.
 
27.
 
28.
'Main Begin 
29.
 
30.
    Set FileObj = CreateObject("Scripting.FileSystemObject")       'Bibliothek Dateifunktionen 
31.
 
32.
    VbsPath = FileObj.GetParentFolderName(Wscript.ScriptFullname)    'Dateipfad Script-Datei 
33.
 
34.
 
35.
    'Dateipfad Konvertierungs-Dateien 
36.
    GDbPath = VbsPath & GDbName 
37.
    DupPath = VbsPath & DupName 
38.
    ExpPath = VbsPath & ExpName 
39.
    GebPath = VbsPath & GebName 
40.
    ImpPath = VbsPath & ImpName 
41.
 
42.
     
43.
    'Feldnamen Export-Datei 
44.
    expFeld = Array("Vorname", "Nachname", "Anzeigename", "Spitzname", _ 
45.
                    "Primäre E-Mail", "Sekundäre E-Mail", "Tel. dienstlich", "Tel. privat", _ 
46.
                    "Fax-Nummer", "Pager-Nummer", "Mobil-Tel.-Nr.", "Privat: Adresse", _ 
47.
                    "Privat: Adresse 2", "Privat: Stadt", "Privat: Bundesland", "Privat: PLZ", _ 
48.
                    "Privat: Land", "Dienstlich: Adresse", "Dienstlich: Adresse 2", "Dienstlich: Stadt", _ 
49.
                    "Dienstlich: Bundesland", "Dienstlich: PLZ", "Dienstlich: Land", "Arbeitstitel", _ 
50.
                    "Abteilung", "Organisation", "Webseite 1", "Webseite 2", _ 
51.
                    "Geburtsjahr", "Geburtsmonat", "Geburtstag", "Benutzerdef. 1", _ 
52.
                    "Benutzerdef. 2", "Benutzerdef. 3", "Benutzerdef. 4", "Notizen") 
53.
     
54.
    Call OpenGDbList      'Datenbank mit Geburtsdaten erzeugen/öffnen 
55.
     
56.
    'Neue Geburtsdaten in Datenbank übernehmen 
57.
    If FileObj.FileExists(GebPath) Then    'Test ob neue Datei mit Geburtsdaten existiert 
58.
        Set GebFile = FileObj.OpenTextFile(GebPath)   
59.
        With GebFile    'Datei Zeilenweise einlesen und neue Daten in Datenbank schreiben 
60.
           .SkipLine 
61.
            Do Until .AtEndOfStream 
62.
                ix = Split(.ReadLine, ";") 
63.
                If Trim(Join(ix)) <> "" Then Call WriteGDbList 
64.
            Loop 
65.
           .Close 
66.
        End With 
67.
        With GDbList    'Datenbank Geburtstage sortieren und speichern 
68.
           .Sort = "TP-Nr" 
69.
           .Save GDbPath, adPersistADTG 
70.
        End With 
71.
    End If 
72.
 
73.
    Call OpenDataList    'Recordset für Allgemeine Daten erzeugen 
74.
     
75.
    Set ImpFile = FileObj.OpenTextFile(ImpPath) 
76.
     
77.
    With ImpFile    'Daten einlesen und nach Export-Feldnamen sortiert in Recordset schreiben 
78.
       .SkipLine 
79.
        Do Until .AtEndOfStream 
80.
            ix = Split(.ReadLine, ";") 
81.
            If Trim(Join(ix)) <> "" Then 
82.
                Call InitGebData 
83.
                If ix(0) = "" Then ix(0) = "0" 
84.
                If ix(6) = "-" Then ix(6) = "00.0000" 
85.
                expData = Array(ix(3), ix(2), ix(3) & " " & ix(2), ix(3) & " " & ix(2), _ 
86.
                                ix(15), "", ix(8), ix(7), ix(10), "", ix(9), ix(11), "", ix(13), "", _ 
87.
                                ix(12), ix(14), "", "", "", "", "", "", "", "", ix(4), "", "", gx(2), _ 
88.
                                gx(1), gx(0), ix(1), "", ix(0), ix(5), _ 
89.
                                ix(6) & " ; " & ix(16) & " ; " & ix(17) & " ; " & ix(18) & " ; " & _ 
90.
                                ix(19) & " ; " & ix(20) & " ; " & ix(21) & " ; " & ix(22) & " ; " & _ 
91.
                                ix(23) & " ; " & ix(24)) 
92.
                Call WriteDataList 
93.
            End If 
94.
        Loop 
95.
       .Close 
96.
    End With 
97.
     
98.
    Set ExpFile = FileObj.CreateTextFile(ExpPath, True) 
99.
    ExpFile.WriteLine Join(expFeld, vbTab)   'Feldnamen speichern 
100.
     
101.
    Set DupFile = FileObj.CreateTextFile(DupPath, True) 
102.
    DupFile.WriteLine Join(expFeld, vbTab)   'Feldnamen speichern 
103.
     
104.
    With DataList   'Daten aus Recordset in Export-Datei und Duplikate-Datei schreiben 
105.
        LastLine = "" 
106.
       .Sort = "Name" 
107.
       .MoveFirst 
108.
        Do Until DataList.EOF 
109.
            ThisLine = .Fields("Zeile") 
110.
            If StrComp(ThisLine, LastLine, vbTextCompare) Then 
111.
                ExpFile.WriteLine ThisLine 
112.
                LastLine = ThisLine 
113.
            Else 
114.
                DupFile.WriteLine ThisLine 
115.
            End If 
116.
           .MoveNext 
117.
        Loop 
118.
    End With 
119.
     
120.
    ExpFile.Close:  DupFile.Close:  DataList.Close:  GDbList.Close   'Objecte schließen 
121.
     
122.
    With FileObj 
123.
        '.DeleteFile GebPath: .DeleteFile ImpPath   'Dateien löschen 
124.
    End With 
125.
 
126.
    WScript.Quit 0 'Errorlevel setzen 
127.
 
128.
'Main End 
129.
 
130.
 
131.
Private Sub OpenDataList()  'ADO-Recordset erzeugen 
132.
    Set DataList = CreateObject("ADOR.Recordset") 
133.
    With DataList.Fields 
134.
        .Append "Name", adVarChar, 64, adFldIsNullable 
135.
        .Append "Zeile", adVarChar, 1024, adFldIsNullable 
136.
         DataList.Open 
137.
    End With 
138.
End Sub 
139.
 
140.
Private Sub WriteDataList() 'In ADO-Recordset schreiben 
141.
    With DataList 
142.
        .AddNew 
143.
        .Fields("Name") = LCase(ix(3) & " " & ix(2)) 
144.
        .Fields("Zeile") = Join(expData, vbTab) 
145.
        .Update 
146.
    End With 
147.
End Sub 
148.
 
149.
Private Sub OpenGDbList()   'Datenbank Geburtsdaten erzeugen/öffnen 
150.
    Set GDbList = CreateObject("ADOR.Recordset") 
151.
    If FileObj.FileExists(GDbPath) Then 
152.
        With GDbList 
153.
            .CursorType = adOpenKeyset 
154.
            .Open GDbPath 
155.
        End With 
156.
    Else 
157.
        With GDbList.Fields 
158.
            .Append "TP-Nr", adVarChar, 24, adFldIsNullable 
159.
            .Append "Datum", adVarChar, 16, adFldIsNullable 
160.
             GDbList.Open 
161.
        End With 
162.
    End If 
163.
End Sub 
164.
 
165.
Private Sub WriteGDbList()  'Geburtsdaten in Datenbank schreiben (nur neue Einträge) 
166.
    With GDbList 
167.
        If .RecordCount Then 
168.
            .MoveFirst 
169.
            .Find = "TP-Nr = " & ix(3) 
170.
             If Not .EOF Then Exit Sub 
171.
        End If 
172.
       .AddNew 
173.
       .Fields("TP-Nr") = ix(3) 
174.
       .Fields("Datum") = ix(1) 
175.
       .Update 
176.
    End With 
177.
End Sub 
178.
 
179.
Private Sub InitGebData()   'Geburtsdaten in Datenbank suchen und auslesen 
180.
    Dim datum 
181.
    gx = Array("", "", "") 
182.
    With GDbList 
183.
        If .RecordCount Then 
184.
            .MoveFirst 
185.
            .Find = "TP-Nr = " & ix(1) 
186.
             If Not .EOF Then 
187.
                datum = Split(.Fields("Datum"), ".") 
188.
                If UBound(datum) = 2 Then gx = datum 
189.
             End If 
190.
        End If 
191.
    End With 
192.
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
Bitte warten ..
Mitglied: Vasili
20.03.2009 um 22:26 Uhr
Hallo an Alle,

Danke für alles noch einmal.

Euer
Vasili
Bitte warten ..
Neuester Wissensbeitrag
CPU, RAM, Mainboards

Angetestet: PC Engines APU 3a2 im Rack-Gehäuse

Erfahrungsbericht von ashnod zum Thema CPU, RAM, Mainboards ...

Ähnliche Inhalte
VB for Applications
Bestimmte Daten aus eine CSV-Datei in eine Excel-Tabelle importieren (2)

Frage von MariaElena zum Thema VB for Applications ...

Batch & Shell
gelöst PS Werte CSV-Datei in AD Attribut (3)

Frage von lupolo zum Thema Batch & Shell ...

Batch & Shell
Mehrere AD Benutzer aus CSV Datei mit PowerShell erstellen (1)

Frage von windelterrorist zum Thema Batch & Shell ...

Heiß diskutierte Inhalte
Windows Server
DHCP Server switchen (25)

Frage von M.Marz zum Thema Windows Server ...

Grafikkarten & Monitore
Win 10 Grafikkarte Crash von Software? (13)

Frage von Marabunta zum Thema Grafikkarten & Monitore ...

Router & Routing
gelöst Empfehlung günstiges ADSL2+ nur Modem (10)

Frage von TimMayer zum Thema Router & Routing ...

Server-Hardware
Lenovo Server System X 3650 M5 Festplatten (9)

Frage von Hendrik2586 zum Thema Server-Hardware ...