Function InsertSpaces(S As String) As String
InsertSpaces = Trim(Replace(StrConv(S, vbUnicode), Chr(0), " "))
End Function
Excel 2007 | |||
---|---|---|---|
A | |||
1 | ABC | ||
2 | 123 | ||
3 | A1B2C3 | ||
4 | 1A2B3C | ||
5 | |||
Sheet1 |
Excel 2007 | |||
---|---|---|---|
A | |||
1 | A B C | ||
2 | 1 2 3 | ||
3 | A 1 B 2 C 3 | ||
4 | 1 A 2 B 3 C | ||
5 | |||
Sheet1 |
Sub AddSpaces()
' hiker95, 02/07/2016, ME919631
Dim r As Range
Application.ScreenUpdating = False
For Each r In Range("A1", Range("A" & Rows.Count).End(xlUp))
r = Trim(Replace(StrConv(r, vbUnicode), Chr(0), " "))
Next r
Columns("A").AutoFit
Application.ScreenUpdating = True
End Sub
A fair point. I do not have much experience (actually, almost none) working with Unicode characters; however, I was able to "dummy up" the following UDF which appears to work correctly no matter what Unicode characters are in the text argument passed into it (though it breaks my heart that it is not a one-liner)...A remark: excel, like most of the applications nowadays, uses Unicode that has tens of thousands of characters.
Both solutions will only work for the first 256 characters which can work for the English language (with no special symbols) but not much more than that.
Function InsertSpaces(S As String) As String
Dim X As Long, Y As Long, Z As Long, Bin() As Byte, Bout() As Byte
If Len(S) Then
Bin = StrConv(S, vbUnicode)
ReDim Bout(LBound(Bin) To 4 * UBound(Bin))
Z = LBound(Bin)
For X = LBound(Bin) To UBound(Bin) - 1 Step 4
For Y = 0 To 7
If Y < 4 Then
Bout(Z + Y) = Bin(X + Y)
ElseIf Y > 4 Then
Bout(Z + Y) = 0
Else
Bout(Z + Y) = 32
End If
Next
Z = Z + 8
Next
InsertSpaces = Trim(Replace(StrConv(Bout, vbFromUnicode), Chr(0), " "))
End If
End Function
Function SpaceOut(S As String)
With CreateObject("VBScript.RegExp")
.Global = True
.Pattern = "(.)" 'or "(\S)" or "([A-Za-z0-9])"
SpaceOut = RTrim(.Replace(S, "$1 "))
End With
End Function
When I first tried getting straight VB string functions to manipulate a cell with Unicode characters in it, I had problems (if I remember correctly, ASCII 63 characters kept being returned). Can you post the code you had in mind? Anyway, I figured instead of battling VB over this, that using Byte arrays should work... and besides, Byte arrays handle strings quite quickly (see my response to Peter below).Hi Rick
You could also loop through the characters adding spaces in between.
I think your code is much slower than the code I posted. Here is how I tested the speed... I put ABC in cell A1 and an 8-character all Unicode string in cell A2 and I left cell A3 blank... I then copied A1:A3 down to A5005 and ran the following code (several times with your function and then several times with my function where the red text is)... or another udf:
This to insert a space after every character.
If the requirement was to add a space after every character except spaces then use the first alternative pattern.
If the requirement is, as the original wording could be interpreted, to only insert spaces after letters or digits (ie exclude punctuation etc) then use the second alternative pattern.
Rich (BB code):Function SpaceOut(S As String) With CreateObject("VBScript.RegExp") .Global = True .Pattern = "(.)" 'or "(\S)" or "([A-Za-z0-9])" SpaceOut = RTrim(.Replace(S, "$1 ")) End With End Function
Sub Test()
Dim X As Long, Dummy As String
Debug.Print "? Abs(" & Timer & " - ";
For X = 1 To 5005
Dummy = [B][COLOR="#FF0000"]InsertSpaces[/COLOR][/B](Cells(X, "A").Value)
Next
Debug.Print Timer & ")"
End Sub
You are certainly correct Rick. With only 2 samples & no indication of the data size, I certainly didn't focus on speed. I posted because I thought that there was an issue around unicode characters, though on looking back I see that wasn't really related to this thread.I think your code is much slower than the code I posted.
Function SpaceOut(s As String) As String
Static RX As Object
If RX Is Nothing Then
Set RX = CreateObject("VBScript.RegExp")
RX.Global = True
End If
RX.Pattern = "(.)" 'or "(\S)" or "([A-Za-z0-9])"
SpaceOut = RTrim(RX.Replace(s, "$1 "))
End Function
Function SpaceIt(s As String) As String
Dim i As Long
Dim tmp As String
If Len(s) Then
tmp = Space(Len(s) * 2 - 1)
For i = 1 To Len(s)
Mid(tmp, i * 2 - 1) = Mid(s, i, 1)
Next i
SpaceIt = tmp
End If
End Function