2011-10-06 24 views

risposta

23

Si potrebbe prima fare un REPLACE sulla corda e poi fare la scissione:

newString = Replace(origString, "-", " ") 
newArray = SPlit(newString, " ") 
3

La risposta precedente è buona, ma vi farà avere problemi se ci sono back to back caratteri da dividere su quello sono nella stringa, come la divisione "Ciao, signore! Come stai, oggi?" su tutti i segni di punteggiatura e spazi. In questo caso, otterresti una stringa vuota tra Hello e Sir.

per gestire questo scenario Chip Pearson offre una grande funzione di VBA per l'uso: http://www.cpearson.com/excel/splitondelimiters.aspx

0

nel qual caso si potrebbe fare

newString = Replace(origString, "-", " ") 
    newString2 = replace(newstring, " " , " ") 
    newArray = SPlit(newString, " ") 
+0

se si desidera evitare il doppio spazio è possibile utilizzare la funzione di rifilo – juanora

1

Non è permesso di commentare (ancora), ma il suggerimento di utilizzare TRIM eliminare un doppio spazio non è completamente chiaro. La funzione TRIM in VBA elimina solo spazi iniziali e finali. Non tocca i doppi spazi all'interno di una stringa. Dovresti usare la funzione del foglio di lavoro per quello.

0

Aggiungo che ho dato una rapida occhiata alla risposta di Chip Pearson, e ho pensato che potrebbe essere migliorato un po 'in termini di prestazioni, così ho scritto il mio che sembra essere circa il 40% più veloce (sentiti libero di testare te stesso). È più veloce (1.0E-5 rispetto a 1.7E-5 secondi per ciclo) perché utilizza i matrici di byte anziché i caratteri reali per confrontare i valori. Ecco la funzione che restituisce un array di stringhe come Chip Pearson:

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 

Ecco il resoconto della prova (il suo è SplitMultiDelims, il mio è 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 

Run in entrambe le direzioni per evitare di scrivere la memoria ostacola

Il codice di prova seguente utilizza Timer quindi non eccessivamente preciso, ma sufficiente per dimostrare la differenza

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 
1

Per dividere con diversi delimitatori; elencare i delimitatori in un array, sostituirli con un ciclo for, quindi dividere:

For Each tSep In Array(";", " ", ".", "<==", ":", vbCr) 
    val1 = Replace(val1, tSép, "°") 
Next tSep 
tab1 = Split(val1, "°")