Suchen-Ersetzen für ganze Websites

Was soll gemacht werden? | Das Formular | Der Code

Das Beispielprogramm, das hier komplett vorgestellt wird, demonstriert die Verwendung der Steuerelemente DriveListBox, DirListBox, FileListBox, den Umgang mit einigen Stringfunktionen, mit TextBoxenund Diskettenzugriffen. Es ist, nebenbei, ein nützliches Tool für die Pflege großer Websites, d.h. vieler Webseiten. Oft will man einen speziellen Eintrag, z.B. den aktuellen Namen der Freundin/des Freundes oder z.B. das Aktualisierungsdatum auf vielen Seiten ändern. Für den Zugriff auf ganze Dateiserien ist speziell Perl geeignet. Aber da wir hier Visual Basic machen ...; wär' doch gelacht, wenn es damit nicht auch ginge.

Was genau soll gemacht werden?

Die Suchen-Ersetzen-Funktion soll anwendbar sein auf beliebig viele Dateien, ohne daß sie alle einzeln von Hand geladen werden müssen. Gebraucht wird ein Dateiauswahlfenster mit der Möglichkeit der Mehrfachauswahl. Das könnte zwar auch der Standarddialog sein, der ist allerdings aus Visual Basic nicht weiter manipulierbar. Mit den drei Steuerelementen kann man variabler gestalten. Der Verlauf der Arbeit sollte erkennbar sein, auch eine Kontrollanzeige des HTML-Textes soll sein. Die Unterscheidung von Groß- und Kleinschreibung ist deshalb wichtig, weil man sie für das Suchen von echtem Text braucht, für HTML-Tags aber auf die Unterscheidung besser verzichtet.

zum Anfang

Das Formular

In Stichworten sollen die wichtigsten Einstellungen zum Formular angegeben werden, weil sie sich nicht in jedem Falle von selbst verstehen.

bild

Form1
Das Formular erhält im Eigenschaftsfenster ein Icon und eine Caption.
DriveListBox
Die Auswahlbox (links oben) für Laufwerke heißt Laufwerk1, nur einfügen.
FileListbox
Sie heißt Verzeichnis1 und muß auch nicht weiter bearbeitet haben.
DateiListBox
Sie heißt Datei1 und muß im Eigenschaftenfenster auf Pattern = *.htm;*.html eingestellt werden, was dafür sorgt, daß nur die gewünschten Dateien angezeigt werden. Dies kann ggf. erweitert werden, übrigens könnte diese Zuweisung auch etwa in Form_Load erfolgen. Weiter muß MultiSelect = 2 - Erweitert eingestellt werden, damit später die Mehrfachauswahl geht.
Auf der rechten Seite sind zwei große
TextBoxen
zu sehen. Die obere heißt Text1 und wird die Fortschrittsmeldungen enthalten. Für diese Box muß ebenso wie die für die untere, die Text4 heißt und den Code zeigen soll, im Eigenschaftsfenster MultiLine = True und ScrollBars = 2 - Vertikal gesetzt werden. Unten liegen zwei weitere Textboxen, Text2 und Text3, für die Eingabe des zu suchenden und des zu ersetzenden Textes. Sie können mit ihren voreingestellten Eigenschaften verwendet werden, solange man sich darauf beschränkt, nur innerhalb von Zeilen zu suchen und zu ersetzen. Falls Such- oder Ersetz-Text Zeilenumbrüche enthalten dürfen sollen (klar?), müssen die beiden Textboxen wie die anderen beiden eingestellt werden.

zum Anfang

Der Code

Die Dateiauswahl funktioniert mit einem Minimum an Programmaufwand. Hier müssen die drei Boxen miteinander verknüpft werden. Die Veränderung (Change) soll als path an die jeweils untergeordnete Box weitergemeldet werden. Wie das geht, steht in der Tabelle.

Option Explicit
Dim DatNam(250) As String, Zeile(1000) As String, grossklein As Integer

Private Sub Form_Load()
grossklein = vbTextCompare
End Sub
Private Sub Laufwerk1_Change()
Verzeichnis1.Path = Laufwerk1.Drive
End Sub
Private Sub Verzeichnis1_Change()
Datei1.Path = Verzeichnis1.Path
Command1.Enabled = bereit
End Sub
Private Sub Datei1_Click()
Command1.Enabled = bereit
End Sub

Nach der Dateiwahl, die nun sichergestellt ist, könnte es schon losgehen. Ein Minimum an Sicherheiten gegen Fehlbedienung soll aber sein. Deshalb ist der "Start"-Button (Command1) im Entwurf auf Enabled = False gesetzt und bleibt nach Programmstart deaktiviert, bis seine Bedienung sinnvoll ist. Es müssen mindestens eine Datei selektiert sein und ein Suchen-Ausdruck vorhanden sein. Das wird in der binären Funktionen "bereit" geprüft. Ergibt sie True, dann wird der Button bei einem der beiden entscheidenden Ereignisse, oben bei Sub Datei1_Click() oder unten bei Sub Text2_Change() aktiviert.

Bevor es ernst wird, muß man noch wissen, ob Groß oder Klein (jetzt nicht mißverstehen!), das erledigt der Check1. Die beiden dort angegeben vb-Konstanten mit den schrecklichen Namen entscheiden später über die Art des Textvergleiches.

Private Function bereit() As Boolean
Dim sel As Boolean, i As Integer
sel = False
For i = 0 To Datei1.ListCount - 1
If Datei1.Selected(i) Then sel = True
Next
If sel And Text2.Text <> "" Then
bereit = True
End If
End Function
Private Sub Text2_Change()
Command1.Enabled = bereit
End Sub
Private Sub Check1_Click()
If Check1.Value Then grossklein = vbBinaryCompare Else grossklein = vbTextCompare
End Sub
Private Sub Command2_Click()
Unload Form1
End
End Sub

Jetzt kommt der Rest: Wenn Command1 geklickt wird, soll die ganze Arbeit erfolgen. Der TextBox1-Text wird "genullt", weil später der Text sozusagen aufaddiert wird. Vom Kommentar 'Dateiliste an beginnt die Arbeit echt. Es werden die Pfade der selektierten Dateien ins Array DatNam() geschrieben. Verzeichnisse werden von Visual Basic ohne abschließenden Backslash gemeldet, Laufwerke mit. Deshalb die eingeschaltete Abfrage.
Es folgt eine For-Next-Schleife, die nacheinander die einzelnen Dateien abarbeitet. Zunächst der Lesevorgang mit Meldung. Dann die Bearbeitung, die hier zeilenweise erfolgt. Na ja, und so weiter. Eigentlich alles klar.
Abschließende Erläuterung zur Anzeige: Die letzte Seite wird zur Kontrolle in Text4 angezeigt. Daraus folgt, daß man das Programm auch zur schnellen Anzeige nutzen kann, indem man einen unmöglichen Suchtext vorgibt und nur eine Datei wählt.

Private Sub Command1_Click()
Dim i%, j%, k%, l%, pos%, posalt%, mal%
Text1.Text = ""
Text4.Text = ""
'Dateiliste
j = 0
For i = 0 To Datei1.ListCount - 1
If Datei1.Selected(i) Then
j = j + 1
If Right(Datei1.Path, 1) <> "\" Then
DatNam(j) = Datei1.Path & "\" & Datei1.List(i)>
Else
DatNam(j) = Datei1.Path & Datei1.List(i)
End If
End If
Next
'Lesen
For i = 1 To j
Text1.Text = Text1.Text & DatNam(i) & " in Arbeit"
Text1.Refresh
k = 0
Open DatNam(i) For Input As #100
Do Until EOF(100)
k = k + 1
Line Input #100, Zeile(k)
Loop
Close #100
'Verarbeiten
mal = 0
For l = 1 To k
posalt = 1
Do
pos = InStr(posalt, Zeile(l), Text2.Text, grossklein)
If pos <> 0 Then
Zeile(l) = Left(Zeile(l), pos - 1) & Text3.Text & Right(Zeile(l), Len(Zeile(l)) - pos - Len(Text2.Text) + 1)
posalt = pos + Len(Text3.Text)
mal = mal + 1
End If
Loop Until pos = 0
Next
Select Case mal
Case 0
Text1.Text = Left(Text1.Text, Len(Text1.Text) - 9) & ", kein Treffer"
Case 1
Text1.Text = Left(Text1.Text, Len(Text1.Text) - 9) & ", eine Ersetzung"
Case Else
Text1.Text = Left(Text1.Text, Len(Text1.Text) - 9) & ", " & mal & " Ersetzungen"
End Select
Text1.Refresh
'Schreiben
Open DatNam(i) For Output As #101
For l = 1 To k
Print #101, Zeile(l)
Next
Close #101
'Erfolg melden
Text1.Text = Text1.Text & ", fertig" & vbCrLf
Text1.Refresh
Next
'Letzte Datei anzeigen>
For i = 1 To k
Text4.Text = Text4.Text & Zeile(i) & vbCrLf
Next
End Sub

So etwa sieht das Programm nach der Arbeit aus.

Okay, man kann es so nutzen.
Es seien noch einige Anregungen für die Weiterarbeit gegeben.
Die Diskettenzugriffe sollten dringend durch Fehlerroutinen abgesichert werden.
Wer das Programm ernsthaft nutzen will, wird bald den Wunsch haben, etwa mehrere Zeilen einzufügen. Dann wird es bequemer, den Seitentext aufzuaddieren, so wie es für die Anzeige geschieht, und gleich im Gesamtstring zu suchen und zu ersetzen.
Da TextBoxen schon von Haus aus Editoren sind, ist die Textbearbeitung im Anzeigefenster schnell verwirklicht. Man muß nur an ein Menü- oder Buttonereignis das Speichern oder Drucken von Text4.Text ermöglichen.
Die Benutzerfreundlichkeit der Textbox bewirkt, daß die Zwischenablage per Maus zur Verfügung steht, dies ließe sich um eine Menü-Bedienung erweitern und so auf Windows-Standard bringen.
Man kann auch über "fortgeschrittenere" Optionen nachdenken.
Eine "Undo"-Funktion etwa: Einfach die Datei(en) vor der Bearbeitung in ein zusätzliches Array speichern, die Rechner haben Platz genug.
Man könnte auch an Komprimierung denken, die Entfernung von Leerzeilen, führenden Leerzeichen oder die Entfernung aller Zeilenumbrüche, alles das läßt sich leicht ergänzen.

zum Anfang

© R. Hirte * 2002