Excel VBAを使用して複数の区切り文字を含む文字列を分割したいと考えています。文字列の1つは、vbaで複数の区切り文字を含む文字列を分割する方法は?
d1-d2 d3 d4
2つのデリメータとしてスペースがあります。私はsplit
関数を試しましたが、それは1つのdelimeterでのみ行います。
Excel VBAを使用して複数の区切り文字を含む文字列を分割したいと考えています。文字列の1つは、vbaで複数の区切り文字を含む文字列を分割する方法は?
d1-d2 d3 d4
2つのデリメータとしてスペースがあります。私はsplit
関数を試しましたが、それは1つのdelimeterでのみ行います。
あなたは最初の最初の文字列にREPLACE
を行い、その後、分割を行うことができます:
newString = Replace(origString, "-", " ")
newArray = SPlit(newString, " ")
前の答えは良いですが、分割する背中合わせ文字がある場合は、問題が発生する原因となりますそれは、「こんにちは、先生、今日はどうやっていますか?すべての句読点やスペースにこの場合、HelloとSirの間に空白の文字列があります。
はチップピアソンは、使用のために偉大なVBA機能を提供し、このシナリオを処理するには、次の http://www.cpearson.com/excel/splitondelimiters.aspxその場合にあなたができる
newString = Replace(origString, "-", " ")
newString2 = replace(newstring, " " , " ")
newArray = SPlit(newString, " ")
ないだけにTRIMを使用しての提案二重スペースを排除することは完全には明らかではない。 VBAのTRIM機能は、先頭と末尾のスペースのみを削除します。文字列内の二重スペースには触れません。そのためにワークシート機能を使用する必要があります。
私は、チップピアソンの答えを素早く見て、性能面で少し改善できると思っていたので、約40%速かったようですあなた自身)。実際の文字ではなくバイト配列を使用して値を比較するので、より高速です(1.0E-5
と1サイクルあたり1.7E-5
秒)。ここでは、チップピアソンのような文字列の配列を返す関数です:
Function SplitMultiDelims2(Text As String, DelimChars As String) As String()
'''
'Function to split a string at multiple charachters
'Use like SplitMultiDelims2("This:is-a,test string", ":-,")
'Returns an array, in that example SplitMultiDelims2("This:is-a,test string", ":-,")(4) would be "test string"
'''
Dim bytes() As Byte
Dim delims() As Byte
Dim i As Long, aub As Long, ub As Long
Dim stack As String
Dim t() As String
Dim tLen As Long
tLen = Len(Text)
If tLen = 0 Then
Exit Function
End If
ReDim t(1 To tLen) 'oversize array to avoid Redim Preserve too often
bytes = StrConv(Text, vbFromUnicode)
delims = StrConv(DelimChars, vbFromUnicode)
ub = UBound(bytes)
For i = 0 To ub
If Contains(delims, bytes(i)) Then
aub = aub + 1
t(aub) = stack
stack = ""
Else
stack = stack & Chr(bytes(i))
End If
Next i
t(aub + 1) = stack
ReDim Preserve t(1 To aub + 1) 'Works marginally faster if you delete this line,
'however it returns an oversized array (which is a problem if you use UBOUND of the result,
'but fine if you are just looking up an indexed value like the 5th string)
SplitMultiDelims2 = t
End Function
'and a 2nd function called by the first one
Function Contains(arr, v As Byte) As Boolean 'checks if Byte v is contained in Byte array arr
Dim rv As Boolean, lb As Long, ub As Long, i As Long
lb = LBound(arr)
ub = UBound(arr)
For i = lb To ub
If arr(i) = v Then
rv = True
Exit For
End If
Next i
Contains = rv
End Function
ここでテストログだ(彼はSplitMultiDelimsで、鉱山がSplitMultiDelims2ある)メモリ書き込みハンディキャップ
を回避するために、両方向の> SplitMultiDelims: 1.76105267188204E-05s per cycle 'this is the important figure
> i = 568064 iterations in 10.00390625 seconds
>Test completed: 08/06/2017 10:23:22
> SplitMultiDelims2: 1.05756701906142E-05s per cycle
>i = 947044 iterations in 10.015625 seconds
>Test completed: 08/06/2017 10:23:32
> SplitMultiDelims2: 1.04176859354441E-05s per cycle
>i = 960656 iterations in 10.0078125 seconds
>Test completed: 08/06/2017 10:23:54
> SplitMultiDelims: 1.76228941673255E-05s per cycle
>i = 567887 iterations in 10.0078125 seconds
>Test completed: 08/06/2017 10:24:04
ランは
以下のテストコードは、Timer
を使用しているため、過度に正確ではありませんが、違いを実証するのに十分です。
Sub testSplit()
Dim t As Double, dt As Double
Dim s As String
Dim i As Long
t = Timer: i = 0: dt = 0: s = ""
Do Until dt > 10 'loop for 10 seconds
s = SplitMultiDelims("This:is-a,test string", ":-,")(1)
dt = Timer - t
i = i + 1
Loop
Debug.Print "SplitMultiDelims: " & dt/i & "s per cycle" & vbCrLf & "i = " & i; " iterations in " & dt; " seconds" & vbCrLf & "Test completed: " & Now
t = Timer: i = 0: dt = 0: s = ""
Do Until dt > 10 'loop for 10 seconds
s = SplitMultiDelims2("This:is-a,test string", ":-,")(1)
dt = Timer - t
i = i + 1
Loop
Debug.Print "SplitMultiDelims2: " & dt/i & "s per cycle" & vbCrLf & "i = " & i; " iterations in " & dt; " seconds" & vbCrLf & "Test completed: " & Now
End Sub
いくつかの異なるデリミタで分割する。区切り文字を配列内にリストし、forループに置き換えてから分割します。
For Each tSep In Array(";", " ", ".", "<==", ":", vbCr)
val1 = Replace(val1, tSép, "°")
Next tSep
tab1 = Split(val1, "°")
トリム機能を使用できるようにするには – juanora