2011-10-06 25 views

Respuesta

23

Se podría primero hacer una REPLACE en la cuerda primero y luego hacer la división:

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

La respuesta anterior es bueno, pero va a hacer que usted tenga problemas si existen espalda con espalda caracteres se dividan en eso están en la Cadena, como por ejemplo, "¡Hola, señor! ¿Cómo estás hoy?" en todos los signos de puntuación y espacios En este caso, obtendría una cadena en blanco entre Hello y Sir.

para manejar este escenario de Chip Pearson ofrece una gran función de VBA para su uso: http://www.cpearson.com/excel/splitondelimiters.aspx

0

en cuyo caso se podría hacer

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

Si desea evitar el doble espacio, puede usar la función trim – juanora

1
No

permitido hacer comentarios (aún), pero la sugerencia de utilizar TRIM para eliminar un doble espacio no es del todo claro. La función TRIM en VBA solo elimina espacios iniciales y finales. No toca espacios dobles dentro de una cadena. Tendría que usar la función de hoja de cálculo para eso.

0

Añadiré que eché un vistazo rápido a la respuesta de Chip Pearson, y pensé que podría mejorarse un poco en términos de rendimiento, así que escribí la mía que parece ser un 40% más rápida (no dude en probarla) tú mismo). Es más rápido (1.0E-5 frente a 1.7E-5 segundos por ciclo) porque usa matrices de bytes en lugar de caracteres reales para comparar valores. Aquí está la función que devuelve una matriz de cadenas como la viruta de 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 

Aquí está el registro de la prueba (el suyo es SplitMultiDelims, la mía está 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 

Ejecutar en ambas direcciones para evitar la escritura de la memoria perjudica

código

prueba siguiente se utiliza Timer modo no demasiado precisa, pero lo suficientemente bueno para demostrar la diferencia

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

Para dividir con varios delimitadores diferentes; enumere los delimitadores en una matriz, reemplácelos por un ciclo for, luego divida:

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