是否有内置的方法在Excel VBA中对字符串进行URL编码,还是需要手动滚动此功能?
不,没有内置(直到Excel 2013 - 请参阅此答案).
URLEncode()
这个答案有三个版本.
具有UTF-8支持的功能.您应该使用这个(或Tom 的替代实现)来兼容现代需求.
出于参考和教育目的,没有UTF-8支持的两个功能:
在第三方网站上找到的,包括原样.(这是答案的第一个版本)
一个优化版本,由我编写
支持UTF-8编码的变体,它基于ADODB.Stream
(包括对项目中"Microsoft ActiveX Data Objects"库的最新版本的引用):
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
此功能在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
我纠正了那里的一个小虫子.
我会使用更高效(~2×快)上面的版本:
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
请注意,这两个函数都不支持UTF-8编码.
为了使其更新,自Excel 2013以来,现在有一种使用工作表函数对URL进行编码的内置方法ENCODEURL
.
要在您的VBA代码中使用它,您只需要打电话
EncodedUrl = WorksheetFunction.EncodeUrl(InputString)
文档
上述支持UTF8的版本:
Private Const CP_UTF8 = 65001 Private Declare Function WideCharToMultiByte Lib "Kernel32" ( ByVal CodePage As Long, ByVal dwflags As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, ByVal lpDefaultChar As Long, ByVal lpUsedDefaultChar As Long) As Long Public Function UTF16To8(ByVal UTF16 As String) As String Dim sBuffer As String Dim lLength As Long If UTF16 <> "" Then lLength = WideCharToMultiByte(CP_UTF8, 0, StrPtr(UTF16), -1, 0, 0, 0, 0) sBuffer = Space$(lLength) lLength = WideCharToMultiByte( CP_UTF8, 0, StrPtr(UTF16), -1, StrPtr(sBuffer), Len(sBuffer), 0, 0) sBuffer = StrConv(sBuffer, vbUnicode) UTF16To8 = Left$(sBuffer, lLength - 1) Else UTF16To8 = "" End If End Function Public Function URLEncode( _ StringVal As String, _ Optional SpaceAsPlus As Boolean = False, _ Optional UTF8Encode As Boolean = True _ ) As String Dim StringValCopy As String: StringValCopy = IIf(UTF8Encode, UTF16To8(StringVal), StringVal) Dim StringLen As Long: StringLen = Len(StringValCopy) 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$(StringValCopy, 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
请享用!
虽然,这个很老.我在这个答案中提出了一个解决方案:
Dim ScriptEngine As ScriptControl Set ScriptEngine = New ScriptControl ScriptEngine.Language = "JScript" ScriptEngine.AddCode "function encode(str) {return encodeURIComponent(str);}" Dim encoded As String encoded = ScriptEngine.Run("encode", "€ömE.sdfds")
添加Microsoft脚本控件作为参考,您就完成了.
只是旁注,因为JS部分,这是完全兼容UTF-8的.VB将从UTF-16正确转换为UTF-8.
类似于Michael-O的代码,只需要引用(后期绑定)和少一行.
*我读过,在excel 2013中,它可以更容易地完成:WorksheetFunction.EncodeUrl(InputString)
Public Function encodeURL(str As String) Dim ScriptEngine As Object Dim encoded As String Set ScriptEngine = CreateObject("scriptcontrol") ScriptEngine.Language = "JScript" encoded = ScriptEngine.Run("encodeURIComponent", str) encodeURL = encoded End Function
由于办公室2013使用内置的功能在这里.
如果在2013年之前
Function encodeURL(str As String) Dim ScriptEngine As ScriptControl Set ScriptEngine = New ScriptControl ScriptEngine.Language = "JScript" ScriptEngine.AddCode "function encode(str) {return encodeURIComponent(str);}" Dim encoded As String encoded = ScriptEngine.Run("encode", str) encodeURL = encoded End Function
添加Microsoft脚本控件作为参考,您就完成了.
与上一篇文章相同,只需完成功能..works!
通过htmlfile
ActiveX再一个解决方案:
Function EncodeUriComponent(strText) Static objHtmlfile As Object If objHtmlfile Is Nothing Then Set objHtmlfile = CreateObject("htmlfile") objHtmlfile.parentWindow.execScript "function encode(s) {return encodeURIComponent(s)}", "jscript" End If EncodeUriComponent = objHtmlfile.parentWindow.encode(strText) End Function
将htmlfile
DOM文档对象声明为静态变量时,由于init而第一次调用时只会产生很小的延迟,并且对于多次调用都会使此函数非常快,例如对于我来说,它会在2秒内将100个字符串的字符串转换为100000次.