How can I URL encode a string in Excel VBA?

后端 未结 15 2310
闹比i
闹比i 2020-11-22 11:39

Is there a built-in way to URL encode a string in Excel VBA or do I need to hand roll this functionality?

15条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-11-22 12:15

    No, nothing built-in (until Excel 2013 - see this answer).

    There are three versions of URLEncode() in this answer.

    • A function with UTF-8 support. You should probably use this one (or the alternative implementation by Tom) for compatibility with modern requirements.
    • For reference and educational purposes, two functions without UTF-8 support:
      • one found on a third party website, included as-is. (This was the first version of the answer)
      • one optimized version of that, written by me

    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.

提交回复
热议问题