calim3ro
Goto Top

VBS Zeilen in Textfile suchen und nur nach erfüllten Kriterien löschen

Hallo zusammen

Ich gelange wieder mal mit einer Bitte an euch.

Kurze Erläuterung:

In einem File habe ich Zeichenböcke:

11 ABCDEF
22 CDEFGH
33 DEFGHI
44 BCDEFG
11 FEDCBA
22 HGFEDC
33 IHGFED
44 GHIFED

Ein Zeichenblock beginnt immer mit 11.
Nun soll als erste Kritik geprüft werden, ob bei 22 in Spalte 4 ein X enthält. Wenn Ergebniss negativ (kein X), weiter mit Kritik zwei. Zweite Kritik, ob bei Zeile 33 in Spalte 4 ein D enthält. Wenn positiv (D vorhanden) weiter mit Kritik drei. Dritte Kritik, ob bei Zeile 44 in Spalte 4 ein B (oder andere/ mehrere gemäss separater Liste) enthalten ist. Da es für Kritik drei mehrere Buchstaben-Möglichkeiten gibt und die einfach zu ändern sein sollten, wäre es super wenn dies über eine Positiv-Liste geschehen würde.

Wenn alle Kriterien erfüllt wurden, muss Zeile 44 gelöscht werden. Falls Kritik eins positiv, muss nichts gelöscht werden, ebenso wie wenn Kritik zwei und drei negativ sind.

Am Ende sollte der Zeichenblock folgendermassen aussehen:

11 ABCDEF
22 CDEFGH
33 DEFGHI
11 FEDCBA
22 HGFEDC
33 IHGFED
44 GHIFED

Wie müsste ein VB-Script aussehen, das nach dieser Logik folgt?

Besten Dank im Voraus für euere Bemühungen.

Bei Unklarheiten einfach nachfragen, die Beschreibung war nicht ganz leicht zu formulieren....

Grüsse Calimero

Content-ID: 233087

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

Ausgedruckt am: 24.11.2024 um 04:11 Uhr

bastla
bastla 19.03.2014 aktualisiert um 23:58:51 Uhr
Goto Top
Hallo Calim3ro!

Versuch es damit:
Kenn = Array("11", "22", "33", "44") 'Kennzeichen Zeilenbeginn  
KPos = Array(0, 4, 4, 4)             'zu untersuchende Position in Zeile  
Krit = Array("", "X", "D", "BCFKN")  'Kriterien für die einzelnen Kennungen; Positivliste für "44" = "BCFKN"  
'Kriterium 1 = 1 (egal, wird nicht geprüft; nur damit gleich viele Elemente wie oben)  
'Kriterium 2 = 0 (keine Übereinstimmung)  
'Kriterium 3 = 1 (Übereinstimmung)  
'Kriterium 4 = 1 (Übereinstimmung)  
K = Array(1, 0, 1, 1)

Ein = "File.txt"  
Aus = "File_neu.txt"  

KLen = Len(Kenn(0)) 'Länge der Zeilenkennung ermitteln  
KAnz = UBound(Kenn) 'Anzahl der Kriterien ermitteln  

Set fso = CreateObject("Scripting.FileSystemObject")  
Set E = fso.OpenTextFile(Ein)
Set A = fso.CreateTextFile(Aus)

Do While Not E.AtEndOfStream 'alle Zeilen durchgehen  
    Z = E.ReadLine 'Zeile einlesen  
    If Left(Z, KLen) = Kenn(0) Then 'Blockbeginn?  
        'KriterienEregebnis auf "erfüllt" setzen  
        KErg = 1
        A.WriteLine Z 'Zeile jedenfalls schreiben  
    Else ' ... ansonsten  
        For i = 1 To KAnz 'auf Kriterien ab 2 (Index beginnt bei 0, daher Schleife ab 1) prüfen  
            If Left(Z, KLen) = Kenn(i) Then 'Kennung gefunden  
                'Wenn Zeichen in Kriterienliste gefunden,  
                'Übereinstimmung / keine Übereinstimmung prüfen:  
                P = InStr(Krit(i), Mid(Z, KPos(i), 1)) 'Zeichenposition; wenn nicht gefunden: 0  
                'Sgn(P) liefert 1 bei "Übereinstimmung" und 0 bei "keine Übereinstimmung"  
                'dieses Ergebnis mit der Vorgabe in K() vergleichen und  
                'KriterienErgebnis durch UND-Verknüpfung (Multiplikation) ermitteln  
                KErg = KErg * (Sgn(P) = K(i))
                KritNr = i 'Kriteriennummer zwischenspeichern  
            End If
        Next
        If KritNr <> KAnz Then 'noch nicht letzte Kennung, ...  
            A.WriteLine Z '... daher Zeile jedenfalls schreiben  
        Else 'letzte Kennung (= "44") ...  
           If KErg = 0 Then A.WriteLine Z '... daher nur schreiben, wenn nicht alle Kriterien erfüllt  
        End If
    End If
Loop
Bitte beachten: Beim Vergleich mit den Zeichen in Krit() wird Groß-/Kleinschreibung berücksichtigt!

Grüße
bastla
TsukiSan
TsukiSan 20.03.2014 aktualisiert um 08:35:17 Uhr
Goto Top
Hallo bastla,

nur so unter Kollegen: Meine paar Zeilen würden den Anforderungen auch genüge tun, allerdings hätte ich dazu gern deinen Kommentar, falls das möglich ist.

Hallo Calim3ro,

nur als Alternative. Bastla hat Kommentare dazu geschrieben. Die erspare ich mir, weil bastlas Zeilen genau das tun, was du möchtest.

Const DateiEin = "DateiEin.txt"  
Const DateiAus = "DateiAus.txt"  
Const BlockTrenner = "11"  
KritArray = Array("","X","D","B")  
Dim DatenNeu

Set FSO = CreateObject("Scripting.FileSystemObject")  
Bloecke = Split(FSO.OpenTextFile(DateiEin).ReadAll,BlockTrenner)

For i = 0 to Ubound(Bloecke)
	If Not Bloecke(i) = "" then  
		TempFailed = 0
		tempZeilen = Split(Bloecke(i),vbcrlf)
		If Mid(tempZeilen(1),4,1) = KritArray(1) then
			TempFailed = 1
		End If
		For j = 2 to 3
			If Mid(tempZeilen(j),4,1) = KritArray(j) Or TempFailed = 1 then
				'hier passiert nichts!  
			Else
				TempFailed = 1
				Exit For
			End If
		next
		If TempFailed = 1 then
			DatenNeu = DatenNeu & BlockTrenner & Bloecke(i)
		Else
			tempZeilen(0) = BlockTrenner & tempZeilen(0)
			For k = 0 to 2
				temp = temp & tempZeilen(k) & vbcrlf
			Next
			DatenNeu = DatenNeu & temp
			temp = ""  
		End If
	End If
Next

DatenAus = FSO.CreateTextFile(DateiAus,True).Write (DatenNeu) 

Set FSO = Nothing
Set DatenAus = Nothing

Gruss

Tsuki

[Edit]
Code entsprechend angepasst, dass
NICHT X, D, B
und beide unnützen Zeilen 15 und 16 entfernt
[/Edit]
bastla
bastla 20.03.2014 um 08:14:56 Uhr
Goto Top
Hallo Tsuki!

Habe Deinen Ansatz nur kurz überflogen, wobei mir aufgefallen ist, dass Du die Variablen aus den Zeilen 15 und 16 gar nicht verwendest und anscheinend alle Überprüfungen auf "Übereinstimmung" vornimmst - für die "22"-Zeilen soll aber gelten, dass "X" <i>nicht<i> vorkommen darf; ansonsten durchaus sinnvoll und nachvollziehbar ... face-smile

Da ich zusammen mit Callim3ro schon in einem anderen Thread eine ähnliche Struktur bearbeitet hatte und dort nachträglich noch diverse Änderungen nötig wurden, habe ich in meinem Ansatz gleich etwas vorgesorgt und stärker parametrisiert ...

Grüße
bastla
TsukiSan
TsukiSan 20.03.2014 um 08:19:00 Uhr
Goto Top
Hallo bastla,

besten Dank für dein Feedback.
Richtig, Zeilen 15 und 16 sind "nutzlos" und dienten nur als Test.
Und auch richtig, dass das X negiert werden muss. Hatte ich beim Lesen der Aufgabe
nicht richtig beachtet. Liese sich aber ändern.

Viele Grüsse

Tsuki
Calim3ro
Calim3ro 23.03.2014 um 23:56:30 Uhr
Goto Top
Hallo TsukiSan

Besten Dank das du dir auch noch Gedanken über die Script-findung gemacht hast, aus den von bastlas erwähnten Gründen verwende ich jedoch seinen. face-smile

Hallo bastla

Irgendwie wusste ich, dass ich von dir als erstes eine Lösung erhalte.
Besten Dank, das Script mach genau das was ich geschrieben habe. Jedoch hat meine Beschreibung einen Fehler: Es sollte Zeile 33 löschen, nicht 44
Sorry, war ein Überlegungsfehler...

Ist es ausserdem möglich für Kritik 4 eine .txt-Liste in das Script zu lesen, ähnlich der Positivliste aus dem letzten Script?

Besten Dank schon mal im Voraus

Grüsse Calimero
bastla
bastla 24.03.2014 aktualisiert um 20:06:34 Uhr
Goto Top
Hallo Calim3ro!

Für die neue Variante bräuchte ich vorweg eine Bestätigung: Besteht jeder Block tatsächlich aus genau 4 Zeilen, die mit "11", "22", "33" und "44" beginnen und auch entsprechend sortiert sind?

Hinsichtlich der Positivliste: Wenn die benötigten Werte alle ohne Trennzeichen in der ersten (einzigen) Zeile der Datei "D:\Positivliste.txt" stehen, kannst Du Zeile 3 durch
Set fso = CreateObject("Scripting.FileSystemObject")  
K4 = fso.OpenTextFile("D:\Positivliste.txt").ReadLine  
Krit = Array("", "X", "D", K4)  'Kriterien für die einzelnen Kennungen  
ersetzen und Zeile 16 weglassen ...

Grüße
bastla