Inhalt einer XML Datei per Batch bzw. Script ändern
Hallo zusammen,
ich versuche mich schon seit mehreren Tagen an der Lösung untenstehenden Problems komme aber leider nicht weiter. Diverse Versuche aufgrund ähnlicher Threads scheitertern kläglich. Ich hoffe daher auf Eure Hilfe. Bin absoluter Script Novize.
Ich bekomme taeglich mehrere XML Dateien geliefert welche in ein Warenwirtschaftssystem eingelesen werden sollen.
Leider kann ich das WAWI Programm nicht dazu bringen alle für mich wichtigen Inhalte der XML Datei zu verarbeiten. Das gelieferte XML Format lässt sich durch den Lieferer leider nicht ändern. (IPad APP)
Es muss demzufolge der Inhalt der XML in mindestens zwei Bereichen geändert werden damit ich sie komplett verarbeiten kann.
1. Der Inhalt zwischen <arbeiten></arbeiten> in Zeile 11-13 sollte den wert zwischen <arbeitszeitBeginn></arbeitszeitBeginn> in Zeile 50 ersetzen. Die dortigen Werte sind für mich unwichtig, den datensatz kann ich aber dann entsprechend zuordnen. Schön wäre, wenn die Zeilenumbrüche erhalten bleiben, ist aber nicht zwingend.
2. Bei dem Wert zwischen <arbeitszeit></arbeitszeit> in Zeile 49 muß das "h" weg.
3. Ein fester Wert z.B. 1050 sollte den Wert zwischen <arbeitszeitEnde></arbeitszeitEnde> in Zeile 51 ersetzen.
4. Schön wäre, wenn das script alle XML Dateien die in einem bestimmten Verzeichniss liegen entsprechend abarbeitet.
Mit den Zeilennummern kann in dem Script nicht gearbeitet werden da sie variieren.
So sieht die gelieferte XML datei aus:
Ich hoffe es kann mir jemand weiterhelfen.
Leider kann ich das WAWI Programm nicht dazu bringen alle für mich wichtigen Inhalte der XML Datei zu verarbeiten. Das gelieferte XML Format lässt sich durch den Lieferer leider nicht ändern. (IPad APP)
Es muss demzufolge der Inhalt der XML in mindestens zwei Bereichen geändert werden damit ich sie komplett verarbeiten kann.
1. Der Inhalt zwischen <arbeiten></arbeiten> in Zeile 11-13 sollte den wert zwischen <arbeitszeitBeginn></arbeitszeitBeginn> in Zeile 50 ersetzen. Die dortigen Werte sind für mich unwichtig, den datensatz kann ich aber dann entsprechend zuordnen. Schön wäre, wenn die Zeilenumbrüche erhalten bleiben, ist aber nicht zwingend.
2. Bei dem Wert zwischen <arbeitszeit></arbeitszeit> in Zeile 49 muß das "h" weg.
3. Ein fester Wert z.B. 1050 sollte den Wert zwischen <arbeitszeitEnde></arbeitszeitEnde> in Zeile 51 ersetzen.
4. Schön wäre, wenn das script alle XML Dateien die in einem bestimmten Verzeichniss liegen entsprechend abarbeitet.
Mit den Zeilennummern kann in dem Script nicht gearbeitet werden da sie variieren.
So sieht die gelieferte XML datei aus:
<?xml version="1.0" encoding="UTF-8"?>
<stundenbericht>
<rechnungsadresse>10101
Testvorname Testnachnme
Teststrasse 11
12345 Testort
Deutschland</rechnungsadresse>
<ausfuehrungsort/>
<berichtNr>14</berichtNr>
<arbeiten>Leistung 1
Leistung 2
Leistung 3</arbeiten>
<material/>
<materialeintrag>
<bezeichnung>Testartikel</bezeichnung>
<artikelnr>12345</artikelnr>
<menge>1</menge>
<verpackungseinheit/>
<einzelpreis/>
<gesamtpreis>0,00</gesamtpreis>
</materialeintrag>
<materialeintrag>
<bezeichnung>Testartikel2</bezeichnung>
<artikelnr>12346</artikelnr>
<menge>1</menge>
<verpackungseinheit/>
<einzelpreis/>
<gesamtpreis>0,00</gesamtpreis>
</materialeintrag>
<materialeintrag>
<bezeichnung>Testartikel3</bezeichnung>
<artikelnr>12347</artikelnr>
<menge>1</menge>
<verpackungseinheit/>
<einzelpreis/>
<gesamtpreis>0,00</gesamtpreis>
</materialeintrag>
<gesamtpreisNetto>0,00</gesamtpreisNetto>
<steuer>0,00</steuer>
<gesamtpreisBrutto>0,00</gesamtpreisBrutto>
<datum>05.08.11</datum>
<taetigkeit>
<datum>05.08.11</datum>
<fahrzeit/>
<fahrzeitAbfahrt/>
<fahrzeitAnkunft/>
<fahrstrecke/>
<arbeitszeit>0,75h</arbeitszeit>
<arbeitszeitBeginn>23:05</arbeitszeitBeginn>
<arbeitszeitEnde>23:50</arbeitszeitEnde>
<pausenzeit/>
<pausenzeitBeginn/>
<pausenzeitEnde/>
<pausenzeit2/>
<pausenzeit2Beginn/>
<pausenzeit2Ende/>
<name/>
</taetigkeit>
<auswahllisteBezeichnung1>Pos</auswahllisteBezeichnung1>
<auswahleintrag1/>
<unterzeichner/>
</stundenbericht>
33 Antworten
- LÖSUNG Friemler schreibt am 06.08.2011 um 01:29:03 Uhr
- LÖSUNG twin850 schreibt am 06.08.2011 um 01:51:19 Uhr
- LÖSUNG Friemler schreibt am 06.08.2011 um 02:10:13 Uhr
- LÖSUNG twin850 schreibt am 06.08.2011 um 02:22:52 Uhr
- LÖSUNG Friemler schreibt am 06.08.2011 um 12:12:10 Uhr
- LÖSUNG bastla schreibt am 06.08.2011 um 12:43:23 Uhr
- LÖSUNG rubberman schreibt am 06.08.2011 um 12:55:53 Uhr
- LÖSUNG Friemler schreibt am 06.08.2011 um 13:24:29 Uhr
- LÖSUNG rubberman schreibt am 06.08.2011 um 14:12:33 Uhr
- LÖSUNG Friemler schreibt am 06.08.2011 um 14:17:01 Uhr
- LÖSUNG rubberman schreibt am 06.08.2011 um 14:12:33 Uhr
- LÖSUNG bastla schreibt am 06.08.2011 um 13:51:02 Uhr
- LÖSUNG rubberman schreibt am 06.08.2011 um 14:05:19 Uhr
- LÖSUNG Friemler schreibt am 06.08.2011 um 13:24:29 Uhr
- LÖSUNG Friemler schreibt am 06.08.2011 um 12:57:03 Uhr
- LÖSUNG bastla schreibt am 06.08.2011 um 13:54:40 Uhr
- LÖSUNG Friemler schreibt am 06.08.2011 um 14:00:36 Uhr
- LÖSUNG twin850 schreibt am 06.08.2011 um 21:01:59 Uhr
- LÖSUNG bastla schreibt am 06.08.2011 um 21:56:12 Uhr
- LÖSUNG rubberman schreibt am 06.08.2011 um 22:14:39 Uhr
- LÖSUNG twin850 schreibt am 08.08.2011 um 12:22:50 Uhr
- LÖSUNG rubberman schreibt am 08.08.2011 um 14:50:53 Uhr
- LÖSUNG twin850 schreibt am 08.08.2011 um 16:13:46 Uhr
- LÖSUNG rubberman schreibt am 08.08.2011 um 19:46:45 Uhr
- LÖSUNG twin850 schreibt am 08.08.2011 um 21:39:48 Uhr
- LÖSUNG rubberman schreibt am 08.08.2011 um 21:47:32 Uhr
- LÖSUNG twin850 schreibt am 08.08.2011 um 23:56:27 Uhr
- LÖSUNG rubberman schreibt am 09.08.2011 um 01:05:54 Uhr
- LÖSUNG twin850 schreibt am 09.08.2011 um 16:32:38 Uhr
- LÖSUNG rubberman schreibt am 09.08.2011 um 18:51:45 Uhr
- LÖSUNG Friemler schreibt am 09.08.2011 um 18:55:31 Uhr
- LÖSUNG rubberman schreibt am 09.08.2011 um 19:08:25 Uhr
- LÖSUNG twin850 schreibt am 09.08.2011 um 20:22:41 Uhr
- LÖSUNG rubberman schreibt am 09.08.2011 um 19:08:25 Uhr
- LÖSUNG twin850 schreibt am 09.08.2011 um 16:32:38 Uhr
- LÖSUNG rubberman schreibt am 09.08.2011 um 01:05:54 Uhr
- LÖSUNG twin850 schreibt am 08.08.2011 um 23:56:27 Uhr
- LÖSUNG rubberman schreibt am 08.08.2011 um 21:47:32 Uhr
- LÖSUNG twin850 schreibt am 08.08.2011 um 21:39:48 Uhr
- LÖSUNG rubberman schreibt am 08.08.2011 um 19:46:45 Uhr
- LÖSUNG twin850 schreibt am 08.08.2011 um 16:13:46 Uhr
- LÖSUNG rubberman schreibt am 08.08.2011 um 14:50:53 Uhr
- LÖSUNG twin850 schreibt am 08.08.2011 um 12:22:50 Uhr
- LÖSUNG rubberman schreibt am 06.08.2011 um 22:14:39 Uhr
- LÖSUNG bastla schreibt am 06.08.2011 um 21:56:12 Uhr
- LÖSUNG twin850 schreibt am 06.08.2011 um 21:01:59 Uhr
- LÖSUNG Friemler schreibt am 06.08.2011 um 14:00:36 Uhr
- LÖSUNG bastla schreibt am 06.08.2011 um 13:54:40 Uhr
- LÖSUNG rubberman schreibt am 06.08.2011 um 12:55:53 Uhr
- LÖSUNG bastla schreibt am 06.08.2011 um 12:43:23 Uhr
- LÖSUNG Friemler schreibt am 06.08.2011 um 12:12:10 Uhr
- LÖSUNG twin850 schreibt am 06.08.2011 um 02:22:52 Uhr
- LÖSUNG Friemler schreibt am 06.08.2011 um 02:10:13 Uhr
- LÖSUNG twin850 schreibt am 06.08.2011 um 01:51:19 Uhr
- LÖSUNG riatnep schreibt am 02.10.2013 um 14:12:13 Uhr
- LÖSUNG rubberman schreibt am 02.10.2013 um 22:24:12 Uhr
LÖSUNG 06.08.2011 um 01:29 Uhr
Hallo twin850,
Deine XML-Datei ist laut Header in der Codierung UTF-8 gespeichert. Solange keine Umlaute (äöüßÄÖÜ) oder andere Zeichen mit einem Code größer 127 in den Daten vorkommen (kannst Du das garantieren?), ließe sich das ganze noch mit Batchscript verarbeiten, die Aufgabe mit Batchscript zu lösen ist aber umständlich. Dazu wäre VBScript viel besser geeignet. Damit lassen sich aber nur Unicode-Dateien in der Codierung UTF-16 Little Endian verarbeiten.
Du solltest zuerstmal klären, ob die iPad-App die Datei auch als UTF-16 LE oder ANSI (Codepage 1252) codieren kann, bevor wir hier Code für die Tonne produzieren.
Gruß
Friemler
Deine XML-Datei ist laut Header in der Codierung UTF-8 gespeichert. Solange keine Umlaute (äöüßÄÖÜ) oder andere Zeichen mit einem Code größer 127 in den Daten vorkommen (kannst Du das garantieren?), ließe sich das ganze noch mit Batchscript verarbeiten, die Aufgabe mit Batchscript zu lösen ist aber umständlich. Dazu wäre VBScript viel besser geeignet. Damit lassen sich aber nur Unicode-Dateien in der Codierung UTF-16 Little Endian verarbeiten.
Du solltest zuerstmal klären, ob die iPad-App die Datei auch als UTF-16 LE oder ANSI (Codepage 1252) codieren kann, bevor wir hier Code für die Tonne produzieren.
Gruß
Friemler
LÖSUNG 06.08.2011 um 01:51 Uhr
Hallo Friemler,
danke für die Antwort zu später Stunde. Irgendwie sind wir alle Leidensgenossen was die Arbeitszeiten angeht.
Die gelieferten XML Dateien sind so wie sie sind. Habe schon Kontakt mit dem Hersteller der APP aufgenommen aber da lässt sich wohl nichts machen.
Hauptsächlich sind die von mir benötigten Daten numerisch. (Kundennummer, Artikelnummer u.s.w.) Es werden zwar auch diverse Texte in die XML mit übergeben (z.B. Name und Anschrift), diese werte ich aber gar nicht aus. Von daher wäre es nicht schlimm wenn die Umlaute verloren oder zerhauen werden.
Als ich die Tage selbst mit VB herumexperimentiert habe hatte ich aber keine Probleme mit der Codierung. (Zumindestens keine Fehlermeldungen die auf ein Problem mit der Codierung hindeuten.) Kann es sein, das die Angabe im Header nicht mit der echten Codierung übereinstimmt ?
Gruß
twin850
danke für die Antwort zu später Stunde. Irgendwie sind wir alle Leidensgenossen was die Arbeitszeiten angeht.
Die gelieferten XML Dateien sind so wie sie sind. Habe schon Kontakt mit dem Hersteller der APP aufgenommen aber da lässt sich wohl nichts machen.
Hauptsächlich sind die von mir benötigten Daten numerisch. (Kundennummer, Artikelnummer u.s.w.) Es werden zwar auch diverse Texte in die XML mit übergeben (z.B. Name und Anschrift), diese werte ich aber gar nicht aus. Von daher wäre es nicht schlimm wenn die Umlaute verloren oder zerhauen werden.
Als ich die Tage selbst mit VB herumexperimentiert habe hatte ich aber keine Probleme mit der Codierung. (Zumindestens keine Fehlermeldungen die auf ein Problem mit der Codierung hindeuten.) Kann es sein, das die Angabe im Header nicht mit der echten Codierung übereinstimmt ?
Gruß
twin850
LÖSUNG 06.08.2011 um 02:10 Uhr
Hallo twin850,
war evtl. missverständlich ausgedrückt: VBScript kann außer Unicode-Dateien natürlich auch ANSI-Dateien (Codepage 1252) korrekt verarbeiten. Die Zeichencodes zwischen 32 (Leerzeichen) und 127 sind sowohl in ASCII, ANSI und UTF-8 gleich.
Warum Du keine Probleme bei Deinen Experimenten hattest, könnte entweder daran liegen, dass die Codierung im Header tatsächlich falsch angegeben ist und das ganze eine ANSI-Datei ist, oder sie wurde in UTF-8 codiert aber ohne Byte Order Mark (BOM) geschrieben. Die BOM wird in die ersten 3 Bytes einer UTF-8-Datei geschrieben, die die Werte EF BB BF (hexadezimal) haben. Das könntest Du mit einem Hex-Editor oder dem Befehl type "NameDerXMLDatei" prüfen. Wenn die ersten drei Zeichen der ersten Zeile irgendwelche seltsamen Zeichen sind, hat die Datei eine BOM.
Gruß
Friemler
war evtl. missverständlich ausgedrückt: VBScript kann außer Unicode-Dateien natürlich auch ANSI-Dateien (Codepage 1252) korrekt verarbeiten. Die Zeichencodes zwischen 32 (Leerzeichen) und 127 sind sowohl in ASCII, ANSI und UTF-8 gleich.
Warum Du keine Probleme bei Deinen Experimenten hattest, könnte entweder daran liegen, dass die Codierung im Header tatsächlich falsch angegeben ist und das ganze eine ANSI-Datei ist, oder sie wurde in UTF-8 codiert aber ohne Byte Order Mark (BOM) geschrieben. Die BOM wird in die ersten 3 Bytes einer UTF-8-Datei geschrieben, die die Werte EF BB BF (hexadezimal) haben. Das könntest Du mit einem Hex-Editor oder dem Befehl type "NameDerXMLDatei" prüfen. Wenn die ersten drei Zeichen der ersten Zeile irgendwelche seltsamen Zeichen sind, hat die Datei eine BOM.
Gruß
Friemler
LÖSUNG 06.08.2011 um 02:22 Uhr
Hallo Friemler,
ich sehe schon ich wäre mit meinem (Un)Wissen völlig untergegangen.
So sieht der Anfang der . xml Datei aus. Auch mit type konnte ich keine seltsamen Zeichen erkennen.
Gruß
ich sehe schon ich wäre mit meinem (Un)Wissen völlig untergegangen.
So sieht der Anfang der . xml Datei aus. Auch mit type konnte ich keine seltsamen Zeichen erkennen.
3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D225554462D38223F3E0A3C7374756E64656E626572696368743E0A
LÖSUNG 06.08.2011 um 12:12 Uhr
Moin twin850,
teste mal folgendes:
Das Script z.B. als Replace.vbs speichern.
Aufruf
Du kannst in Zeile 5 den festen Wert vorgeben, der in Zeile 51 der (Beispiel-)XML-Datei eingefügt werden soll, und das Icon des Verzeichnisses, das die XML-Dateien enthält, per Drag&Drop auf das Icon des Scripts ziehen
oder
das Script folgendermaßen aufrufen
oder
das Script folgendermaßen aufrufen
In diesem Fall wird der Fixwert aus der Befehlszeile verwendet, auch wenn im Scriptcode ein anderer Wert gesetzt ist.
Es wird im selben Verzeichnis, in dem die Eingabedateien liegen, für jede Eingabedatei eine neue Ausgabedatei erzeugt, deren Namen um _Neu ergänzt wurden (aus z.B. Datei.xml wird Datei_Neu.xml).
Gruß
Friemler
teste mal folgendes:
Const ForReading = 1
Const AsASCII = 0
strFixedValue = "1050"
If WScript.Arguments.Count > 0 Then
Set objFSO = CreateObject("Scripting.FileSystemObject")
strSrcDir = objFSO.GetAbsolutePathName(WScript.Arguments(0))
If WScript.Arguments.Count > 1 Then strFixedValue = WScript.Arguments(1)
If objFSO.FolderExists(strSrcDir) Then
Set objRegExp = New RegExp
objRegExp.Global = False
objRegExp.IgnoreCase = True
For Each objFile In objFSO.GetFolder(strSrcDir).Files
If LCase(objFSO.GetExtensionName(objFile.Name)) = "xml" Then
'Eingabedatei lesen
Set objInFile = objFile.OpenAsTextStream(ForReading, AsASCII)
strContent = objInFile.ReadAll
objInFile.Close
'Den Wert zwischen <arbeitszeitBeginn></arbeitszeitBeginn>
'durch den Wert zwischen <arbeiten></arbeiten> ersetzen
objRegExp.Pattern = "<arbeiten>"
Set colMatch1 = objRegExp.Execute(strContent)
objRegExp.Pattern = "</arbeiten>"
Set colMatch2 = objRegExp.Execute(strContent)
If (colMatch1.Count > 0) And (colMatch2.Count > 0) Then
intKeyValueStart = colMatch1(0).FirstIndex + 1 + colMatch1(0).Length
intKeyValueLen = colMatch2(0).FirstIndex + 1 - intKeyValueStart
strReplace = Mid(strContent, intKeyValueStart, intKeyValueLen)
objRegExp.Pattern = "(<arbeitszeitBeginn>).*(</arbeitszeitBeginn>)"
strContent = objRegExp.Replace(strContent, "$1" & strReplace & "$2")
End If
'Das h bei dem Wert zwischen <arbeitszeit></arbeitszeit> entfernen
objRegExp.Pattern = "(<arbeitszeit>)([0-9,]{1,}).{1,}(</arbeitszeit>)"
strContent = objRegExp.Replace(strContent, "$1$2$3")
'Den Wert zwischen <arbeitszeitEnde></arbeitszeitEnde>
'durch einen fixen Wert ersetzen
objRegExp.Pattern = "(<arbeitszeitEnde>).*(</arbeitszeitEnde>)"
strContent = objRegExp.Replace(strContent, "$1" & strFixedValue & "$2")
'Ausgabedaei schreiben
Set objOutFile = objFSO.CreateTextFile(objFSO.BuildPath(strSrcDir, objFSO.GetBaseName(objFile.Name) & "_Neu." & objFSO.GetExtensionName(objFile.Name)), True)
objOutFile.Write strContent
objOutFile.Close
End If
Next
End If
End If
Aufruf
Du kannst in Zeile 5 den festen Wert vorgeben, der in Zeile 51 der (Beispiel-)XML-Datei eingefügt werden soll, und das Icon des Verzeichnisses, das die XML-Dateien enthält, per Drag&Drop auf das Icon des Scripts ziehen
oder
das Script folgendermaßen aufrufen
cscript /nologo "Replace.vbs" "PfadDesVerzeichnissesMitDenXMLDateien"
das Script folgendermaßen aufrufen
cscript /nologo "Replace.vbs" "PfadDesVerzeichnissesMitDenXMLDateien" "FixerWert"
Es wird im selben Verzeichnis, in dem die Eingabedateien liegen, für jede Eingabedatei eine neue Ausgabedatei erzeugt, deren Namen um _Neu ergänzt wurden (aus z.B. Datei.xml wird Datei_Neu.xml).
Gruß
Friemler
LÖSUNG 06.08.2011 um 12:43 Uhr
Hallo twin850 und willkommen im Forum, hallo Friemler!
Mit etwas Verspätung (und nur mal zum Testen für eine einzelne Datei) mein (nicht unähnlicher
) Ansatz:
Im Zweifelsfall würde ich nur Quell- und Zieldateinamen als Parameter übernehmen und das Abarbeiten aller Dateien einem Batch überlassen ...
Grüße
bastla
Mit etwas Verspätung (und nur mal zum Testen für eine einzelne Datei) mein (nicht unähnlicher
Ein = "D:\Test.xml"
Aus = "D:\Korrigiert.xml"
FestWert = "1050"
Set fso = CreateObject("Scripting.FileSystemObject")
Set rE = New RegExp
T = fso.OpenTextFile(Ein).ReadAll
rE.Pattern = "<arbeiten>([\S\s]+)</arbeiten>"
Set Matches = rE.Execute(T)
If Matches.Count = 0 Then
WScript.Echo "Leistungsdaten nicht gefunden!"
WScript.Quit(1)
End If
Wert = Matches(0).SubMatches(0)
rE.Pattern = "<arbeitszeitBeginn>.*</arbeitszeitBeginn>"
T = rE.Replace(T, "<arbeitszeitBeginn>" & Wert & "</arbeitszeitBeginn>")
rE.Pattern = "(<arbeitszeit>[^h]*)(h)(</arbeitszeit>)"
T = rE.Replace(T, "$1$3")
rE.Pattern = "<arbeitszeitEnde>.*</arbeitszeitEnde>"
T = rE.Replace (T, "<arbeitszeitEnde>" & FestWert & "</arbeitszeitEnde>")
fso.CreateTextFile(Aus).Write T
Grüße
bastla
LÖSUNG 06.08.2011 um 12:55 Uhr
Hallo Zusammen.
Windows stellt doch extra zur Verarbeitung von XML Dateien ein ActiveX-Object zur Verfügung.
Für eine einzelne XML-Datei namens "test.xml" könnte das ganze dann so aussehen:
Wenn es so funktioniert, ist die Massenverarbeitung aller XML Dateien in einem Verzeichnis nur noch Makulatur.
Grüße
rubberman
<EDIT: bastlas Vorschlag berücksichtigt. />
Windows stellt doch extra zur Verarbeitung von XML Dateien ein ActiveX-Object zur Verfügung.
Für eine einzelne XML-Datei namens "test.xml" könnte das ganze dann so aussehen:
Const strXmlDoc = "test.xml"
Set objXmlDoc = CreateObject("Microsoft.XMLDOM")
objXmlDoc.async = False
objXmlDoc.load(strXmlDoc)
Set objNode1 = objXmlDoc.documentElement.SelectSingleNode("//arbeiten")
If objNode1 Is Nothing Then
MsgBox "Der Knoten ""arbeiten"" wurde nicht gefunden!", vbCritical, "Fehler"
WScript.Quit 1
End If
Set objNode2 = objXmlDoc.documentElement.SelectSingleNode("//taetigkeit/arbeitszeitBeginn")
If objNode2 Is Nothing Then
MsgBox "Der Knoten ""arbeitszeitBeginn"" wurde nicht gefunden!", vbCritical, "Fehler"
WScript.Quit 1
End If
objNode2.text = objNode1.text
Set objNode3 = objXmlDoc.documentElement.SelectSingleNode("//taetigkeit/arbeitszeit")
If objNode3 Is Nothing Then
MsgBox "Der Knoten ""arbeitszeit"" wurde nicht gefunden!", vbCritical, "Fehler"
WScript.Quit 1
End If
strArbeitszeit = objNode3.text
objNode3.text = Left(strArbeitszeit, Len(strArbeitszeit) - 1)
Set objNode4 = objXmlDoc.documentElement.SelectSingleNode("//taetigkeit/arbeitszeitEnde")
If objNode4 Is Nothing Then
MsgBox "Der Knoten ""arbeitszeitEnde"" wurde nicht gefunden!", vbCritical, "Fehler"
WScript.Quit 1
End If
objNode4.text = "1050"
objXmlDoc.save(strXmlDoc)
Set objXmlDoc = Nothing
Grüße
rubberman
<EDIT: bastlas Vorschlag berücksichtigt. />
LÖSUNG 06.08.2011 um 12:57 Uhr
LÖSUNG 06.08.2011 um 13:24 Uhr
LÖSUNG 06.08.2011 um 13:51 Uhr
LÖSUNG 06.08.2011 um 13:54 Uhr
LÖSUNG 06.08.2011 um 14:00 Uhr
Hallo bastla,
klar, das macht immer Sinn, so kann man ja voneinander lernen.
Gruß
Friemler
Zitat von @bastla:
so gesehen hatte es dann aber trotzdem etwas Sinn, auch meine Variante anzubieten ...
so gesehen hatte es dann aber trotzdem etwas Sinn, auch meine Variante anzubieten ...
klar, das macht immer Sinn, so kann man ja voneinander lernen.
Gruß
Friemler
LÖSUNG 06.08.2011 um 14:05 Uhr
LÖSUNG 06.08.2011 um 14:12 Uhr
Hallo Friemler,
eine Liste mit allen ActiveX Objekten und Ihrer Referenz würde vermutlich den Rahmen sprengen. Letztlich findest du eine solche Liste aber in der Registry.
Schau mal hier. Die Referenzen dazu findest du dann sicher im MSDN.
Grüße
rubberman
eine Liste mit allen ActiveX Objekten und Ihrer Referenz würde vermutlich den Rahmen sprengen. Letztlich findest du eine solche Liste aber in der Registry.
Schau mal hier. Die Referenzen dazu findest du dann sicher im MSDN.
Grüße
rubberman
LÖSUNG 06.08.2011 um 14:17 Uhr
LÖSUNG 06.08.2011 um 21:01 Uhr
Hallo zusammen,
was soll ich sagen, alle drei Vorschläge funktionieren einwandfrei und ich habe nun ein Luxusproblem. Welches Script nehme ich ?.
Friemlers Script ist ja fix und fertig da schon alle Dateien in einem Verzeichniss verarbeitet werden.
Ich werd noch ein bisschen testen und auch die Weiterverarbeitung der geänderten XML Dateien überprüfen.
Im Moment bleibt nur ein große D A N K E an alle.
was soll ich sagen, alle drei Vorschläge funktionieren einwandfrei und ich habe nun ein Luxusproblem. Welches Script nehme ich ?.
Friemlers Script ist ja fix und fertig da schon alle Dateien in einem Verzeichniss verarbeitet werden.
Ich werd noch ein bisschen testen und auch die Weiterverarbeitung der geänderten XML Dateien überprüfen.
Im Moment bleibt nur ein große D A N K E an alle.
LÖSUNG 06.08.2011 um 21:56 Uhr
Hallo twin850!
Du brauchst ja die Version von rubberman nur ein wenig zu ergänzen, etwa so:
und kannst sie dann per Batch wie folgt verwenden:
Anmerkungen:
Beides ungetestet
Wenn's "unattended" laufen soll, die Zeilen der Art
entweder auf
ändern oder durch ein vorangestelltes REM auskommentieren - die Dateien mit Fehler werden auf jeden Fall in der "Fehler.txt" protokolliert (und in der aktuellen Version auch durch die vorher erstellte Sicherungskopie ersetzt) ...
Grüße
bastla
[Edit] Gegen Fehler durch automatisches Wiederherstellen der Sicherungskopie zusätzlich abgesichert - ist aber eigentlich unnötig, da ja Änderungen ohnehin nur geschrieben werden, wenn das Script fehlerfrei durchläuft ... [/Edit]
Du brauchst ja die Version von rubberman nur ein wenig zu ergänzen, etwa so:
'XML_bearbeiten
If WScript.Arguments.Count = 0 Then
MsgBox "Keine Datei übergeben!", vbCritical, "Fehler"
WScript.Quit 2
End If
strXmlDoc = WScript.Arguments(0)
Set objXmlDoc = CreateObject("Microsoft.XMLDOM")
objXmlDoc.async = False
objXmlDoc.load(strXmlDoc)
Set objNode1 = objXmlDoc.documentElement.SelectSingleNode("//arbeiten")
If objNode1 Is Nothing Then
MsgBox "Der Knoten ""arbeiten"" wurde nicht gefunden!", vbCritical, "Fehler"
WScript.Quit 1
End If
Set objNode2 = objXmlDoc.documentElement.SelectSingleNode("//taetigkeit/arbeitszeitBeginn")
If objNode2 Is Nothing Then
MsgBox "Der Knoten ""arbeitszeitBeginn"" wurde nicht gefunden!", vbCritical, "Fehler"
WScript.Quit 1
End If
objNode2.text = objNode1.text
Set objNode3 = objXmlDoc.documentElement.SelectSingleNode("//taetigkeit/arbeitszeit")
If objNode3 Is Nothing Then
MsgBox "Der Knoten ""arbeitszeit"" wurde nicht gefunden!", vbCritical, "Fehler"
WScript.Quit 1
End If
strArbeitszeit = objNode3.text
objNode3.text = Left(strArbeitszeit, Len(strArbeitszeit) - 1)
Set objNode4 = objXmlDoc.documentElement.SelectSingleNode("//taetigkeit/arbeitszeitEnde")
If objNode4 Is Nothing Then
MsgBox "Der Knoten ""arbeitszeitEnde"" wurde nicht gefunden!", vbCritical, "Fehler"
WScript.Quit 1
End If
objNode4.text = "1050"
objXmlDoc.save(strXmlDoc)
Set objXmlDoc = Nothing
@echo off & setlocal
set "Verzeichnis=D:\XML"
set "Script=D:\XML_bearbeiten.vbs"
set "Fehler=%Verzeichnis%\Fehler.txt"
pushd "%Verzeichnis%"
del "%Fehler%"
for /f "delims=" %%i in ('dir /b /a-d *.xml') do (
copy "%%i" *.bak
echo Bearbeite: %%i
cscript //nologo "Script%" "%%i" || (
move "%%~ni.bak" *.xml
echo Fehler!
>>"%Fehler%" echo %%i
)
echo\
)
if exist "%Fehler%" notepad "%Fehler%"
popd
Beides ungetestet
Wenn's "unattended" laufen soll, die Zeilen der Art
MsgBox "Der Knoten ""arbeitszeitBeginn"" wurde nicht gefunden!", vbCritical, "Fehler"
WScript.Echo "Der Knoten ""arbeitszeitBeginn"" wurde nicht gefunden!"
Grüße
bastla
[Edit] Gegen Fehler durch automatisches Wiederherstellen der Sicherungskopie zusätzlich abgesichert - ist aber eigentlich unnötig, da ja Änderungen ohnehin nur geschrieben werden, wenn das Script fehlerfrei durchläuft ... [/Edit]
LÖSUNG 06.08.2011 um 22:14 Uhr
Hallo twin850, hallo bastla.
Ich würde dann, wie von Friemler vorgeschlagen, die Verarbeitung des Verzeichnisses auch im VBScript vornehmen, da der wiederholte Aufruf des Scripts eine Menge Zeit frisst.
Ungetestet:
Grüße
rubberman
Ich würde dann, wie von Friemler vorgeschlagen, die Verarbeitung des Verzeichnisses auch im VBScript vornehmen, da der wiederholte Aufruf des Scripts eine Menge Zeit frisst.
Ungetestet:
If WScript.Arguments.Count < 1 Then
WScript.Echo "Syntax:" & _
vbLf & "cscript //nologo """ & WScript.ScriptName & """ ""Pfad"" [""FixerWert""]" & _
vbLf & vbLF & "Returncodes:" & _
vbLf & "3 zu wenig Argumente" & _
vbLf & "2 Verzeichnis nicht gefunden" & _
vbLf & "1 eine oder Mehrere Dateien konnten nicht verarbeitet werden" & _
vbLf & "0 alle gefundenen Dateien erfolgreich verarbeitet" & vbLf
WScript.Quit 3
End If
Set objFSO = CreateObject("Scripting.FileSystemObject")
strSrcDir = objFSO.GetAbsolutePathName(WScript.Arguments(0))
If Not objFSO.FolderExists(strSrcDir) Then WScript.Quit 2
If WScript.Arguments.Count > 1 Then
strFixedValue = WScript.Arguments(1)
Else
strFixedValue = "1050"
End If
iSucc = 0
iErr = 0
For Each objFile In objFSO.GetFolder(strSrcDir).Files
If LCase(objFSO.GetExtensionName(objFile.Name)) = "xml" Then
If Process_XML(objFile.Path) Then
WScript.Echo """" & objFile.Name & """ - Verarbeitung erfolgreich."
iSucc = iSucc + 1
Else
WScript.Echo """" & objFile.Name & """ - Verarbeitung fehlgeschlagen."
iErr = iErr + 1
End If
End If
Next
WScript.Echo vbLf & iSucc + iErr & " Dateien verarbeitet." & _
vbLf & iSucc & " erfolreich" & _
vbLf & iErr & " fehlgeschlagen" & vbLf
If iErr > 0 Then WScript.Quit 1
Function Process_XML(ByRef strXmlDoc)
Set objXmlDoc = CreateObject("Microsoft.XMLDOM")
objXmlDoc.async = False
objXmlDoc.load(strXmlDoc)
Set objNode1 = objXmlDoc.documentElement.SelectSingleNode("//arbeiten")
If objNode1 Is Nothing Then
Process_XML = False
Exit Function
End If
Set objNode2 = objXmlDoc.documentElement.SelectSingleNode("//taetigkeit/arbeitszeitBeginn")
If objNode2 Is Nothing Then
Process_XML = False
Exit Function
End If
objNode2.text = objNode1.text
Set objNode3 = objXmlDoc.documentElement.SelectSingleNode("//taetigkeit/arbeitszeit")
If objNode3 Is Nothing Then
Process_XML = False
Exit Function
End If
strArbeitszeit = objNode3.text
objNode3.text = Left(strArbeitszeit, Len(strArbeitszeit) - 1)
Set objNode4 = objXmlDoc.documentElement.SelectSingleNode("//taetigkeit/arbeitszeitEnde")
If objNode4 Is Nothing Then
Process_XML = False
Exit Function
End If
objNode4.text = strFixedValue
objXmlDoc.save(strXmlDoc)
Set objXmlDoc = Nothing
Process_XML = True
End Function
rubberman
LÖSUNG 08.08.2011 um 12:22 Uhr
Hallo Rubbermann, bastla, Friemler,
nachdem ich das WE rumexperimentiert habe, habe ich mich grundsätzlich für die Variante von rubbermann entschieden da ich das Script am ehesten verstehe und selbst Anpassungen vornehmen konnte was in Zukunft evtl. hilfreich ist.
@Friemler
Trotzdem DANKE. Auch Deine Variante geht.
@Rubbermann
Ich habe das Script um einen weiteren Eintrag ergänzt.
Damit wird der Wert Rechungsadresse auf 5 Stellen gekürzt (Das ist die Kundennummer die ich als einzelnen Wert benötige). Ich hoffe das es so richtig ist.
Nun habe ich eine generelles Problem. Bei der IpadAPP handelt es sich um einen Lieferschein für Leistungen und Material. Nun passiert es, wenn nur Material geliefert wird, das das Script nicht durchläuft da einzelne Objekte der Leistungserfassung gar nicht vorhanden sind.
So sieht die gelieferte XML Datei ohne erfasste Arbeitszeit aus.
Es fehlt hier der komplette Bereich Tätigkeit.
Kann man erreichen das das Script immer durchläuft damit in dem Fall immer noch das Objekt "Rechnungsadresse" bearbeitet wird ?
nachdem ich das WE rumexperimentiert habe, habe ich mich grundsätzlich für die Variante von rubbermann entschieden da ich das Script am ehesten verstehe und selbst Anpassungen vornehmen konnte was in Zukunft evtl. hilfreich ist.
@Friemler
Trotzdem DANKE. Auch Deine Variante geht.
@Rubbermann
Ich habe das Script um einen weiteren Eintrag ergänzt.
Set objNode5 = objXmlDoc.documentElement.SelectSingleNode("//rechnungsadresse")
If objNode5 Is Nothing Then
MsgBox "Der Knoten ""Rechnungsadresse"" wurde nicht gefunden!", vbCritical, "Fehler"
WScript.Quit 1
End If
strrechnungsadresse = objNode5.text
objNode5.text = Left(strrechnungsadresse,5)
Nun habe ich eine generelles Problem. Bei der IpadAPP handelt es sich um einen Lieferschein für Leistungen und Material. Nun passiert es, wenn nur Material geliefert wird, das das Script nicht durchläuft da einzelne Objekte der Leistungserfassung gar nicht vorhanden sind.
So sieht die gelieferte XML Datei ohne erfasste Arbeitszeit aus.
<?xml version="1.0" encoding="UTF-8"?>
<stundenbericht>
<rechnungsadresse>10101
Testvorname Testnachnme
Teststrasse 11
12345 Testort
Deutschland</rechnungsadresse>
<ausfuehrungsort/>
<berichtNr>14</berichtNr>
<arbeiten/>
<material/>
<materialeintrag>
<bezeichnung>Testartikel</bezeichnung>
<artikelnr>12345</artikelnr>
<menge>1</menge>
<verpackungseinheit/>
<einzelpreis/>
<gesamtpreis>0,00</gesamtpreis>
</materialeintrag>
<materialeintrag>
<bezeichnung>Testartikel2</bezeichnung>
<artikelnr>12346</artikelnr>
<menge>1</menge>
<verpackungseinheit/>
<einzelpreis/>
<gesamtpreis>0,00</gesamtpreis>
</materialeintrag>
<materialeintrag>
<bezeichnung>Testartikel3</bezeichnung>
<artikelnr>12347</artikelnr>
<menge>1</menge>
<verpackungseinheit/>
<einzelpreis/>
<gesamtpreis>0,00</gesamtpreis>
</materialeintrag>
<gesamtpreisNetto>0,00</gesamtpreisNetto>
<steuer>0,00</steuer>
<gesamtpreisBrutto>0,00</gesamtpreisBrutto>
<datum>05.08.11</datum>
<auswahllisteBezeichnung1>Pos</auswahllisteBezeichnung1>
<auswahleintrag1/>
<unterzeichner/>
</stundenbericht>
Kann man erreichen das das Script immer durchläuft damit in dem Fall immer noch das Objekt "Rechnungsadresse" bearbeitet wird ?
LÖSUNG 08.08.2011 um 14:50 Uhr
LÖSUNG 08.08.2011 um 16:13 Uhr
Hallo rubberman,
folgendes Script verwende ich
folgendes Script verwende ich
If WScript.Arguments.Count < 1 Then
WScript.Echo "Syntax:" & _
vbLf & "cscript //nologo """ & WScript.ScriptName & """ ""Pfad"" [""FixerWert""]" & _
vbLf & vbLF & "Returncodes:" & _
vbLf & "3 zu wenig Argumente" & _
vbLf & "2 Verzeichnis nicht gefunden" & _
vbLf & "1 eine oder Mehrere Dateien konnten nicht verarbeitet werden" & _
vbLf & "0 alle gefundenen Dateien erfolgreich verarbeitet" & vbLf
WScript.Quit 3
End If
Set objFSO = CreateObject("Scripting.FileSystemObject")
strSrcDir = objFSO.GetAbsolutePathName(WScript.Arguments(0))
If Not objFSO.FolderExists(strSrcDir) Then WScript.Quit 2
If WScript.Arguments.Count > 1 Then
strFixedValue = WScript.Arguments(1)
Else
strFixedValue = "1050"
End If
iSucc = 0
iErr = 0
For Each objFile In objFSO.GetFolder(strSrcDir).Files
If LCase(objFSO.GetExtensionName(objFile.Name)) = "xml" Then
If Process_XML(objFile.Path) Then
WScript.Echo """" & objFile.Name & """ - Verarbeitung erfolgreich."
iSucc = iSucc + 1
Else
WScript.Echo """" & objFile.Name & """ - Verarbeitung fehlgeschlagen."
iErr = iErr + 1
End If
End If
Next
WScript.Echo vbLf & iSucc + iErr & " Dateien verarbeitet." & _
vbLf & iSucc & " erfolreich" & _
vbLf & iErr & " fehlgeschlagen" & vbLf
If iErr > 0 Then WScript.Quit 1
Function Process_XML(ByRef strXmlDoc)
Set objXmlDoc = CreateObject("Microsoft.XMLDOM")
objXmlDoc.async = False
objXmlDoc.load(strXmlDoc)
Set objNode1 = objXmlDoc.documentElement.SelectSingleNode("//arbeiten")
If objNode1 Is Nothing Then
Process_XML = False
Exit Function
End If
Set objNode2 = objXmlDoc.documentElement.SelectSingleNode("//taetigkeit/arbeitszeitBeginn")
If objNode2 Is Nothing Then
Process_XML = False
Exit Function
End If
objNode2.text = objNode1.text
Set objNode3 = objXmlDoc.documentElement.SelectSingleNode("//taetigkeit/arbeitszeit")
If objNode3 Is Nothing Then
Process_XML = False
Exit Function
End If
strArbeitszeit = objNode3.text
objNode3.text = Left(strArbeitszeit, Len(strArbeitszeit) - 1)
Set objNode4 = objXmlDoc.documentElement.SelectSingleNode("//taetigkeit/arbeitszeitEnde")
If objNode4 Is Nothing Then
Process_XML = False
Exit Function
End If
objNode4.text = strFixedValue
Set objNode5 = objXmlDoc.documentElement.SelectSingleNode("//rechnungsadresse")
If objNode5 Is Nothing Then
Process_XML = False
Exit Function
End If
strrechnungsadresse = objNode5.text
objNode5.text = Left(strrechnungsadresse,5)
objXmlDoc.save(strXmlDoc)
Set objXmlDoc = Nothing
Process_XML = True
End Function
LÖSUNG 08.08.2011 um 19:46 Uhr
Hallo twin850,
habe leider erst nach Feierabend die Zeit gefunden ...
Mit ein paar kleinen Anpassungen sieht das Script nun so aus:
Hoffe das funktioniert wie gewünscht.
Grüße
rubberman
habe leider erst nach Feierabend die Zeit gefunden ...
Mit ein paar kleinen Anpassungen sieht das Script nun so aus:
If WScript.Arguments.Count < 1 Then
WScript.Echo "Syntax:" & _
vbLf & "cscript //nologo """ & WScript.ScriptName & """ ""Pfad"" [""FixerWert""]" & _
vbLf & vbLF & "Returncodes:" & _
vbLf & "3 zu wenig Argumente" & _
vbLf & "2 Verzeichnis nicht gefunden" & _
vbLf & "1 eine oder Mehrere Dateien konnten nicht verarbeitet werden" & _
vbLf & "0 alle gefundenen Dateien erfolgreich verarbeitet" & vbLf
WScript.Quit 3
End If
Set objFSO = CreateObject("Scripting.FileSystemObject")
strSrcDir = objFSO.GetAbsolutePathName(WScript.Arguments(0))
If Not objFSO.FolderExists(strSrcDir) Then WScript.Quit 2
If WScript.Arguments.Count > 1 Then
strFixedValue = WScript.Arguments(1)
Else
strFixedValue = "1050"
End If
iSucc = 0
iErr = 0
For Each objFile In objFSO.GetFolder(strSrcDir).Files
If LCase(objFSO.GetExtensionName(objFile.Name)) = "xml" Then
iRet = Process_XML(objFile.Path)
If iRet > 0 Then
WScript.Echo """" & objFile.Name & """ - " & iRet & " Knoten verarbeitet."
iSucc = iSucc + 1
Else
WScript.Echo """" & objFile.Name & """ - Verarbeitung fehlgeschlagen."
iErr = iErr + 1
End If
End If
Next
WScript.Echo vbLf & iSucc + iErr & " Dateien verarbeitet." & _
vbLf & iSucc & " erfolreich" & _
vbLf & iErr & " fehlgeschlagen" & vbLf
If iErr > 0 Then WScript.Quit 1
Function Process_XML(ByRef strXmlDoc)
Set objXmlDoc = CreateObject("Microsoft.XMLDOM")
objXmlDoc.async = False
objXmlDoc.load(strXmlDoc)
iCounter = 0
Set objNode1 = objXmlDoc.documentElement.SelectSingleNode("//arbeiten")
If Not objNode1 Is Nothing Then
Set objNode2 = objXmlDoc.documentElement.SelectSingleNode("//taetigkeit/arbeitszeitBeginn")
If Not objNode2 Is Nothing Then
objNode2.text = objNode1.text
iCounter = iCounter + 2
End If
End If
Set objNode3 = objXmlDoc.documentElement.SelectSingleNode("//taetigkeit/arbeitszeit")
If Not objNode3 Is Nothing Then
strArbeitszeit = objNode3.text
objNode3.text = Left(strArbeitszeit, Len(strArbeitszeit) - 1)
iCounter = iCounter + 1
End If
Set objNode4 = objXmlDoc.documentElement.SelectSingleNode("//taetigkeit/arbeitszeitEnde")
If Not objNode4 Is Nothing Then
objNode4.text = strFixedValue
iCounter = iCounter + 1
End If
Set objNode5 = objXmlDoc.documentElement.SelectSingleNode("//rechnungsadresse")
If Not objNode5 Is Nothing Then
strrechnungsadresse = objNode5.text
objNode5.text = Left(strrechnungsadresse, 5)
iCounter = iCounter + 1
End If
If iCounter > 0 Then objXmlDoc.save(strXmlDoc)
Set objXmlDoc = Nothing
Process_XML = iCounter
End Function
Grüße
rubberman
LÖSUNG 08.08.2011 um 21:39 Uhr
LÖSUNG 08.08.2011 um 21:47 Uhr
Haha noch'n Thüringer 
Generelles Problem, dass hier lösbar wäre?
In dem Zusammenhang:
Die XML Dateien werden ja mehr oder weniger sinnentfremdet. Gibt es nicht die Möglichkeit die einmal angefassten Werte gleich in eine einzelne Datei zu bringen, die euer WaWi System versteht?
Grüße nach MHL
rubberman
Generelles Problem, dass hier lösbar wäre?
In dem Zusammenhang:
Die XML Dateien werden ja mehr oder weniger sinnentfremdet. Gibt es nicht die Möglichkeit die einmal angefassten Werte gleich in eine einzelne Datei zu bringen, die euer WaWi System versteht?
Grüße nach MHL
rubberman
LÖSUNG 08.08.2011 um 23:56 Uhr
Hallo rubberman,
sorry, ging nicht früher.
Die generellen Probleme liegen eher in der APP. So wird z.B. die Zeiterfassung über eine Art Stoppuhr gergelt. (Kommen und Gehen). Allerdings wird hier nicht gerundet, so dass zb. 55 Minuten als 0,42h in der XML Datei ausgegeben werden. Das sieht auf nem Auftrag natürlich blöd aus. Wenn man es noch hinbekommen würde das der Wert <arbeitszeit> auf 0,25 0,5 0,75 bzw. 1 auf -bzw. abzurunden wäre toll. Ich kann mich aber auch damit arrangieren, das ich beim erfassen per "Hand" runde.
Was die Sinnentfremdung angeht stimme ich Dir zu. Allerdings ist dem WAWI völlig egal wie die gelieferte XML Datei aussieht da ich per Definitionsdatei bestimme wo sich welche Werte befinden. Ohne diese Definitionsdatei geht garnichts, selbst wenn die orignial <Tag's> mit den Datenbankfeldnamen im WAWI übereinstimmen.
Wichtig ist nur, das sich alle Werte für die gelieferten Artikel jeweils unter dem <TAG> <materialeintrag> befinden und die ausgeführten Leistungen unter dem <TAG> <Tätigkeiten>. Und hier war halt das Prolbem das der Text für die Arbeiten als eingenständiges Objekt in der XML Datei auftaucht und somit nicht der entsprechenden Auftragsposition zuzuordnen war.
Bsp. gelieferte XML Datei
Die entsprechende Definitionsdatei des WAWI
Während das WAWI die gelieferte XML Datei abarbeitet wird nun für jeden <TAG> materialeintrag und Tätigkeit eine neue Auftragspostion angelegt. Dafür auch der feste Wert 1050, das ist die Artikelnummer für Leistungen im WAWI.
Ein erneutes schreiben der XML Datei wäre meiner Meinung nach daher nur für eine bessere Optik.
Bitte entschuldige meine nicht immer korrekte Verwendung von Begriffen wie <Tag>, Objekt etc. Ich hoffe Du verstehst micht trotzdem.
Gruß
twin850
sorry, ging nicht früher.
Die generellen Probleme liegen eher in der APP. So wird z.B. die Zeiterfassung über eine Art Stoppuhr gergelt. (Kommen und Gehen). Allerdings wird hier nicht gerundet, so dass zb. 55 Minuten als 0,42h in der XML Datei ausgegeben werden. Das sieht auf nem Auftrag natürlich blöd aus. Wenn man es noch hinbekommen würde das der Wert <arbeitszeit> auf 0,25 0,5 0,75 bzw. 1 auf -bzw. abzurunden wäre toll. Ich kann mich aber auch damit arrangieren, das ich beim erfassen per "Hand" runde.
Was die Sinnentfremdung angeht stimme ich Dir zu. Allerdings ist dem WAWI völlig egal wie die gelieferte XML Datei aussieht da ich per Definitionsdatei bestimme wo sich welche Werte befinden. Ohne diese Definitionsdatei geht garnichts, selbst wenn die orignial <Tag's> mit den Datenbankfeldnamen im WAWI übereinstimmen.
Wichtig ist nur, das sich alle Werte für die gelieferten Artikel jeweils unter dem <TAG> <materialeintrag> befinden und die ausgeführten Leistungen unter dem <TAG> <Tätigkeiten>. Und hier war halt das Prolbem das der Text für die Arbeiten als eingenständiges Objekt in der XML Datei auftaucht und somit nicht der entsprechenden Auftragsposition zuzuordnen war.
Bsp. gelieferte XML Datei
<stundenbericht>
<rechnungsadresse>10101
Testvorname Testnachnme
Teststrasse 11
12345 Testort
Deutschland</rechnungsadresse>
<ausfuehrungsort/>
<berichtNr>31</berichtNr>
<arbeiten>Testleistung 1
Testleisting 2
Bestleistung 3</arbeiten>
<material/>
<materialeintrag>
<bezeichnung>AOC 2216Sa TFT 22Zoll wide analog</bezeichnung>
<artikelnr>1573</artikelnr>
<menge>1</menge>
<verpackungseinheit>0,00</verpackungseinheit>
<einzelpreis/>
<gesamtpreis>0,00</gesamtpreis>
</materialeintrag>
<materialeintrag>
<bezeichnung>VMware vSphere 4 Essentials Bundle for 3 hosts</bezeichnung>
<artikelnr>1748</artikelnr>
<menge>1</menge>
<verpackungseinheit>0,00</verpackungseinheit>
<einzelpreis/>
<gesamtpreis>0,00</gesamtpreis>
</materialeintrag>
<gesamtpreisNetto>0,00</gesamtpreisNetto>
<steuer>0,00</steuer>
<gesamtpreisBrutto>0,00</gesamtpreisBrutto>
<datum>08.08.11</datum>
<taetigkeit>
<datum>08.08.11</datum>
<fahrzeit/>
<fahrzeitAbfahrt/>
<fahrzeitAnkunft/>
<fahrstrecke/>
<arbeitszeit>1h</arbeitszeit>
<arbeitszeitBeginn>22:30</arbeitszeitBeginn>
<arbeitszeitEnde>23:30</arbeitszeitEnde>
<pausenzeit/>
<pausenzeitBeginn/>
<pausenzeitEnde/>
<pausenzeit2/>
<pausenzeit2Beginn/>
<pausenzeit2Ende/>
<name/>
</taetigkeit>
<auswahllisteBezeichnung1>Pos</auswahllisteBezeichnung1>
<auswahleintrag1/>
<unterzeichner/>
</stundenbericht>
<stundenbericht NewData="AUFTRAG">
<rechnungsadresse>#KUNADRESSE.NR</rechnungsadresse>
<berichtNr>#AUFTRAGNR</berichtNr>
<materialeintrag NewData="ATRPOS">
<bezeichnung>#BEZEICHUNG</bezeichnung>
<artikelnr>#ARTIKELNR</artikelnr>
<menge>#MENGE</menge>
</materialeintrag>
<datum>#AUFTRAG.DATUM</datum>
<taetigkeit NewData="ATRPOS">
<arbeitszeit>#MENGE</arbeitszeit>
<arbeitszeitBeginn>#text</arbeitszeitBeginn>
<arbeitszeitEnde>#Artikel.Nr</arbeitszeitEnde>
</taetigkeit>
</stundenbericht>
Ein erneutes schreiben der XML Datei wäre meiner Meinung nach daher nur für eine bessere Optik.
Bitte entschuldige meine nicht immer korrekte Verwendung von Begriffen wie <Tag>, Objekt etc. Ich hoffe Du verstehst micht trotzdem.
Gruß
twin850
LÖSUNG 09.08.2011 um 01:05 Uhr
Hallo twin850.
Verstehe wie es funktioniert. Ich hatte an so etwas triviales wie eine CSV Datei gedacht. Die meisten Datenbanksysteme sind in der Lage solche sonderzeichengetrennten Werte zu importieren.
Was das Rundungsproblem angeht, teste mal mit
Je nach Locale-Einstellung musst du einmalig nachsehen, ob du tatsächlich einen Dezimalwert bekommst und ob das Dezimaltrennzeichen als Komma kommt. Bei mir funktioniert das so.
Grüße
rubberman
Verstehe wie es funktioniert. Ich hatte an so etwas triviales wie eine CSV Datei gedacht. Die meisten Datenbanksysteme sind in der Lage solche sonderzeichengetrennten Werte zu importieren.
Was das Rundungsproblem angeht, teste mal mit
objNode3.text = CStr(Round(Left(strArbeitszeit, Len(strArbeitszeit) - 1) * 4, 0) / 4)
Grüße
rubberman
LÖSUNG 09.08.2011 um 16:32 Uhr
Hallo Rubberman,
auch das funktioniert auf Anhieb. RESPEKT.
Monentan rufe ich das Script über eine Batch Datei auf.
Mache ich das von der Befehlszeile aus bekomme ich auch Rückmeldung ob erfolgreich oder nicht. Rufe ich die Batch als Verknüpfung bekomme ich keine Rückmeldung, da ja das Fenster gleich wieder zugeht. Wie bekomme ich die Statusmeldung als Windows Fenster ?
Danke und dann wars das wirklich.
Gruß
twin850
auch das funktioniert auf Anhieb. RESPEKT.
Monentan rufe ich das Script über eine Batch Datei auf.
cscript /nologo "replace.vbs" "PfadDerXMLDateien"
Danke und dann wars das wirklich.
Gruß
twin850
LÖSUNG 09.08.2011 um 18:51 Uhr
Hallo twin850,
Der PAUSE Befehl verhindert das Schließen des Fensters.
Falls der Batch nicht im gleichen Verzeichnis mit dem VBScript liegt, musst du natürlich den gesamten Pfad zu replace.vbs angeben.
Andere Möglichkeit:
du legst eine Verknüpfung an, mit ...
Ziel:
%SystemRoot%\System32\cmd.exe /k cscript.exe //nologo "C:\Pfad\zu\Replace.vbs" "C:\Pfad\zu\XMLDateien"
Ausführen in:
%SystemRoot%\System32
Grüße
rubberman
Der PAUSE Befehl verhindert das Schließen des Fensters.
@echo off
cscript //nologo "replace.vbs" "PfadDerXMLDateien"
pause
Andere Möglichkeit:
du legst eine Verknüpfung an, mit ...
Ziel:
%SystemRoot%\System32\cmd.exe /k cscript.exe //nologo "C:\Pfad\zu\Replace.vbs" "C:\Pfad\zu\XMLDateien"
Ausführen in:
%SystemRoot%\System32
Grüße
rubberman
LÖSUNG 09.08.2011 um 18:55 Uhr
Hallo twin850,
hier noch ein Verbesserungsvorschlag von mir. Ich modifiziere dazu mal das letzte Script von Rubberman, poste hier allerdings nur den ersten Teil, ohne das Unterprogramm ProcessXML, da sich dort nichts geändert hat.
Die Meldungen des Scripts werden in eine Log-Datei geschrieben, die im gleichen Verzeichnis wie das Script angelegt wird. Wenn das Script z.B. "PatchXML.vbs" heißt, wird die Log-Datei unter dem Namen "PatchXML YYYY-MM-DD HH-MM-SS.log" angelegt (der Name enthält also einen Zeitstempel). Wenn das Script seine Arbeit getan hat, erscheint eine Dialogbox, die über das Ergebnis informiert und fragt, ob man sich die Log-Datei anschauen möchte. Nach Klick auf den Button "Ja" wird dann Notepad gestartet und zeigt die Datei an.
Vorteil der Ausgabe der Meldungen in eine Log-Datei: Du kannst jetzt wieder den Ordner mit den XML-Dateien per Drag&Drop auf das Icon des Scripts ziehen, ohne bei jeder bearbeiteten Datei eine Dialogbox mit der Meldung "X Knoten verarbeitet" bzw. "Verarbeitung fehlgeschlagen" weg klicken zu müssen.
Gruß
Friemler
hier noch ein Verbesserungsvorschlag von mir. Ich modifiziere dazu mal das letzte Script von Rubberman, poste hier allerdings nur den ersten Teil, ohne das Unterprogramm ProcessXML, da sich dort nichts geändert hat.
If WScript.Arguments.Count < 1 Then
WScript.Echo "Syntax:" & _
vbLf & """" & WScript.ScriptName & """ ""Pfad"" [""FixerWert""]" & _
vbLf & vbLF & "Returncodes:" & _
vbLf & "3 zu wenig Argumente" & _
vbLf & "2 Verzeichnis nicht gefunden" & _
vbLf & "1 eine oder Mehrere Dateien konnten nicht verarbeitet werden" & _
vbLf & "0 alle gefundenen Dateien erfolgreich verarbeitet" & vbLf
WScript.Quit 3
End If
Set objFSO = CreateObject("Scripting.FileSystemObject")
strSrcDir = objFSO.GetAbsolutePathName(WScript.Arguments(0))
If Not objFSO.FolderExists(strSrcDir) Then WScript.Quit 2
If WScript.Arguments.Count > 1 Then
strFixedValue = WScript.Arguments(1)
Else
strFixedValue = "1050"
End If
strLogPath = objFSO.GetParentFolderName(WScript.ScriptFullName)
strLogName = objFSO.GetBaseName(WScript.ScriptName) & " " & _
Year(Now) & "-" & Right("0" & Month(Now), 2) & "-" & Right("0" & Day(Now), 2) & " " & _
Right("0" & Hour(Now), 2) & "-" & Right("0" & Minute(Now), 2) & "-" & Right("0" & Second(Now), 2) & _
".log"
Set objLogFile = objFSO.CreateTextFile(objFSO.BuildPath(strLogPath, strLogName), True)
iSucc = 0
iErr = 0
For Each objFile In objFSO.GetFolder(strSrcDir).Files
If LCase(objFSO.GetExtensionName(objFile.Name)) = "xml" Then
iRet = Process_XML(objFile.Path)
If iRet > 0 Then
objLogFile.WriteLine """" & objFile.Name & """ - " & iRet & " Knoten verarbeitet."
iSucc = iSucc + 1
Else
objLogFile.WriteLine """" & objFile.Name & """ - Verarbeitung fehlgeschlagen."
iErr = iErr + 1
End If
End If
Next
objLogFile.Close
strMessage = iSucc + iErr & " Dateien verarbeitet." & _
vbLf & iSucc & " erfolreich" & _
vbLf & iErr & " fehlgeschlagen" & _
vbLf & _
vbLf & "Möchten Sie sich die Log-Datei anschauen?"
If iErr = 0 Then
cButtons = vbQuestion
Else
cButtons = vbCritical
End If
If MsgBox(strMessage, cButtons + vbYesNo, WScript.ScriptName) = vbYes Then
Set objShell = CreateObject("WScript.Shell")
objShell.Run "notepad.exe """ & objFSO.BuildPath(strLogPath, strLogName) & """"
End If
If iErr > 0 Then WScript.Quit 1
Vorteil der Ausgabe der Meldungen in eine Log-Datei: Du kannst jetzt wieder den Ordner mit den XML-Dateien per Drag&Drop auf das Icon des Scripts ziehen, ohne bei jeder bearbeiteten Datei eine Dialogbox mit der Meldung "X Knoten verarbeitet" bzw. "Verarbeitung fehlgeschlagen" weg klicken zu müssen.
Gruß
Friemler
LÖSUNG 09.08.2011 um 19:08 Uhr
LÖSUNG 09.08.2011 um 20:22 Uhr
LÖSUNG 02.10.2013, aktualisiert um 14:14 Uhr
Hallo zusammen,
ich schließe mich mal diesem Thread an da ich eine ähnliche Frage habe und einfach nicht weiter komme.
Wie kann ich in einer XML einige Zeilen zusätzlich per Script hinzufügen?
Soll:
Ist:
Sprich die Zeilen von 11 bis 17 sollen immer nach <Nm Company Name </Nm> hinzugefügt werden. Diese hinzugefügten Zeilen sind fix und müssen nicht angepasst werden.
Die Datei mit dem neuen Inhalt soll als neue Datei im gleichen Verzeichnis mit anderem Namen abgelegt werden.
Wäre super wenn Ihr Eure Ideen mit einbirngen könntet.
Viele Grüße
Steffen
ich schließe mich mal diesem Thread an da ich eine ähnliche Frage habe und einfach nicht weiter komme.
Wie kann ich in einer XML einige Zeilen zusätzlich per Script hinzufügen?
Soll:
<?xml version="1.0" encoding="utf-8" ?>
<Document>
<CstmrCdtTrfInitn>
<GrpHdr>
<MsgId>20130619001</MsgId>
<CreDtTm>2013-06-19T14:22:08</CreDtTm>
<NbOfTxs>1</NbOfTxs>
<CtrlSum>100.00</CtrlSum>
<InitgPty>
<Nm>Company Name</Nm>
<Id>
<OrgId>
<Othr>
<Id>123456789</Id>
</Othr>
</OrgId>
</Id>
</InitgPty>
</GrpHdr>
</CstmrCdtTrfInitn>
</Document>
<?xml version="1.0" encoding="utf-8" ?>
<Document>
<CstmrCdtTrfInitn>
<GrpHdr>
<MsgId>20130619001</MsgId>
<CreDtTm>2013-06-19T14:22:08</CreDtTm>
<NbOfTxs>1</NbOfTxs>
<CtrlSum>100.00</CtrlSum>
<InitgPty>
<Nm>Company Name</Nm>
</InitgPty>
</GrpHdr>
</CstmrCdtTrfInitn>
</Document>
Die Datei mit dem neuen Inhalt soll als neue Datei im gleichen Verzeichnis mit anderem Namen abgelegt werden.
Wäre super wenn Ihr Eure Ideen mit einbirngen könntet.
Viele Grüße
Steffen
LÖSUNG 02.10.2013 um 22:24 Uhr
Hallo riatnep, willkommen im Forum.
Magst du vielleicht trotzdem einen neuen Thread erstellen? Dieser ist 2 Jahre alt und deine Frage wird wohl von den allermeisten Helfern nicht mehr wahrgenommen. (Abgesehen davon, dass du fremde Threads nicht für deine Themen nutzen solltest. Das ist eine Frage der "Netiquette".) Natürlich kannst du dann auf diesen Thread verweisen.
Grüße
rubberman
Magst du vielleicht trotzdem einen neuen Thread erstellen? Dieser ist 2 Jahre alt und deine Frage wird wohl von den allermeisten Helfern nicht mehr wahrgenommen. (Abgesehen davon, dass du fremde Threads nicht für deine Themen nutzen solltest. Das ist eine Frage der "Netiquette".) Natürlich kannst du dann auf diesen Thread verweisen.
Grüße
rubberman