Hurtig måde at tælle tegn på!

Tags:    visual-basic
Skrevet af Bruger #2572 @ 22.11.2002
Hurtig måde at tælle tegn på!

Hvorfor
Ja hvorfor skrive en artikel om hvordan man tæller tegn i en streng? Mere fordi jeg har lyst til at vise hvor nemt det gøres og hvordan man bedst skriver kode der er let at læse. Jeg har tit ærgret mig over hvordan nogen skriver uden at formatere med korrekt indrykning samt uden kort beskrivelse. I dette tilfælde kopierer du følgende kode ind i et nyt modul:
Option Explicit

Public Function TextCount(ByVal Text As String, ByVal SearchString As String,
Optional CaseSense As Boolean = True) As Long On Error GoTo errTrap ' Tjekker om der overhovedet er noget tekst If Len(Text) > 0 And Len(SearchString) > 0 Then If CaseSense Then ' Tegnene skal være i samme Case (Store / Små bogstaver) TextCount = UBound(Split(Text, SearchString)) Else ' Kig ikke efter tegnenes Case (Store / Små bogstaver) TextCount = UBound(Split(LCase(Text), LCase(SearchString))) End If Else TextCount = 0 End If Exit Function errTrap: ' Der opstod en fejl som der ikke er taget højde for TextCount = -1 ' Beskeden kan med fordel udelades, da vi returnerer -1 MsgBox "En fejl opstod i funktionen TextCount." & vbLf & _ "Fejlbesked: " & Err.Description, vbExclamation End Function
Læg først mærke til at der sørges for at pakke funktionen ind i en simpel men stærk errorhandler, hvis der opstår en fejl (hvad der ikke skulle kunne ske) vil funktionen returnere et -1 til koden hvorfra funktionen er kaldt. Den første egentlige kode tjekker for om der overhovedet er overført noget tekst og søgestreng, hvis en af dem mangler er det ikke nødvendigt at gøre mere end at returnere 0. Hvis forudsætningerne er ok, så er vi klar til at tælle hvor mange gange at SearchString forekommer i teksten.
Hvordan
Hvordan kan en linie som 'UBound(Split(Text, SearchString))' returnere antal forekomster? Funktionen Split danner en array som er splittet hver gang at søgestrengen forkommer, det vil sige at hvis du har en tekst der hedder "Maler mester Madsen maler mange malerier" og din søgestreng er lig med "m" så vil der blive dannet en array med følgende indhold:
Array(0) = "Maler "
Array(1) = "ester Madsen "
Array(2) = "aler "
Array(3) = "ange "
Array(4) = "alerier"
Men hvorfor lave en array når man bare vil kende forefomsten af "m", kunne man ikke lave en loop der gennemløb teksten og talte hvor mange forekomster der er? Jo selvfølgelig kunne man det, men det er bedre at bruge de indbyggede funktioner i VB så meget som muligt, da de er væsentlig hurtigere, faktisk lavede jeg en test hvor jeg henholdsvis lavede funktionen med en loop og med split komandoen, og den sidste var omkr. 10 gange hurtigere. Men kig nu på det foregående eksempel igen, læg mærke til at teksten ikke er delt ved de store M'er, for i code sprog er "m" og "M" ikke ens, derfor kan du vælge at lægge en lCase() omkring både teksten og søgestrengen, så alle store bogstaver bliver konverteret til små tegn, og du vil få dette resultat:
Array(0) = ""
Array(1) = "aler "
Array(2) = "ester 
Array(3) = "adsen "
Array(4) = "aler "
Array(5) = "ange "
Array(6) = "alerier"
Nu mangler vi bare at hente top index værdien af den Array vi har lavet, det gøres hurtigt med UBound(), og koden er faktisk færdig. Jeg håber at denne artikel kan give lidt ideer omkring formatering af kode, samt en enkel og hurtig opbygning af god kode.



Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.

Del også gerne artiklen med dine Facebook venner:  

Kommentarer (1)

User
Bruger #2572 @ 22.10.04 12:36
Lige en vigtig detalje, det gør søgningen en hel del hurtigere hvis i bruger lCase$() istedet for lCase, da den kun søger i streng værdien, på den anden måde opfører den sig som den langsomme Variant.
Du skal være logget ind for at skrive en kommentar.
t