VBS, String im String finden: Fehler im Code
lima-city → Forum → Programmiersprachen → Basic
array
code
datei
datensatz
einlesen
file
funktion
gelesenen zeile
index
null
ordner
output
problem
set
tag
term
text
zeichen
zeile
ziel
-
Hallo zusammen,
Meine bisherige Suche hat mir keine Ergebnisse gebracht, außerdem habe ich speziell mit meinem tag/code">Code ein Problem. Außerdem hoffe ich, dass der vbscript hier im Basic-Forum kein so großen Unterschied macht. Von daher denke ich ist der Post hier richtig.
function extrahieren(suchterm,datei) Do Until datei.atEndOfStream strLine = datei.Readline 'Vorne und hinten finden if inStr(1,strLine,suchterm,0)>0 then msgbox(strline) vorne = inStr(1,strLine,suchterm,0) msgbox(vorne) bisHinten = inStr(vorne, strLine,"<\",0) - vorne '<--- Gibt immer nur null-vorne zurück. msgbox(bishinten) wert = wert & mid(strline,vorne,bisHinten) 'Fehlermeldung extrahieren = extrahieren & wert exit function end if loop end function
Dies ist mein Code. Übergeben wird der String "suchterm" und die "datei", die per
Set fs = CreateObject("Scripting.FileSystemObject") Set datei = fs.OpenTextFile("<pfad>\index.html")
eingebunden wurde.
Mein Ziel ist/war innerhalb der Datei einen Tag zu finden und dann den Text innerhalb der Tags auszugeben. Deswegen die beiden Markierungen "vorne" und "bishinten", weil die Funktion "mid()" einen String ausgibt der bei "vorne" anfängt, und soviele Zeichen "bisHinten" ausgeben soll.
Zwei Probleme treten auf:
1. "bisHinten" ist immer der negative Wert von vorne. Ergo, gibt
null zurück. Verstehe ich nicht.inStr(vorne, strLine,"<\",0)
2. An der oben markierten Stelle kommt dann eine Fehlermeldung: "800A0005" ungültiger Prozedurenaufruf oder ungültiges Argument: 'mid'. Es scheitert definitiv an "bisHinten". Wahrscheinlich, weil es negativ ist. Also zurück zu 1.
Das komplette Skript:
function extrahieren(suchterm,datei) Do Until datei.atEndOfStream strLine = datei.Readline 'Vorne und hinten finden if inStr(1,strLine,suchterm,0)>0 then msgbox(strline) vorne = inStr(1,strLine,suchterm,0) msgbox(vorne) bisHinten = inStr(vorne, strLine,"<\",0) - vorne '<--- Gibt immer nur null-vorne zurück. msgbox(bishinten) wert = wert & mid(strline,vorne,bisHinten) extrahieren = extrahieren & wert exit function end if loop end function function datensatz(datei) suchterme_definieren() Dim suchterme(2) 'Jeweilige html-tags suchterme(0) = "vi-is1-prcp" 'Preis tag suchterme(1) = "EUR" suchterme(2) = "MEZ" max = (UBound(suchterme)) for i = 0 to max datensatz = datensatz & extrahieren(suchterme(i), datei) & "," next end function '---------------------- 'Datei öffnen/einlesen '---------------------- Dim fs, datei Set fs = CreateObject("Scripting.FileSystemObject") Set datei = fs.OpenTextFile("e:\users\chris\desktop\index.html") '---------------------------------- 'In Datei schreiben/schließen '---------------------------------- set fs = createobject("Scripting.filesystemobject") set output = fs.opentextfile("e:\users\chris\desktop\output.txt",2,true,0) output.write datensatz(datei) datei.close output.close MsgBox "Abwischen...",0,"Fertig!"
UPDATE:
Gut, wenn keiner antworten will...
Kann mir jemand erklären, wie die Funktion "datei.readline" funktioniert?
Welchen Wert sie liefert?
Wie sie sich zu readall unterscheidet?
Gruß Christoph
Beitrag zuletzt geändert: 14.3.2010 16:58:59 von cdas -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Hi,
also bei mir funktioniert dein Script _grundsätzlich_ schon.
Du hast ja ein paar MsgBoxes als Debug eingebaut, guck doch die Ausgaben an, dann siehst du wo das Problem liegt. Ich würde auch vorschlagen zunächst mal nur nach einem Bergriff zu suchen, wenn das funktioniert kannst du ja das Script erweitern.
Eine Problemursache könnte sein, dass ReadLine immer nach der gelesenen Zeile stehen bleibt (genauer gesagt der Zeiger in der Datei zeigt auf das erste Zeichen nach der gelesenen Zeile). Um für die nächste Abfrage wieder am Dateianfang zu starten müstest du die Datei schließen und wieder öffnen.
Ein anderes Problem könnte sein, dass sich im Suchbegriff ein Zeilenumbruch befindet. Für diesen Falls müßtest du das "<\" dann auch in den nächsten Zeilen suchen.
cdas schrieb:
Immer mit der Ruhe. Wie eigentlich unschwer aus den Funktionsnamen zu erkennen ist liest ReadLine den Dateiinhalt zeilenweise und ReadAll den gesamten Inhalt der Datei auf einmal.
Gut, wenn keiner antworten will...
Kann mir jemand erklären, wie die Funktion "datei.readline" funktioniert?
Welchen Wert sie liefert?
Wie sie sich zu readall unterscheidet?
Hier mal der etwas geänderte Code:
als input die Datei text.txt:function extrahieren(suchterm,datei) Do Until datei.atEndOfStream strLine = datei.Readline 'Vorne und hinten finden if inStr(1,strLine,suchterm,0)>0 then MsgBox(strline) vorne = inStr(1,strLine,suchterm,0) MsgBox(vorne) bisHinten = inStr(vorne, strLine,"<\",0) - vorne '<--- Gibt immer nur null-vorne zurück. MsgBox(bishinten) wert = wert & mid(strline,vorne,bisHinten) MsgBox(wert) extrahieren = extrahieren & wert exit function end if loop end function function datensatz(datei) 'suchterme_definieren() Dim suchterme(2) 'Jeweilige html-tags suchterme(0) = "vi-is1-prcp" 'Preis tag suchterme(1) = "EUR" suchterme(2) = "MEZ" terms = (UBound(suchterme)) for i = 0 to terms Set datei = fs.OpenTextFile("text.txt") datensatz = datensatz & extrahieren(suchterme(i), datei) & "," datei.close next end function '---------------------- 'Datei öffnen/einlesen '---------------------- Dim fs, datei Set fs = CreateObject("Scripting.FileSystemObject") '---------------------------------- 'In Datei schreiben/schließen '---------------------------------- set fs = createobject("Scripting.filesystemobject") set output = fs.opentextfile("output.txt",2,true,0) output.write datensatz(datei) output.close MsgBox "Abwischen...",0,"Fertig!"
sdfsf <EUR>Hallo<\EUR> ssadffsf
Gruß
Manni -
bandi999 schrieb: Hi,
Immer mit der Ruhe.
Danke für die Antwort. So war es auch nicht gemeint, sondern eher die Konversation anregen und evtl. Mitwissende einbeziehen, die meinen konkreten Code durch allgemeines Wissen hätten unterfuttern können.
Vorweg: Inzwischen bezweifle ich, ob VBS die sinnvollste Sprache ist. Ein Freund erwähnte diesen Zweifel und meinte, ich solle mir mal JScript, Soap o.ä. anschauen. Die böten nämlich spezielle Funktionen zum Umgang mit Tags und eben sonstigen Besonderheiten von HTML-Files.
Eine Problemursache könnte sein, dass ReadLine immer nach der gelesenen Zeile stehen bleibt (genauer gesagt der Zeiger in der Datei zeigt auf das erste Zeichen nach der gelesenen Zeile). Um für die nächste Abfrage wieder am Dateianfang zu starten müstest du die Datei schließen und wieder öffnen.
Ahh... es hat fünf Minuten gedauert, aber jetzt sehe ich das Problem. Das kann natürlich sein. Ich hatte inzwischen an die folgende Alternative gedacht:
Man kann die Datei auch komplett in einen Array einlesen. (Idee kommt von http://www.aspfree.com/c/a/Windows-Scripting/Reading-Text-Files-in-WSH/3/ )
i = 1 Do Until objReadFile.AtEndOfStream Redim Preserve arrData(i) arrData(i) = objFile.ReadLine i = i + 1 Loop
Funktioniert aber bei mir nicht einwandfrei, weil in Zeile 4 Typen nicht passen, oder so ähnlich. -
Hi,
cdas schrieb:
Das Objekt objFile hat keine Methode ReadLine sondern das Objekt objReadFile. Hier mal das Beispiel mit Änderungen, was bei mir funktioniert:
i = 1 Do Until objReadFile.AtEndOfStream Redim Preserve arrData(i) arrData(i) = objFile.ReadLine i = i + 1 Loop
Funktioniert aber bei mir nicht einwandfrei, weil in Zeile 4 Typen nicht passen, oder so ähnlich.
GrußSet objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.GetFile("addresses.txt") If objFile.Size > 0 Then Set objReadFile = objFSO.OpenTextFile("addresses.txt", 1) i = 1 Do Until objReadFile.AtEndOfStream Redim Preserve arrData(i) arrData(i) = objReadFile.ReadLine i = i + 1 Loop objReadFile.Close strContents = arrData(4) for i = 0 to (UBound(arrData)) MsgBox(arrData(i)) next End If
Manni -
Danke Manni!
Dein Code funktioniert bei mir auch. Da war bei mir -glaube ich- ein kleiner Fehler ausschlaggebend: Wenn man nämlich "Dim arrData" anfangs aufruft, dann funktioniert es nicht.
Öffnet sich eine Tür, schließt sich eine andere.
Neue Funktion, neues Problem mit altem Code, eben leicht angepasst. Hoffentlich kannste mir da auch noch drüber hinweg helfen. Ich seh den Fehler nicht. Hier der Code inkl. Funktion zum Ausführen:
function dateienFinden() Dim objFSO, unterordner, i, Files Set objFSO = createobject("Scripting.FileSystemObject") Set ordner = objFSO.getfolder("E:\Users\chris\Documents\data\data\") i = 0 Set Subfolders = ordner.subfolders If Subfolders.Count > 0 Then For each unterordner in Subfolders 'Bekomme Pfad von index.html Redim Preserve arrListe(i) arrListe(i) = unterordner.Path '<--- Bug hockt vermutlich hier! i = i + 1 next End If dateienFinden = arrListe End Function 'function test temp = dateienFinden For j = 0 To UBound(temp) output = output & temp(i) Next msgbox output
Ziel:
Der soll die Pfade der Unterordner in einen Array speichern, ähnlich, wie den Text einlesen.
Problem:
Er spuckt einen Array aus mit gleichen Einträgen aus. Es gibt soviele Einträge, wie tatsächlich Unterordner vorhanden sind. Das Problem steckt also in der markierten Zeile.
Pers.Problem:
Der Rückgabewert von "unterordner.Path" ist wohl immer der gleiche. Doch es wird doch durch die "for each"-Struktur immer ein weiteres Element angesprochen.
UPDATE:
Feststellung: Im "for each ... next" wird i nicht inkrementiert.
Ich vermute der Haken ist der Rückgabewert von "ordner.Subfolders". Dies ist nämlich eine collection. (Im Gegensatz zum dateiEinlesen-Code)
Fraglich ist demnach also, ob anderer Code innerhalb von "for each ... next" ausgeführt werden kann.
Beitrag zuletzt geändert: 16.3.2010 17:46:55 von cdas -
Hi,
nun ja, manchmal denkt man zu kompliziert, vor allem wenn man schon lange vor so einem Rechner am selben Problem sitzt :).
Hier hast du die Variablen j und i gemischt, dass sollte wohl nicht so sein.For j = 0 To UBound(temp) output = output & temp(i) Next
Gruß
Manni -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage