badfsaadkl
Goto Top

Probleme mit Array in vbscript

Hallo zusammen,

ich habe mal wieder ein Problem, bei einem Vergleich / Update zweier Files mittels vbscript, und hohhe Ihr könnt mir helfen.
Habe zwar schon die ersten Grundzüge in dem Script, komme aber jetzt nicht weiter, wie und wo ich ein entsprechendes Array einbauen muss face-sad.

Aber erst einmal zur Ausgangssituation.
Ich habe zwei csv Files, welche ich auf Inhalt vergleichen muss, und wenn eine Bedingung zutrifft, soll ein Wert aus File A nach File B übernommen werden.

File A:
XTSOL;p_model;p_stock;p_sorting;p_shipping;p_tpl;p_manufacturer;p_fsk18;p_priceNoTax;p_priceNoTax.1;p_priceNoTax.2;p_priceNoTax.3;p_tax;p_status;p_weight;p_ean

XTSOL;41014500;10000;0;5;default;1_100FM;0;32.353;;;;1;1;0.00;8714572047791
XTSOL;85010700;10000;0;5;default;1_100FM;0;150.840;;;;1;1;0.00;8714572074919
XTSOL;10007800;9984;0;5;default;1_100FM;0;15.966;;;;1;1;0.00;8714572075060
XTSOL;80022100;0;0;5;default;1_100FM;0;23.529;;;;1;1;0.00;8714572079105

File B:
products_id;external_id;afterbuy_id;afterbuy_image_path;permission_id;products_owner;products_ean;products_quantity;products_average_quantity;products_shippingtime;products_model

8852;41777081;../info_images/12882_0.jpg;1;;;hier müsste die EAN stehen;1000.00;0;7;41014500
8820;41536000;../info_images/12854_0.jpg;1;;;8714572074919;1000.00;0;7;85010700
8671;41242775;../info_images/12746_0.jpg;1;;;8714572075060;1000.00;0;7;10007800
9157;43366458;../info_images/13102_0.jpg;1;;;8714572079105;1000.00;0;7;80022100

Ich habe nun das Problem, das in File B nicht alle EAN Nummern aus File A übernommen sind.
Im Normalfall steht diese in File B an der 7ten Stelle.
Bei einigen fehlt diese aber, und die Stelle ist leer.
In File A ist die EAN aber noch vorhanden, und müsste jetzt ausgelesen werden, und in File B übertragen werden.

Den Querverweis hierzu habe ich über die Felder p_model (File A - Zweiter Eintrag) und products_model (File B - 11ter Eintrag).
Als Beispiel siehe hier die Nummer "41014500".

Es müsste nun geprüft werden, ob in File B die 7te Stelle leer ist.
Ist das der Fall, muss aus File B, die Nummer aus products_model (File B - 11ter Eintrag) genommen werden, und nach diesem in p_model (File A - Zweiter Eintrag) gesucht werden.
Bei einem Treffer, muss nun aus File A die EAN (16te Stelle) in File B übernommen werden (7te Stelle).

Anbei mal mein Script, was ich bis jetzt habe.
Ich weis, ist nicht viel, aber das ist ja mein Problem, ich weis im Moment nicht, wie ich weiter machen muss...

Const ForWriting = 2
Const ForReading = 1
Const ForAppending = 8
Set FSO = CreateObject("Scripting.FileSystemObject")  

Const Basis01 = "S:\datacenter\Workspace\tmp\file_a.csv"  
Const Basis02 = "S:\datacenter\Workspace\tmp\file_b.csv"  
Const Ausgabe01 = "S:\datacenter\Workspace\tmp\Ausgabe_Ergbenisse.csv"  

if not fso.fileexists(Basis01) then
	wscript.echo "Achtung die Eingabedatei " & Basis01 & " steht nicht zur Verfügung, Script wird abgebrochen"  
	wscript.quit
end if

if not fso.fileexists(Basis02) then
	wscript.echo "Achtung die Eingabedatei " & Basis02 & " steht nicht zur Verfügung, Script wird abgebrochen"  
	wscript.quit
end if

set mf = fso.CreateTextFile(Ausgabe01,True) : mf.close

set xout = fso.OpenTextFile(Basis02, ForReading)
While not xout.AtEndOfStream
	inhalt_datei02=xout.Readall()
Wend
xout.close

set erg = fso.OpenTextFile(Ausgabe01, ForAppending)

set xout = fso.OpenTextFile(Basis01, ForReading)
While not xout.AtEndOfStream
	inhalt_datei01=xout.ReadLine()
if Instr(inhalt_datei02,inhalt_datei01) then
	'Mach Nischt  
else
erg.write "      " & """" & inhalt_datei01 & " xx""," & vbcrlf  
end if
Wend
xout.close
erg.close

Das script hatte ich mal, um einen kompletten String zweier Files zu vergleichen.

Ich hoffe Ihr könnt mir hier helfen.

Gruß
BadFsaadKl

Content-Key: 236793

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

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

Member: bastla
bastla Apr 29, 2014 at 21:39:31 (UTC)
Goto Top
Hallo BadFsaadKl!

Versuch es damit:
Set fso = CreateObject("Scripting.FileSystemObject")  

Const Basis01 = "S:\datacenter\Workspace\tmp\file_a.csv"  
Const Basis02 = "S:\datacenter\Workspace\tmp\file_b.csv"  
Const Ausgabe01 = "S:\datacenter\Workspace\tmp\Ausgabe_Ergbenisse.csv"  

Const Delim = ";" 'Trennreichen  

If Not fso.FileExists(Basis01) Then
	WScript.Echo "Achtung die Eingabedatei " & Basis01 & " steht nicht zur Verfügung, Script wird abgebrochen"  
	WScript.Quit
End If

If Not fso.FileExists(Basis02) Then
	WScript.Echo "Achtung die Eingabedatei " & Basis02 & " steht nicht zur Verfügung, Script wird abgebrochen"  
	WScript.Quit
End If

Set xout = fso.OpenTextFile(Basis01)
If xout.AtEndOfStream Then
	WScript.Echo "Achtung die Eingabedatei " & Basis01 & " enthält keine Daten, Script wird abgebrochen"  
	WScript.Quit
End If
Inhalt_Datei01 = Split(xout.ReadAll, vbNewLine)

Set xout = fso.OpenTextFile(Basis02)
If xout.AtEndOfStream Then
	WScript.Echo "Achtung die Eingabedatei " & Basis02 & " enthält keine Daten, Script wird abgebrochen"  
	WScript.Quit
End If
Inhalt_Datei02 = Split(xout.ReadAll, vbNewLine)

'EAN-Tabelle aufbauen  
Set d = CreateObject("Scripting.Dictionary")  
For i = 2 To UBound(Inhalt_Datei01) 'erste 2 Zeilen überspringen  
    Satz = Split(Inhalt_Datei01(i), Delim) 'Datensatz (Zeile) zerlegen  
    d.Add Satz(1), Satz(15) 'Feld 2 = Schlüssel, Feld 16 = EAN  
Next

For i = 2 To UBound(Inhalt_Datei02) 'erste 2 Zeilen überspringen  
    Satz = Split(Inhalt_Datei02(i), Delim) 'Datensatz (Zeile) zerlegen  
    If Satz(6) = "" Then 'EAN in Feld 7 fehlt  
        If d.Exists(Satz(10)) Then 'Schlüssel lt Feld 11 vorhanden?  
            Satz(6) = d.Item(Satz(10)) 'EAN in Feld 7 übernehmen  
        Else
            WScript.Echo "Für Zeile " & i + 1 & " keine EAN gefunden!"  
            WScript.Quit
        End If
        Inhalt_Datei02(i) = Join(Satz, Delim) 'Satz überschreiben  
    End If
Next

fso.CreateTextFile(Ausgabe01).Write Join(Inhalt_Datei02, vbNewline) 'komplette Datei ausgeben  
Grüße
bastla
Member: BadFsaadKl
BadFsaadKl Apr 30, 2014 at 16:48:32 (UTC)
Goto Top
Hallo Bastla,

erst einmal danke für die Hilfe.
Das Script bricht jedoch mit folgender Meldung ab:
ean-abgleich.vbs(38, 5) Laufzeitfehler in Microsoft VBScript: Dieser Schlüssel ist bereits einem Element dieser Auflistung zugeordnet

Laut Fehlermeldung ist bei mir in Zeile 38,5 folgender Bereich
d.Add Satz(1), Satz(15) 'Feld 2 = Schlüssel, Feld 16 = EAN   
In deinem Beispiel Zeile 37.

Gruß BadFsaadKl
Member: bastla
bastla Apr 30, 2014 at 17:41:00 (UTC)
Goto Top
Hallo BadFsaadKl!

Ursache ist, dass in File A der Wert für "p_model" in mehreren Datensätzen gleich ist - mit
If Not d.Exists(Satz(1)) Then d.Add Satz(1), Satz(15) 'Feld 2 = Schlüssel, Feld 16 = EAN
sollte der Fehler nicht mehr auftreten ...

Grüße
bastla
Member: BadFsaadKl
BadFsaadKl Apr 30, 2014 at 17:50:11 (UTC)
Goto Top
Hi Bastla,

Ok, ist ausgetauscht.
'EAN-Tabelle aufbauen   
Set d = CreateObject("Scripting.Dictionary")   
For i = 1 To UBound(Inhalt_Datei01) 'erste Zeile überspringen   
    Satz = Split(Inhalt_Datei01(i), Delim) 'Datensatz (Zeile) zerlegen   
    If Not d.Exists(Satz(1)) Then d.Add Satz(1), Satz(15) 'Feld 2 = Schlüssel, Feld 16 = EAN   
Next 

jetzt bekomme ich folgenden Fehler:
ean-abgleich.vbs(38, 5) Laufzeitfehler in Microsoft VBScript: Index außerhalb des gültigen Bereichs: '[number: 1]'  

Gruß
Bad
Member: bastla
bastla Apr 30, 2014 at 18:00:13 (UTC)
Goto Top
Hallo BadFsaadKl!

Vermutlich enthält die Datei A am Ende eine Leerzeile - demnach müssten die Zeilen 36 und 37 so ergänzt werden:
    If Trim(Inhalt_Datei01(i)) <> "" Then  
        Satz = Split(Inhalt_Datei01(i), Delim) 'Datensatz (Zeile) zerlegen  
        If Not d.Exists(Satz(1)) Then d.Add Satz(1), Satz(15) 'Feld 2 = Schlüssel, Feld 16 = EAN  
    End If
- analog dazu vermutlich auch für die "Inhalt_Dati02"-Schleife.

Alternativ dazu könntest Du auch mit
    If UBound(Satz) >= 15 Then d.Add Satz(1), Satz(15) 'Feld 2 = Schlüssel, Feld 16 = EAN
als Zeile 37 nur eine Zuweisung vornehmen, wenn genügend Felder gefunden wurden ...

Grüße
bastla
Member: BadFsaadKl
BadFsaadKl Apr 30, 2014 at 18:21:22 (UTC)
Goto Top
Hi Bastla,

soweit sogut, das Script bricht mir jetzt zwar nicht mehr, und läuft auch erfolgreich durch.
Aber irgendwie übernimmt das Script nicht die EAN Nummern in die Ausgabedatei face-sad.
Das Feld bleibt hierbei leer.

8852;;41777081;../info_images/12882_0.jpg;1;;1000.00;;0;7;41014500

Vor der 1000.00 müsste hier eigentlich die EAN Nummer jetzt übernommen sein.

in File A ist die EAN auch vorhanden, an 16ter Stelle. Also Laut Array stelle 15, das würde ja soweit passen.
XTSOL;41014500;10000;0;5;default;1_100FM;0;32.353;;;;1;1;0.00;8714572047791;1;0.00;default;0;0;0.0000;12882_0.jpg;

Hast du ne Idee woran das liegen kann ?

Gruß
Bad
Member: bastla
bastla Apr 30, 2014 at 18:35:56 (UTC)
Goto Top
Hallo BadFsaadKl!

Wenn ich die Zeile mit der fehlenden EAN aus Deinem Beispiel oben mit Deinem letzten Beispiel vergleiche:
8852;41777081;../info_images/12882_0.jpg;1;;;hier müsste die EAN stehen;1000.00;0;7;41014500
8852;;41777081;../info_images/12882_0.jpg;1;;1000.00;;0;7;41014500
fällt mir etwas auf - Dir auch?

Zähl mal bis 7 ... face-wink

Grüße
bastla
Member: BadFsaadKl
BadFsaadKl Apr 30, 2014 at 18:49:35 (UTC)
Goto Top
Hi Bastla,

Glaube muss mich entschuldigen, hatte glaub bei meinem Bespiel ein Semikolon zu viel entfernt.

Anbei aber mal der komplette auszug, und Vergleich der Files wie sie mir vorliegen:
File A:
XTSOL;41014500;10000;0;5;default;1_100FM;0;32.353;;;;1;1;0.00;8714572047791
File B:
8852;;41777081;../info_images/12882_0.jpg;;1; ;1000.00;0;7;41014500
Ausgabe:
8852;;41777081;../info_images/12882_0.jpg;;1; ;1000.00;0;7;41014500

Und hier passt es doch aber, oder ?
In File B bzw. Ausgabe müsste die EAN an die 7te Stelle.

Oder steh ich jetzt irgendwie auf dem schlauch ?

Gruß
Bad
Member: bastla
bastla Apr 30, 2014 at 18:57:06 (UTC)
Goto Top
Hallo Hallo BadFsaadKl!

Jetzt hast Du anstatt der EAN ein Leerzeichen - wenn dem wirklich so sein sollte, müsstest Du Zeile 42 auf
If Trim(Satz(6)) = "" Then 'EAN in Feld 7 fehlt
ändern (kannst Du aber auf jeden Fall machen) ...

Grüße
bastla
Member: BadFsaadKl
BadFsaadKl Apr 30, 2014 at 19:17:52 (UTC)
Goto Top
BASTLA....
Du bist mein Held !!!
Danke dir...

Sag mal wenn ich jetzt noch nen weiteres Feld abgleichen wöllte, müsste ich das doch nur als neuen "Satz" anfügen, oder ?
In File A hab ich ein Feld 14, welches ich dann in File B an Stelle 24 bringen würde.

Würde ich jetzt wie folgt machen:
Set d = CreateObject("Scripting.Dictionary")   
For i = 1 To UBound(Inhalt_Datei01) 'erste Zeile überspringen  
	if Trim(Inhalt_Datei01(i)) <> "" Then  
		Satz = Split(Inhalt_Datei01(i), Delim) 'Datensatz (Zeile) zerlegen   
		If Not d.Exists(Satz(1)) Then d.Add Satz(1), Satz(15), Satz(13) 'Feld 2 = Schlüssel, Feld 16 = EAN, Feld 13 = Status  
	End If
Next 

For i = 1 To UBound(Inhalt_Datei02) 'erste Zeile überspringen   
    Satz = Split(Inhalt_Datei02(i), Delim) 'Datensatz (Zeile) zerlegen   
	If Trim(Inhalt_Datei02(i)) <> "" Then	  
		If Trim(Satz(6)) = "" Then 'EAN in Feld 7 fehlt   
			If d.Exists(Satz(10)) Then 'Schlüssel lt Feld 11 vorhanden?   
				Satz(6) = d.Item(Satz(10)) 'EAN in Feld 7 übernehmen   
				Satz(23) = d.Item(Satz(23))
			Else 
				WScript.Echo "Für Zeile " & i + 1 & " keine EAN gefunden!"   
				'WScript.Quit   
			End If 
			Inhalt_Datei02(i) = Join(Satz, Delim) 'Satz überschreiben   
		End If 
	End If
Next 

Oder bringe ich hier jetzt noch was mit den Satz-Array durcheinander ?

In Zeile 5 habe ich es mit dekraliert, als Satz(13).
Aber glaub habe bei der Übergabe
Satz(23) = d.Item(Satz(23)) 
noch nen kleinen Denkfehler, oder ?

Gruß
Bad
Member: bastla
Solution bastla Apr 30, 2014, updated at May 02, 2014 at 15:33:47 (UTC)
Goto Top
Hallo BadFsaadKl!

Schau Dir einmal das Dictionary genauer an: http://msdn.microsoft.com/en-us/library/x4k5wbx4%28v=vs.84%29.aspx

Du kannst zu jedem Schlüssel nur einen Wert speichern - daher entweder die beiden benötigten Werte zusammenfassen und danach wieder trennen, oder (wenn es wirklich nur 2 Werte sein sollten) ein zweites Dictionary erstellen und den zweiten Wert dort ablegen / heraussuchen.

Möglichkeit 1 sähe etwa so aus:
In die Liste schreiben:
If Not d.Exists(Satz(1)) Then d.Add Satz(1), Satz(15) & Delim & Satz(13) 'Feld 2 = Schlüssel, Feld 16 = EAN und Feld 14 = Status, getrennt durch ";" (Delim) als Wert speichern
Aus der Liste lesen:
			If d.Exists(Satz(10)) Then 'Schlüssel lt Feld 11 vorhanden?  
                                Werte = Split(d.Item(Satz(10)), Delim) 'zum Schlüssel gespeicherte Werte (ein String) in Array einlesen; dazu anhand des Delimiters ";" trennen  
				Satz(6) = Werte(0) 'EAN in Feld 7 übernehmen   
				Satz(23) = Werte(1) 'Status in Feld 24 übernehmen  
Nach diesem Muster kannst Du dann auch 3 oder mehr Werte abgleichen.

Grüße
bastla
Member: BadFsaadKl
BadFsaadKl Apr 30, 2014 at 19:49:23 (UTC)
Goto Top
Hi Bastla,

klingt irgendwie kompliziert %).

Ja, das sind nur 2 Werte...
Einmal die EAN Nummer, und der zweite Wert ist entweder eine 1 oder 0.

Äh, blöde Frage.
Wie speichere ich in diesem Zusammenhang die beiden Zahlen als Wert ab ?
Wo mach ich hier die Deklaration ?

Ist ja bestimmt wieder mit
Werte = Split...

Gruß
Bad
Member: bastla
bastla Apr 30, 2014 at 21:01:14 (UTC)
Goto Top
Hallo BadFsaadKl!
Wie speichere ich in diesem Zusammenhang die beiden Zahlen als Wert ab ?
Steht doch schon da: Der Status ist in Satz(13) zu finden und wird einfach zusammen mit der EAN gespeichert, sodass lt Deinem Beispiel für den Key "41014500" der Wert "8714572047791;1" abgelegt wird - beim Auslesen entsteht dann per Split das Array "Werte", wobei in Werte(0) "8714572047791" und in Werte(1) eben "1" enthalten ist.

Grüße
bastla