onko vb kutoselle olemassa vastaavanlaista funktiota kuin substr_count? Substr_countin infoa: https://www.ohjelmointiputka.net/hak/?kieli=PHP&nimi=substr_count
Sikäli kun tiedän, niin ei, mutta voit tehdä oman helposti InStr:ää hyödyntämällä.
ok. kiitos.
Public Function Substr_Count(merkkijono as String,merkki as String) as Long Static Count as Long For i = 0 to Len(merkkijono) If Mid(merkkijono,i,1)=merkki Then Count=Count +1 Next i Substr_Count = Count End Function
Jos halutaan että kirjainkoolla ei ole väliä niin sillon scannataan ucasena tai lcasena ihan sama
Jos vauhdille on tarvetta...
' sijoita omaan moduuliinsa
Option Explicit
Private Declare Sub RtlMoveMemory Lib "ntdll.dll" (ByRef lpvDest As Any, ByRef lpvSrc As Any, ByVal cbLen As Long)
'Private Declare Function VarPtrArray Lib "msvbvm50.dll" Alias "VarPtr" (Var() As Any) As Long
Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (Var() As Any) As Long
Private BufStrHeader(5) As Long
Private BufFindHeader(5) As Long
Private BufStr() As Integer
Private BufFind() As Integer
Private OldStr As Long
Private OldFind As Long
Public Sub SisicInitialize()
BufStrHeader(0) = 1
BufStrHeader(1) = 2
BufStrHeader(4) = &H7FFFFFFF
BufFindHeader(0) = 1
BufFindHeader(1) = 2
BufFindHeader(4) = &H7FFFFFFF
OldStr = 0
OldFind = 0
End Sub
Public Sub SisicTerminate()
RtlMoveMemory ByVal VarPtrArray(BufStr), 0&, 4
RtlMoveMemory ByVal VarPtrArray(BufFind), 0&, 4
End Sub
Public Function SisicM(ByRef pStr As Long, ByRef pFind As Long, ByRef lenStr As Long, ByRef lenFind As Long) As Long
Dim lngA As Long, lngB As Long, lngC As Long
Dim intFind As Integer, intStr As Integer
Dim intFirst As Integer, intLast As Integer, lngCounter As Long, lngFlag As Long
If OldStr <> pStr Then
BufStrHeader(3) = pStr
RtlMoveMemory ByVal VarPtrArray(BufStr), VarPtr(BufStrHeader(0)), 4
OldStr = pStr
End If
If OldFind <> pFind Then
BufFindHeader(3) = pFind
RtlMoveMemory ByVal VarPtrArray(BufFind), VarPtr(BufFindHeader(0)), 4
OldFind = pFind
End If
If lenFind = 1 Then
intFirst = BufFind(0)
For lngA = lenStr - 1 To 0 Step -1
intStr = BufStr(lngA)
If intFirst = intStr Then lngCounter = lngCounter + 1
Next lngA
ElseIf lenFind = 2 Then
lenFind = 1
intFirst = BufFind(0)
intLast = BufFind(lenFind)
For lngA = lenStr - 1 To lenFind Step -1
intStr = BufStr(lngA)
If intLast = intStr Then
intStr = BufStr(lngA - lenFind)
If intFirst = intStr Then lngCounter = lngCounter + 1: lngA = lngA - lenFind
End If
Next lngA
Else
lenFind = lenFind - 1
intFirst = BufFind(0)
intLast = BufFind(lenFind)
For lngA = lenStr - 1 To lenFind Step -1
intStr = BufStr(lngA)
If intLast = intStr Then
intStr = BufStr(lngA - lenFind)
If intFirst = intStr Then
lngC = lngA - 1
For lngB = lenFind - 1 To 1 Step -1
intFind = BufFind(lngB)
intStr = BufStr(lngC)
If Not (intFind = intStr) Then lngFlag = 1: Exit For
lngC = lngC - 1
Next lngB
If lngFlag = 1 Then lngFlag = 0 Else lngCounter = lngCounter + 1: lngA = lngC
End If
End If
Next lngA
End If
SisicM = lngCounter
End FunctionPäihittää mm. useamman InStr:n avulla tehdyn funktion mennen tullen. Optimointi on tosin tehnyt tämän käytöstä vähän vaikeampaa: SisicInitialize täytyy kutsua vaikka ohjelman alussa ja SisicTerminate sitten kun ohjelma suljetaan. Lisäksi kutsu tapahtuu näin:
Määrä = SisicM(StrPtr(Teksti), StrPtr(Hakusana), Len(Teksti), Len(Hakusana))
Nopeuden huomaa vasta sitten, kun ohjelman kääntää exeksi asettaen Advanced Optimizations -ikkunan kohtiin ruksit.
No, kiitos kummallekin!
Korjausta tuohon minun koodiini
Public Function Substr_Count(merkkijono As String, merkki As String) As Long Dim Count As Long For i = 1 To Len(merkkijono) If Mid(UCase(merkkijono), i, Len(merkki)) = UCase(merkki) Then Count = Count + 1 Next i Substr_Count = Count End Function
Aihe on jo aika vanha, joten et voi enää vastata siihen.