Is there a built-in way to URL encode a string in Excel VBA or do I need to hand roll this functionality?
Is there a built-in way to URL encode a string in Excel VBA or do I need to hand roll this functionality?
No, nothing built-in (until Excel 2013 - see this answer).
There are three versions of URLEncode() in this answer.
A variant that supports UTF-8 encoding and is based on ADODB.Stream (include a reference to a recent version of the "Microsoft ActiveX Data Objects" library in your project):
Public Function URLEncode( _
ByVal StringVal As String, _
Optional SpaceAsPlus As Boolean = False _
) As String
Dim bytes() As Byte, b As Byte, i As Integer, space As String
If SpaceAsPlus Then space = "+" Else space = "%20"
If Len(StringVal) > 0 Then
With New ADODB.Stream
.Mode = adModeReadWrite
.Type = adTypeText
.Charset = "UTF-8"
.Open
.WriteText StringVal
.Position = 0
.Type = adTypeBinary
.Position = 3 ' skip BOM
bytes = .Read
End With
ReDim result(UBound(bytes)) As String
For i = UBound(bytes) To 0 Step -1
b = bytes(i)
Select Case b
Case 97 To 122, 65 To 90, 48 To 57, 45, 46, 95, 126
result(i) = Chr(b)
Case 32
result(i) = space
Case 0 To 15
result(i) = "%0" & Hex(b)
Case Else
result(i) = "%" & Hex(b)
End Select
Next i
URLEncode = Join(result, "")
End If
End Function
This function was found on freevbcode.com:
Public Function URLEncode( _
StringToEncode As String, _
Optional UsePlusRatherThanHexForSpace As Boolean = False _
) As String
Dim TempAns As String
Dim CurChr As Integer
CurChr = 1
Do Until CurChr - 1 = Len(StringToEncode)
Select Case Asc(Mid(StringToEncode, CurChr, 1))
Case 48 To 57, 65 To 90, 97 To 122
TempAns = TempAns & Mid(StringToEncode, CurChr, 1)
Case 32
If UsePlusRatherThanHexForSpace = True Then
TempAns = TempAns & "+"
Else
TempAns = TempAns & "%" & Hex(32)
End If
Case Else
TempAns = TempAns & "%" & _
Right("0" & Hex(Asc(Mid(StringToEncode, _
CurChr, 1))), 2)
End Select
CurChr = CurChr + 1
Loop
URLEncode = TempAns
End Function
I've corrected a little bug that was in there.
I would use more efficient (~2× as fast) version of the above:
Public Function URLEncode( _
StringVal As String, _
Optional SpaceAsPlus As Boolean = False _
) As String
Dim StringLen As Long: StringLen = Len(StringVal)
If StringLen > 0 Then
ReDim result(StringLen) As String
Dim i As Long, CharCode As Integer
Dim Char As String, Space As String
If SpaceAsPlus Then Space = "+" Else Space = "%20"
For i = 1 To StringLen
Char = Mid$(StringVal, i, 1)
CharCode = Asc(Char)
Select Case CharCode
Case 97 To 122, 65 To 90, 48 To 57, 45, 46, 95, 126
result(i) = Char
Case 32
result(i) = Space
Case 0 To 15
result(i) = "%0" & Hex(CharCode)
Case Else
result(i) = "%" & Hex(CharCode)
End Select
Next i
URLEncode = Join(result, "")
End If
End Function
Note that neither of these two functions support UTF-8 encoding.
The accepted answer's code stopped on a Unicode error in Access 2013, so I wrote a function for myself with high readability that should follow RFC 3986 according to Davis Peixoto, and cause minimal trouble in various environments.
Note: The percent sign itself must be replaced first, or it will double-encode any previously encoded characters. Replacing space with + was added, not to conform with RFC 3986, but to provide links that don't break due to formatting. It is optional.
Public Function URLEncode(str As Variant) As String
Dim i As Integer, sChar() As String, sPerc() As String
sChar = Split("%|!|*|'|(|)|;|:|@|&|=|+|$|,|/|?|#|[|]| ", "|")
sPerc = Split("%25 %21 %2A %27 %28 %29 %3B %3A %40 %26 %3D %2B %24 %2C %2F %3F %23 %5B %5D +", " ")
URLEncode = Nz(str)
For i = 0 To 19
URLEncode = Replace(URLEncode, sChar(i), sPerc(i))
Next i
End Function
The VBA-tools library has a function for that:
http://vba-tools.github.io/VBA-Web/docs/#/WebHelpers/UrlEncode
It seems to work similar to encodeURIComponent() in JavaScript.
The best of both worlds. This function uses the new(ish) worksheet function ENCODEURL() if the workbook is open in Excel 2013 or newer.
If it's an older version of Excel then this function uses htmlfile instead.
You can also force this function to use htmlfile by passing True as the optional bForceOldSchool argument.
Function URLEncode$(s$, Optional bForceOldSchool As Boolean)
Select Case True
Case bForceOldSchool Or Val(Application.Version) < 15
URLEncode = CreateObject("htmlfile").parentWindow.EncodeUriComponent(s)
Case Else: URLEncode = WorksheetFunction.EncodeURL(s)
End Select
End Function