Jak ułatwić sobie pracę z HTML-em?
Jeżeli mamy kilkadziesiąt pojedynczych stron i trzeba będzie na wszystkich stronach dokonać zmian, to robienie tego „na piechotę” zajmie strasznie dużo czasu. Przewidując taki problem, powinniśmy wcześniej wyznaczyć „strategiczne” miejsca na stronie gdzie najczęściej będziemy dokonywać hurtowych zmian i nadać niektórym znacznikom identyfikatory (wiadomo unikalne), bądź oznaczyć te obszary komentarzami o określonej, indywidualnej nazwie.
<div id="mnuArt">
<!-- a ich tag zamykający oznaczyć komentarzem -->
</div <!-- END id="mnuArt" -->
Łatwiej nam będzie zamienić zawartość całego znacznika, bez przeszukiwanie znaczników wewnątrz naszego głównego znacznika. Obszarem wymagającym najczęstszych zmian na pewno będzie obszar nawigacji. W Html5 obszar ten umieszczony jest pomiędzy znacznikiem otwierającym <nav>
<nav>
<!-- całe menu nawigacyjne stron (strony) -->
</nav
i znacznikiem zamykającym </nav>.
Nazwy plików *.html można porzedzić prefiksami, np. api-, bmp-, docmd-, form-, plik-, tekst-, vba-, które określają poruszaną tematykę tych stron
i same z siebie wymuszą pogrupowanie tematyczne stron w folderze.
Przykładowa lista plików *.html
Aby hurtowo przetwarzać pliki musimy najpierw zrobić ich listę. Do tego celu wykorzystamy funkcję plikListFiles() przedstawioną na stronie API. Lista plików. Funkcja ta w argumencie ByRef sFilesPathRet() zwraca tablicę typu String zawierająca pełne nazwy znalezionych plików w folderze roboczym. Pliki możemy wyszukiwać z użyciem symboli wieloznacznych Asterisk "*" oraz QuestionMark "?".
Jeżeli struktura naszego serwisu jest bardziej rozbudowana i strony *.html znajdują się w wielu podfolderach, będziemy musieli dodatkowo skorzystać z funkcji plikListSubFoldersApi(...) wyszukującą podfoldery w folderze roboczym, która przedstawiona jest na stronie API. Lista folderów.
Mając listę plików możemy kolejno każdy plik wczytać do zmiennej sTekstHtml typu String , dokonać wymaganych zmian i zapisać plik na dysku. By wczytać plik użyjemy funkcji plikFileToString(...), która przedstawiona jest na stronie Plik do zmiennej String. Należy pamiętać, że funkcja plikFileToString(...) korzysta z pomocniczej funkcji sprawdzającej poprawność argumentów plikCheckArguments(...), która przedstawiona jest na stronie Argumenty otwarcia pliku. Jeżeli jesteśmy pewni, że plik istnieje i możemy go otworzyć bez problemów do operacji „Odczytu” i (lub) „Zapisu” to możemy zrezygnować z użycia tej funkcji.
Struktura przykładowego pliku *.html
Poniżej uproszczony plik testowy, który używany był do testów funkcji przetwarzających tekst plików *.html.
<!doctype html> <html lang="pl"> <head> <meta charset="UTF-8"> <meta name=viewport content="width=device-width, initial-scale=1"> <title>Przetwarzanie tekstu. Access i tekst</title> <link rel="stylesheet" type="text/css" href="css/access.css"> <link rel="stylesheet" type="text/css" href="css/accessIndex.css"> </head><body> <div id="container"> <header id="hdpage"> <img src="images/banner.png" alt="Access"> <h1 id="hdpageh1"><span> MS Access 2010+ | Przetwarzanie tekstu | VBA 7.0</span></h1> </header> <section id="sect1" class="sectpage"> <header> <h1>Nagłówek H1 nagłówka artykułu</h1> </header> <article> <h1>Nagłówek H1 artykułu</h1> </article> </section> <nav> <div id="mnuArt" class="navMnu"> <h2><a href="index.html" title="Strona główna">www.accdb.pl</a></h2> <div class="paddvert"> <div id="mnuArtO" class="opis"> <p> <img id="logo" src="images/logo8bit.png" alt="Logo"> <span id="navMoje">Moje boje<br>z<br>MS Access</span> </p> </div><!-- END id="mnuArtO" --> <hr> <h2 id="navZag"><span>Zagadnienia</span></h2> <ul id="ul_link"> <li><a href="api.html" title="Lista artykułów o API">API</a></li> <li><a href="bmp.html" title="24-bitowa bitmapa">Bitmapa</a></li> <li><a href="docmd.html" title="Metody obiektu DoCmd">DoCmd - metody</a></li> <li><a href="form.html" title="O formularzach">Formularze</a></li> <li><a href="funkcja.html" title="Wbudowane funkcje">Funkcje VBA</a></li> <li><a href="instrukcja.html" title="Instrukcje VBA">Instrukcje VBA</a></li> <li><a href="akcja.html" title="Akcja (makro)">Makra - (Akcje)</a></li> <li><a href="metoda.html" title="Metody w MS Access">Metody obiektów</a></li> <li><a href="plik.html" title="Operacje na plikach">Pliki</a></li> <li><a href="tekst.html" title="Przetwarzanie tekstu">Tekst</a></li> <li><a href="wlasciwosc.html" title="Właściwości MS Access">Właściwości obiektów</a></li> <li><a href="vba.html" title="Artykułów o VBA">VBA</a></li> <li><a href="zdarzenie.html" title="Zdarzenia w MS Access">Zdarzenia (events)</a></li> </ul> </div><!-- END id="paddvert" --> </div><!-- END id="mnuArt" --> <div id="mnuAcc" class="navMnu"> <h2>Przetwarzanie tekstu</h2> <div class="paddvert"> <div id="mnuAccO" class="opis"> <p> <span> Jakiś tekst … Opis zagadnień … </span> </p> </div><!-- END id="mnuAccO" --> <ul id="nav_art"> <li><a href="tekst.html" title="Funkcje MS Access">Spis. Przetwarzanie tekstu</a></li> <li><a href="tekst-isunicode.html" title="Czy Unicode">tekstIsUnicode(...)</a></li> <li><a href="tekst-ascii-to-utf8.html" title="ASCI na UTF8">ASCII »» UTF8.</a><li> <li><a href="tekst-utf8-to-ascii.html" title="UTF8 na ASCI">UTF8 »» ASCII.</a><li> </ul> </div> </div><!-- END id="mnuAcc" --> </nav> <aside> <!-- tekst Aside --> </aside> <footer> <!-- tekst footer --> </footer> </div><!-- END id="container" --> </body></html>
Odczyt tekstu pomiędzy identyfikatorami (tagami, znacznikami).
Jeżeli dobrze oznaczyliśmy „strategiczne” miejsca w pliku *.html za pomocą identyfikatorów, bądź komentarzy
o określonej, indywidualnej nazwie to możemy przystąpić do dzieła ....
Plik *.html mamy już zapisany w zmiennej sTekstHtml, więc za pomocą funkcji
InStr pobieramy wystąpienia tagu startowego,
następnie pozycję tagu końcowego, a pomiędzy tymi tagami, a raczej za pozycją ostatniego znaku tagu startowego
i przed pozycją pierwszego znaku tagu końcowego znajduje się szukany tekst.
Mając określoną pozycję pierwszego i ostatniego znaku szukanego tekstu, za pomocą funkcji
Mid pobieramy tekst z ciągu wejściowego.
⊗ Public Function tekstExtractTextFromHtml( _ ByVal sTextHtml As String, _ ByVal sTagStart As String, _ ByVal sTagEnd As String, _ Optional ByVal lStart As Long = 1, _ Optional lRetEndPos As Long = 0, _ Optional ByVal fRaiseErr As Boolean = False) As String
- Pobiera z wejściowego ciągu znaków sTextHtml podciąg znaków, zawarty pomiędzy tagiem (znacznikiem) startowym sTagStart, a tagiem (znacznikiem) końcowym sTagEnd.
- argumenty:
- sTextHtml
- wejściowy ciąg znaków, z którego ma zostać pobrany tekst znajdujący się pomiędzy tagiem (znacznikiem) początkowym sTagStart i tagiem (znacznikiem) końcowym sTagEnd,
- sTagStart
-
tag (znacznik) początkowy, za którym znajduje się tekst do pobrania. Jeżeli tag (znacznik)
początkowy sTagStart nie zostanie znaleziony w ciągu wejściowym sTextHtml, generowany jest
błąd wykonania o numerze:
errNotInString = vbObjectError + err_plikError + 10, (err_plikError = 100), - sTagEnd
-
tag (znacznik) końcowy, określający koniec tekstu do pobrania. Jeżeli tag (znacznik)
końcowy sTagEnd nie zostanie znaleziony w ciągu wejściowym sTextHtml, generowany jest
błąd wykonania o numerze:
errNotInString = vbObjectError + err_plikError + 10, (err_plikError = 100), - lStart
- argument nieobowiązkowy. Domyślna wartość = 1. Pozycja znaku od której będzie szukany tag (znacznik) początkowy. Dla wartości argumentu lStart < 1 generowany jest błąd wykonania o numerze errInvalidStart = vbObjectError + err_plikError + 1, (err_plikError = 100), Dla wartości argumentu lStart > Len(sTextHtml) (większy niz długość ciągu wejściowego) generowany jest błąd wykonania o numerze errStartEOF = vbObjectError + err_plikError + 11, (err_plikError = 100),
- lRetEndPos
- argument nieobowiązkowy. Domyślna wartość = 0. Bez względu na przekazaną wartość zwracana jest ByRef pozycja ostatniego znaku tagu (znacznika) końcowego sTagEnd. Gdy tag (znacznik) początkowy lub tag (znacznik) końcowy nie zostanie znaleziony wartość zwracanego ByRef argumentu lRetEndPos nie ulega zmianie. Znajomość pozycji ostatniego znaku tagu (znacznika) końcowego umożliwia w następnym wywołaniu funkcji, szukanie tagu startowego i końcowego za pozycją bieżącego tagu końcowego. Jest to istotne, gdy w zmiennej sTextHtml występuje więcej tagów (znaczników) o tej samej nazwie np. <section>, <header>, <h1>, <h2>.
- fRaiseErr
- argument nieobowiązkowy. Domyślna wartość = False. Dla wartości True, przy nieprawidłowych wartościach argumentu lStart, bądź braku tagu startowego sTagStart lub końcowego sTagEnd generowany będzie błąd wykonania o określonym numerze.
- zwraca:
-
Przy powodzeniu zwraca ciąg znaków znajdujący się pomiędzy tagiem (znacznikiem) startowym sTagStart, a tagiem (znacznikiem) końcowym sTagEnd.
Przy niepowodzeniu, bądź gdy tag (znacznik) początkowy lub tag (znacznik) końcowy nie zostanie znaleziony, funkcja zwraca ciąg zerowej długości "". - autor: Zbigniew Bratko
- data: 09.02.2018
Option Compare Database Option Explicit 'dolna granica zakresu numerów błędów dotyczących plików Private Const err_plikError As Long = 100 ' Numer początkowy bajtu (znaku, linii), nie może być mniejszy niż 1 Private Const errInvalidStart As Long = vbObjectError + err_plikError + 1 ' W pliku wejściowym nie istnieje szukany podciąg znaków Private Const errNotInString As Long = vbObjectError + err_plikError + 10 ' Pozycja startowa wyszukiwania jest większa niż długość ciągu wejściowego Private Const errStartEOF As Long = vbObjectError + err_plikError + 11 Public Function tekstExtractTextFromHtml( _ ByVal sTextHtml As String, _ ByVal sTagStart As String, _ ByVal sTagEnd As String, _ Optional ByVal lStart As Long = 1, _ Optional lRetEndPos As Long = 0, _ Optional ByVal fRaiseErr As Boolean = False) As String On Error GoTo Err_Handler Dim lInStrStart As Long Dim lInStrEnd As Long Const conProcName As String = "Funkcja tekstExtractTextFromHtml(...)" ' pozycja znaku startowego nie może być mniejsza od Zera If lStart < 1 Then tekstExtractTextFromHtml = "" If fRaiseErr = True Then Err.Raise errInvalidStart Exit Function End If ' pozycja znaku startowego nie może być większa niż długość ciągu If lStart < Len(sTextHtml) Then tekstExtractTextFromHtml = "" If fRaiseErr = True Then Err.Raise errStartEOF Exit Function End If ' pobierz pozycję tagu startowego lInStrStart = InStr(lStart, sTextHtml, sTagStart, vbBinaryCompare) If lInStrStart = 0 Then tekstExtractTextFromHtml = "" If fRaiseErr = True Then Err.Raise errNotInString, , _ " początkowy " & sTagStart & " za znakiem nr " & lStart End If Exit Function End If ' pobierz pozycję tagu końcowego, zacznij szukać za ostatnim znakiem tagu startowego lInStrEnd = InStr(lInStrStart + Len(sTagStart), sTextHtml, sTagEnd, vbBinaryCompare) If lInStrEnd = 0 Then tekstExtractTextFromHtml = "" If fRaiseErr = True Then Err.Raise errNotInString, , _ " końcowy " & sTagEnd & " za znakiem nr " & (lInStrStart + Len(sTagStart)) End If Exit Function End If ' oblicz pozycję początkową tekstu do pobrania lInStrStart = lInStrStart + Len(sTagStart) ' zwróć ByRef pozycję ostatniego znaku tagu końcowego, by umożliwić w następnym ' wywołaniu szukanie tagu startowego i końcowego za pozycją bieżącego tagu końcowego lRetEndPos = lInStrEnd + Len(sTagStart) ' pobierz tekst pomiędzy tagami tekstExtractTextFromHtml = Mid$(sTextHtml, lInStrStart, lInStrEnd - lInStrStart) Exit_Here: Exit Function Err_Handler: Select Case Err.Number Case 0 ' nie ma błędu Case errInvalidStart Err.Raise errInvalidStart, conProcName, _ "Niewłaściwa wartość argumentu lStart." & vbNewLine & _ "Prawidłowo: [lStart] > 0" Case errNotInString Err.Raise errNotInString, conProcName, _ "Identyfikator " & Err.Description & " nie istnieje !" Case errStartEOF Err.Raise errStartEOF, conProcName, _ "Niewłaściwa wartość argumentu lStart." & vbNewLine & _ "Przekroczona długość ciągu wejściowego" Case Else Err.Raise Err.Number, conProcName, _ "Nieprzewidziany błąd!" & vbNewLine & _ Err.Description End Select Resume Exit_Here End Function
Zamiana tekstu pomiędzy identyfikatorami (tagami, znacznikami).
⊗ Public Function tekstInsertTextInHtml( _ ByVal sTextHtml As String, _ ByVal sTagStart As String, _ ByVal sTagEnd As String, _ ByVal sInsertText As String, _ Optional ByVal lStart As Long = 1, _ Optional lRetEndPos As Long = 0, _ Optional ByVal fRaiseErr As Boolean = False) As String
- Zamienia w wejściowym ciągu znaków sTextHtml podciąg znaków, zawarty pomiędzy tagiem (znacznikiem) startowym sTagStart, a tagiem (znacznikiem) końcowym sTagEnd na ciąg znaków sInsertText.
- argumenty:
- sTextHtml
- wejściowy ciąg znaków, w którym tekst zawarty między tagami (znacznikami) początkowym i końcowym, ma zostać zamieniony na tekst sInsertText
- sTagStart
- tag (znacznik) początkowy, za którym ma być wstawiony tekst
sInsertText. Tekst pomiędzy tagiem (znacznikiem) początkowym sTagStart
a tagiem (znacznikiem) końcowym sTagStart zostaje w całości zastąpiony.
Jeżeli tag (znacznik) początkowy sTagStart nie zostanie
znaleziony w ciągu wejściowym sTextHtml, generowany jest błąd wykonania o numerze:
errNotInString = vbObjectError + err_plikError + 10, (err_plikError = 100), - sTagEnd
- tag (znacznik) końcowy, wyznaczający końcową pozycję wstawianego
tekstu. Tekst pomiędzy tagiem (znacznikiem) początkowym sTagStart
a tagiem (znacznikiem) końcowym sTagStart zostaje w całości zastąpiony.
Jeżeli tag (znacznik) końcowy sTagEnd nie zostanie
znaleziony w ciągu wejściowym sTextHtml, generowany jest błąd wykonania o numerze:
errNotInString = vbObjectError + err_plikError + 10, (err_plikError = 100), - sInsertText
- tekst, który ma być wstawiony pomiędzy tagiem (znacznikiem) początkowym sTagStart a tagiem (znacznikiem) końcowym sTagStart
- lStart
-
argument nieobowiązkowy. Domyślna wartość = 1. Pozycja znaku od której będzie
szukany tag (znacznik) początkowy. Dla wartości argumentu lStart < 1 generowany
jest błąd wykonania o numerze:
errInvalidStart = vbObjectError + err_plikError + 1, (err_plikError = 100), Dla wartości argumentu lStart > Len(sTextHtml) (większy niz długość ciągu wejściowego) generowany jest błąd wykonania o numerze:
errStartEOF = vbObjectError + err_plikError + 11, (err_plikError = 100), - lRetEndPos
- argument nieobowiązkowy. Domyślna wartość = 0. Bez względu na przekazaną wartość zwracana jest ByRef pozycja ostatniego znaku tagu (znacznika) końcowego sTagEnd. Gdy tag (znacznik) początkowy lub tag (znacznik) końcowy nie zostanie znaleziony wartość zwracanego ByRef argumentu lRetEndPos nie ulega zmianie. Znajomość pozycji ostatniego znaku tagu końcowego umożliwia w następnym wywołaniu funkcji, szukanie tagu startowego i końcowego za pozycją bieżącego tagu końcowego. Istotne, gdy w zmiennej sTextHtml występuje więcej tagów (znaczników) o tej samej nazwie np. <section>, <header>, <h1>, <h2>.
- fRaiseErr
- argument nieobowiązkowy. Domyślna wartość = False. Dla wartości True, przy nieprawidłowych wartościach argumentu lStart, bądź braku tagu startowego sTagStart lub końcowego sTagEnd generowany będzie błąd wykonania o określonym numerze.
- zwraca:
-
Przy powodzeniu zwraca wejściowy ciąg znaków sTextHtml w którym pomiędzy tagiem (znacznikiem) startowym, od pozycji określonej przez argument lStart i tagiem (znacznikiem końcowym został wstawiony tekst sInsertText.
Przy niepowodzeniu, bądź gdy tag (znacznik) początkowy lub tag (znacznik) końcowy nie zostanie znaleziony, funkcja zwraca ciąg zerowej długości "". - autor: Zbigniew Bratko
- data: 09.02.2018
Option Compare Database Option Explicit 'dolna granica zakresu numerów błędów dotyczących plików Private Const err_plikError As Long = 100 ' Numer początkowy bajtu (znaku, linii), nie może być mniejszy niż 1 Private Const errInvalidStart As Long = vbObjectError + err_plikError + 1 ' W pliku wejściowym nie istnieje szukany podciąg znaków Private Const errNotInString As Long = vbObjectError + err_plikError + 10 ' Pozycja startowa wyszukiwania jest większa niż długość ciągu wejściowego Private Const errStartEOF As Long = vbObjectError + err_plikError + 11 Public Function tekstInsertTextInHtml( _ ByVal sTextHtml As String, _ ByVal sTagStart As String, _ ByVal sTagEnd As String, _ ByVal sInsertText As String, _ Optional ByVal lStart As Long = 1, _ Optional lRetEndPos As Long = 0, _ Optional ByVal fRaiseErr As Boolean = False) As String On Error GoTo Err_Handler Dim lInStrStart As Long Dim lInStrEnd As Long Const conProcName As String = "Funkcja tekstInsertTextInHtml(...)" ' pozycja znaku startowego nie może być mniejsza od Zera If lStart < 1 Then tekstInsertTextInHtml = "" If fRaiseErr = True Then Err.Raise errInvalidStart Exit Function End If ' pozycja znaku startowego nie może być większa niż długość ciągu If lStart > Len(sTextHtml) Then tekstInsertTextInHtml = "" If fRaiseErr = True Then Err.Raise errStartEOF Exit Function End If ' pobierz pozycję tagu startowego lInStrStart = InStr(lStart, sTextHtml, sTagStart, vbBinaryCompare) If lInStrStart = 0 Then tekstInsertTextInHtml = "" If fRaiseErr = True Then Err.Raise errNotInString, , _ " początkowy " & sTagStart & " za znakiem nr " & lStart End If Exit Function End If ' pobierz pozycję tagu końcowego, zacznij szukać za ostatnim znakiem tagu startowego lInStrEnd = InStr(lInStrStart + Len(sTagStart), sTextHtml, sTagEnd, vbBinaryCompare) If lInStrEnd = 0 Then 'tekstExtractTextFromHtml = "" If fRaiseErr = True Then Err.Raise errNotInString, , _ " końcowy " & sTagEnd & " za znakiem nr " & (lInStrStart + Len(sTagStart)) End If Exit Function End If ' zwróć ByRef pozycję ostatniego znaku tagu końcowego, by umożliwić w następnym ' wywołaniu szukanie tagu startowego i końcowego za pozycją bieżącego tagu końcowego lRetEndPos = lInStrEnd + Len(sTagStart) ' wstaw tekst pomiędzy tagi tekstInsertTextInHtml = _ Left$(sTextHtml, lInStrStart - 1 + Len(sTagStart)) & _ sInsertText & _ Mid$(sTextHtml, lInStrEnd) Exit_Here: Exit Function Err_Handler: Select Case Err.Number Case 0 ' nie ma błędu Case errInvalidStart Err.Raise errInvalidStart, conProcName, _ "Niewłaściwa wartość argumentu lStart." & vbNewLine & _ "Prawidłowo: [lStart] > 0" Case errNotInString Err.Raise errNotInString, conProcName, _ "Identyfikator " & Err.Description & " nie istnieje !" Case errStartEOF Err.Raise errStartEOF, conProcName, _ "Niewłaściwa wartość argumentu lStart." & vbNewLine & _ "Przekroczona długość ciągu wejściowego" Case Else Err.Raise Err.Number, conProcName, _ "Nieprzewidziany błąd!" & vbNewLine & _ Err.Description End Select Resume Exit_Here End Function
Tabela z danymi informacyjnymi o stronach www.
- 1. ⇒ToDo⇐ Stworzyć tabelę w której przechowywane będą dane dotyczące poszczególnych stron, takie jak:
- • pełna ścieżka pliku strony *.html
- • nazwa pliku strony *.html
- • <title>tytuł strony</title>
- • <header><h1> nagłówek strony</h1></header>
- • <section><header><h1>nagłówek sekcji</h1></header></section>
- • <section><article><header><h1>nagłówek artykułu w sekcji</h1></header></article></section>
- • <section><article><h1>artykuł w sekcji</h1></article></section>
Struktura tabela z danymi plików *.html
Do zrobienia:
Aby efektywnie (nie efektownie), szybko i bezboleśnie (bez błędów) przetwarzać te kilkadziesiąt pojedynczych stron trzeba wcześniej popełnić kilka stron z rozwiązaniami przedstawionych poniżej problemów.
- 1. ⇒ToDo⇐ Stworzyć tabelę w której przechowywane będą dane dotyczące poszczególnych stron, takie jak:
- • nazwa pliku strony *.html
- • <title>tytuł strony</title>
- • <h1> nagłówek strony</h1>
- • <h1>nagłówek sekcji</h1>
- • <h1>nagłówek artykułu sekcji</h1>
- 2. ⇒ToDo⇐ Wybór folderu. Napisać funkcję.
- Okno dialogowe wyboru folderu. Funkcja API SHBrowseForFolder(...)
- 3. ⇒ToDo⇐ Wybór pliku. Napisać funkcję.
- Okno dialogowe wyboru pliku. Funkcja API GetOpenFileName(...)
- 4. ⇒ToDo⇐ Konwersja tekstu z UTF8 na Windows 1250.
- Skorzystać z funkcji tekstUTF8ToString(...) ze strony UTF8 »» ASCII.
- 5. ⇒ToDo⇐ Konwersja tekstu z Windows 1250 na UTF8.
-
Skorzystać z funkcji tekstStringToUTF8(...) ze strony
ASCII »» UTF8.
- 6. ⇒ToDo⇐Jeszcze nie znane, ale na pewno, zapewne pewne, pewne problemy.
- No pewnie ....