Gibt es eine integrierte Möglichkeit, eine Zeichenfolge in Excel VBA per URL zu codieren, oder muss ich diese Funktionalität manuell ausführen?
76
Nein, nichts eingebaut ( bis Excel 2013 - siehe diese Antwort ).
URLEncode()
Diese Antwort enthält drei Versionen von .
Eine Variante, die die UTF-8-Codierung unterstützt und auf der basiert ADODB.Stream
(Verweis auf eine aktuelle Version der Bibliothek "Microsoft ActiveX Data Objects" in Ihrem Projekt):
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
Diese Funktion wurde auf freevbcode.com gefunden :
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
Ich habe einen kleinen Fehler behoben, der dort drin war.
Ich würde eine effizientere (~ 2 × so schnelle) Version der oben genannten verwenden:
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
Beachten Sie, dass keine dieser beiden Funktionen die UTF-8-Codierung unterstützt.
ADODB.Stream
Objekt verwenden, das die erforderliche Zeichenfolgenkonvertierung durchführen kann. Beispiele für die Herstellung von UTF-8 mit VBA oder VBScript finden Sie im Internet.Um dies auf den neuesten Stand zu bringen, gibt es seit Excel 2013 eine integrierte Methode zum Codieren von URLs mithilfe der Arbeitsblattfunktion
ENCODEURL
.Um es in Ihrem VBA-Code zu verwenden, müssen Sie nur anrufen
Dokumentation
quelle
Application.WorksheetFunction.EncodeUrl(myString)
funktionierte perfekt für meine Bedürfnisse - hoffentlich wird diese Antwort genug positiv bewertet, um die vorherige, mega-alte Version zuVersion des oben genannten unterstützenden UTF8:
Private Const CP_UTF8 = 65001 #If VBA7 Then Private Declare PtrSafe Function WideCharToMultiByte Lib "kernel32" ( _ ByVal CodePage As Long, _ ByVal dwFlags As Long, _ ByVal lpWideCharStr As LongPtr, _ ByVal cchWideChar As Long, _ ByVal lpMultiByteStr As LongPtr, _ ByVal cbMultiByte As Long, _ ByVal lpDefaultChar As Long, _ ByVal lpUsedDefaultChar As Long _ ) As Long #Else 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 cbMultiByte As Long, _ ByVal lpDefaultChar As Long, _ ByVal lpUsedDefaultChar As Long _ ) As Long #End If Public Function UTF16To8(ByVal UTF16 As String) As String Dim sBuffer As String Dim lLength As Long If UTF16 <> "" Then #If VBA7 Then lLength = WideCharToMultiByte(CP_UTF8, 0, CLngPtr(StrPtr(UTF16)), -1, 0, 0, 0, 0) #Else lLength = WideCharToMultiByte(CP_UTF8, 0, StrPtr(UTF16), -1, 0, 0, 0, 0) #End If sBuffer = Space$(lLength) #If VBA7 Then lLength = WideCharToMultiByte(CP_UTF8, 0, CLngPtr(StrPtr(UTF16)), -1, CLngPtr(StrPtr(sBuffer)), LenB(sBuffer), 0, 0) #Else lLength = WideCharToMultiByte(CP_UTF8, 0, StrPtr(UTF16), -1, StrPtr(sBuffer), LenB(sBuffer), 0, 0) #End If 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
Genießen!
quelle
VBA7
Header mitPtrSafe
undLongPtr
.Obwohl dieser sehr alt ist. Ich habe eine Lösung gefunden, die auf dieser Antwort basiert :
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")
Fügen Sie Microsoft Script Control als Referenz hinzu und Sie sind fertig.
Nur eine Randnotiz: Aufgrund des JS-Teils ist dies vollständig UTF-8-kompatibel. VB konvertiert korrekt von UTF-16 nach UTF-8.
quelle
htmlfile
ActiveX und umgehen Sie das Problem, damit ScriptControl mit Excel x64 funktioniert .Ähnlich wie der Code von Michael-O, nur ohne Referenz (späte Bindung) und mit weniger einer Zeile.
* Ich habe gelesen, dass es in Excel 2013 einfacher geht: 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
quelle
htmlfile
ActiveX und umgehen Sie das Problem, damit ScriptControl mit Excel x64 funktioniert .Verwenden Sie seit Office 2013 diese eingebaute Funktion hier .
Wenn vor dem Amt 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
Fügen Sie Microsoft Script Control als Referenz hinzu und Sie sind fertig.
Gleich wie im letzten Beitrag nur komplette Funktion ..works!
quelle
htmlfile
ActiveX und umgehen Sie das Problem, damit ScriptControl mit Excel x64 funktioniert .Eine weitere Lösung über
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
Das Deklarieren des
htmlfile
DOM-Dokumentobjekts als statische Variable gibt die einzige kleine Verzögerung beim ersten Aufruf aufgrund von init und macht diese Funktion für zahlreiche Aufrufe sehr schnell, z. B. konvertiert sie für mich die Zeichenfolge mit einer Länge von 100 Zeichen 100000 Mal in ca. 2 Sekunden.quelle
Static
kann für den gleichen Zweck auch mit früher Bindung verwendet werden.(Auf einen alten Faden stoßen). Hier ist eine Version, die Zeiger verwendet, um die Ergebniszeichenfolge zusammenzusetzen. Es ist ungefähr 2x - 4x so schnell wie die schnellere zweite Version in der akzeptierten Antwort.
Public Declare PtrSafe Sub Mem_Copy Lib "kernel32" _ Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long) Public Declare PtrSafe Sub Mem_Read2 Lib "msvbvm60" _ Alias "GetMem2" (ByRef Source As Any, ByRef Destination As Any) Public Function URLEncodePart(ByRef RawURL As String) As String Dim pChar As LongPtr, iChar As Integer, i As Long Dim strHex As String, pHex As LongPtr Dim strOut As String, pOut As LongPtr Dim pOutStart As LongPtr, pLo As LongPtr, pHi As LongPtr Dim lngLength As Long Dim cpyLength As Long Dim iStart As Long pChar = StrPtr(RawURL) If pChar = 0 Then Exit Function lngLength = Len(RawURL) strOut = Space(lngLength * 3) pOut = StrPtr(strOut) pOutStart = pOut strHex = "0123456789ABCDEF" pHex = StrPtr(strHex) iStart = 1 For i = 1 To lngLength Mem_Read2 ByVal pChar, iChar Select Case iChar Case 97 To 122, 65 To 90, 48 To 57, 45, 46, 95, 126 ' Ok Case Else If iStart < i Then cpyLength = (i - iStart) * 2 Mem_Copy ByVal pOut, ByVal pChar - cpyLength, cpyLength pOut = pOut + cpyLength End If pHi = pHex + ((iChar And &HF0) / 8) pLo = pHex + 2 * (iChar And &HF) Mem_Read2 37, ByVal pOut Mem_Read2 ByVal pHi, ByVal pOut + 2 Mem_Read2 ByVal pLo, ByVal pOut + 4 pOut = pOut + 6 iStart = i + 1 End Select pChar = pChar + 2 Next If iStart <= lngLength Then cpyLength = (lngLength - iStart + 1) * 2 Mem_Copy ByVal pOut, ByVal pChar - cpyLength, cpyLength pOut = pOut + cpyLength End If URLEncodePart = Left$(strOut, (pOut - pOutStart) / 2) End Function
quelle
Gleich wie
WorksheetFunction.EncodeUrl
bei der UTF-8-Unterstützung:Public Function EncodeURL(url As String) As String Dim buffer As String, i As Long, c As Long, n As Long buffer = String$(Len(url) * 12, "%") For i = 1 To Len(url) c = AscW(Mid$(url, i, 1)) And 65535 Select Case c Case 48 To 57, 65 To 90, 97 To 122, 45, 46, 95 ' Unescaped 0-9A-Za-z-._ ' n = n + 1 Mid$(buffer, n) = ChrW(c) Case Is <= 127 ' Escaped UTF-8 1 bytes U+0000 to U+007F ' n = n + 3 Mid$(buffer, n - 1) = Right$(Hex$(256 + c), 2) Case Is <= 2047 ' Escaped UTF-8 2 bytes U+0080 to U+07FF ' n = n + 6 Mid$(buffer, n - 4) = Hex$(192 + (c \ 64)) Mid$(buffer, n - 1) = Hex$(128 + (c Mod 64)) Case 55296 To 57343 ' Escaped UTF-8 4 bytes U+010000 to U+10FFFF ' i = i + 1 c = 65536 + (c Mod 1024) * 1024 + (AscW(Mid$(url, i, 1)) And 1023) n = n + 12 Mid$(buffer, n - 10) = Hex$(240 + (c \ 262144)) Mid$(buffer, n - 7) = Hex$(128 + ((c \ 4096) Mod 64)) Mid$(buffer, n - 4) = Hex$(128 + ((c \ 64) Mod 64)) Mid$(buffer, n - 1) = Hex$(128 + (c Mod 64)) Case Else ' Escaped UTF-8 3 bytes U+0800 to U+FFFF ' n = n + 9 Mid$(buffer, n - 7) = Hex$(224 + (c \ 4096)) Mid$(buffer, n - 4) = Hex$(128 + ((c \ 64) Mod 64)) Mid$(buffer, n - 1) = Hex$(128 + (c Mod 64)) End Select Next EncodeURL = Left$(buffer, n) End Function
quelle
Der Code der akzeptierten Antwort wurde aufgrund eines Unicode-Fehlers in Access 2013 gestoppt. Daher habe ich eine Funktion für mich mit hoher Lesbarkeit geschrieben, die laut Davis Peixoto RFC 3986 folgen und in verschiedenen Umgebungen nur minimale Probleme verursachen sollte.
Hinweis: Das Prozentzeichen selbst muss zuerst ersetzt werden, da sonst alle zuvor codierten Zeichen doppelt codiert werden. Das Ersetzen von Speicherplatz durch + wurde hinzugefügt, um nicht RFC 3986 zu entsprechen, sondern um Links bereitzustellen, die aufgrund der Formatierung nicht beschädigt werden. Es ist 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
quelle
Wenn Sie möchten, dass es auch auf MacOs funktioniert, erstellen Sie eine separate Funktion
Function macUriEncode(value As String) As String Dim script As String script = "do shell script " & """/usr/bin/python -c 'import sys, urllib; print urllib.quote(sys.argv[1])' """ & Chr(38) & " quoted form of """ & value & """" macUriEncode = MacScript(script) End Function
quelle
Ich hatte Probleme beim Codieren von kyrillischen Buchstaben in URF-8.
Ich habe eines der oben genannten Skripte so geändert, dass es mit der Karte der kyrillischen Zeichen übereinstimmt. Impliziert ist der kyrrile Abschnitt von
https://en.wikipedia.org/wiki/UTF-8 und http://www.utf8-chartable.de/unicode-utf8-table.pl?start=1024
Die Entwicklung anderer Abschnitte ist ein Beispiel und muss mit realen Daten überprüft und die Char-Map-Offsets berechnet werden
Hier ist das Skript:
Public Function UTF8Encode( _ StringToEncode As String, _ Optional UsePlusRatherThanHexForSpace As Boolean = False _ ) As String Dim TempAns As String Dim TempChr As Long Dim CurChr As Long Dim Offset As Long Dim TempHex As String Dim CharToEncode As Long Dim TempAnsShort As String CurChr = 1 Do Until CurChr - 1 = Len(StringToEncode) CharToEncode = Asc(Mid(StringToEncode, CurChr, 1)) ' http://www.utf8-chartable.de/unicode-utf8-table.pl?start=1024 ' as per https://en.wikipedia.org/wiki/UTF-8 specification the engoding is as follows Select Case CharToEncode ' 7 U+0000 U+007F 1 0xxxxxxx 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 0 To &H7F TempAns = TempAns + "%" + Hex(CharToEncode And &H7F) Case &H80 To &H7FF ' 11 U+0080 U+07FF 2 110xxxxx 10xxxxxx ' The magic is in offset calculation... there are different offsets between UTF-8 and Windows character maps ' offset 192 = &HC0 = 1100 0000 b added to start of UTF-8 cyrillic char map at &H410 CharToEncode = CharToEncode - 192 + &H410 TempAnsShort = "%" & Right("0" & Hex((CharToEncode And &H3F) Or &H80), 2) TempAnsShort = "%" & Right("0" & Hex(((CharToEncode \ &H40) And &H1F) Or &HC0), 2) & TempAnsShort TempAns = TempAns + TempAnsShort '' debug and development version '' CharToEncode = CharToEncode - 192 + &H410 '' TempChr = (CharToEncode And &H3F) Or &H80 '' TempHex = Hex(TempChr) '' TempAnsShort = "%" & Right("0" & TempHex, 2) '' TempChr = ((CharToEncode And &H7C0) / &H40) Or &HC0 '' TempChr = ((CharToEncode \ &H40) And &H1F) Or &HC0 '' TempHex = Hex(TempChr) '' TempAnsShort = "%" & Right("0" & TempHex, 2) & TempAnsShort '' TempAns = TempAns + TempAnsShort Case &H800 To &HFFFF ' 16 U+0800 U+FFFF 3 1110xxxx 10xxxxxx 10xxxxxx ' not tested . Doesnot match Case condition... very strange MsgBox ("Char to encode matched U+0800 U+FFFF: " & CharToEncode & " = &H" & Hex(CharToEncode)) '' CharToEncode = CharToEncode - 192 + &H410 TempAnsShort = "%" & Right("0" & Hex((CharToEncode And &H3F) Or &H80), 2) TempAnsShort = "%" & Right("0" & Hex(((CharToEncode \ &H40) And &H3F) Or &H80), 2) & TempAnsShort TempAnsShort = "%" & Right("0" & Hex(((CharToEncode \ &H1000) And &HF) Or &HE0), 2) & TempAnsShort TempAns = TempAns + TempAnsShort Case &H10000 To &H1FFFFF ' 21 U+10000 U+1FFFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx '' MsgBox ("Char to encode matched &H10000 &H1FFFFF: " & CharToEncode & " = &H" & Hex(CharToEncode)) ' sample offset. tobe verified CharToEncode = CharToEncode - 192 + &H410 TempAnsShort = "%" & Right("0" & Hex((CharToEncode And &H3F) Or &H80), 2) TempAnsShort = "%" & Right("0" & Hex(((CharToEncode \ &H40) And &H3F) Or &H80), 2) & TempAnsShort TempAnsShort = "%" & Right("0" & Hex(((CharToEncode \ &H1000) And &H3F) Or &H80), 2) & TempAnsShort TempAnsShort = "%" & Right("0" & Hex(((CharToEncode \ &H40000) And &H7) Or &HF0), 2) & TempAnsShort TempAns = TempAns + TempAnsShort Case &H200000 To &H3FFFFFF ' 26 U+200000 U+3FFFFFF 5 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx '' MsgBox ("Char to encode matched U+200000 U+3FFFFFF: " & CharToEncode & " = &H" & Hex(CharToEncode)) ' sample offset. tobe verified CharToEncode = CharToEncode - 192 + &H410 TempAnsShort = "%" & Right("0" & Hex((CharToEncode And &H3F) Or &H80), 2) TempAnsShort = "%" & Right("0" & Hex(((CharToEncode \ &H40) And &H3F) Or &H80), 2) & TempAnsShort TempAnsShort = "%" & Right("0" & Hex(((CharToEncode \ &H1000) And &H3F) Or &H80), 2) & TempAnsShort TempAnsShort = "%" & Right("0" & Hex(((CharToEncode \ &H40000) And &H3F) Or &H80), 2) & TempAnsShort TempAnsShort = "%" & Right("0" & Hex(((CharToEncode \ &H1000000) And &H3) Or &HF8), 2) & TempAnsShort TempAns = TempAns + TempAnsShort Case &H4000000 To &H7FFFFFFF ' 31 U+4000000 U+7FFFFFFF 6 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx '' MsgBox ("Char to encode matched U+4000000 U+7FFFFFFF: " & CharToEncode & " = &H" & Hex(CharToEncode)) ' sample offset. tobe verified CharToEncode = CharToEncode - 192 + &H410 TempAnsShort = "%" & Right("0" & Hex((CharToEncode And &H3F) Or &H80), 2) TempAnsShort = "%" & Right("0" & Hex(((CharToEncode \ &H40) And &H3F) Or &H80), 2) & TempAnsShort TempAnsShort = "%" & Right("0" & Hex(((CharToEncode \ &H1000) And &H3F) Or &H80), 2) & TempAnsShort TempAnsShort = "%" & Right("0" & Hex(((CharToEncode \ &H40000) And &H3F) Or &H80), 2) & TempAnsShort TempAnsShort = "%" & Right("0" & Hex(((CharToEncode \ &H1000000) And &H3F) Or &H80), 2) & TempAnsShort TempAnsShort = "%" & Right("0" & Hex(((CharToEncode \ &H40000000) And &H1) Or &HFC), 2) & TempAnsShort TempAns = TempAns + TempAnsShort Case Else ' somethig else ' to be developped MsgBox ("Char to encode not matched: " & CharToEncode & " = &H" & Hex(CharToEncode)) End Select CurChr = CurChr + 1 Loop UTF8Encode = TempAns End Function
Viel Glück!
quelle
Dieses Snippet, das ich in meiner Anwendung zum Codieren der URL verwendet habe, kann Ihnen dabei helfen, dasselbe zu tun.
Function URLEncode(ByVal str As String) As String Dim intLen As Integer Dim x As Integer Dim curChar As Long Dim newStr As String intLen = Len(str) newStr = "" For x = 1 To intLen curChar = Asc(Mid$(str, x, 1)) If (curChar < 48 Or curChar > 57) And _ (curChar < 65 Or curChar > 90) And _ (curChar < 97 Or curChar > 122) Then newStr = newStr & "%" & Hex(curChar) Else newStr = newStr & Chr(curChar) End If Next x URLEncode = newStr End Function
quelle
Keine der Lösungen hier funktionierte sofort für mich, aber es lag höchstwahrscheinlich an meiner mangelnden Erfahrung mit VBA. Dies kann auch daran liegen, dass ich einige der oben genannten Funktionen einfach kopiert und eingefügt habe, ohne die Details zu kennen, die möglicherweise erforderlich sind, damit sie in einer VBA für Anwendungsumgebung funktionieren.
Meine Bedürfnisse waren einfach, xmlhttp-Anfragen mit URLs zu senden, die einige Sonderzeichen der norwegischen Sprache enthielten. Einige der oben genannten Lösungen codieren sogar Doppelpunkte, wodurch die URLs für das, was ich brauchte, ungeeignet waren.
Ich habe mich dann entschlossen, meine eigene URLEncode-Funktion zu schreiben. Es verwendet keine cleverere Programmierung wie die von @ndd und @Tom. Ich bin kein sehr erfahrener Programmierer, aber ich musste dies früher erledigen.
Ich stellte fest, dass das Problem darin bestand, dass mein Server keine UTF-16-Codierungen akzeptierte, sodass ich eine Funktion schreiben musste, die UTF-16 in UTF-8 konvertierte. Hier und hier wurde eine gute Informationsquelle gefunden .
Ich habe es nicht ausgiebig getestet, um zu überprüfen, ob es mit URLs mit Zeichen funktioniert, die höhere Unicode-Werte haben und mehr als 2 Byte utf-8-Zeichen erzeugen würden. Ich sage nicht, dass es alles dekodiert, was dekodiert werden muss (aber es ist einfach zu ändern, um Zeichen in die
select case
Anweisung aufzunehmen / auszuschließen ), noch dass es mit höheren Zeichen funktioniert, da ich nicht vollständig getestet habe. Aber ich teile den Code, weil er jemandem helfen könnte, der versucht, das Problem zu verstehen.Kommentare sind willkommen.
Public Function URL_Encode(ByVal st As String) As String Dim eachbyte() As Byte Dim i, j As Integer Dim encodeurl As String encodeurl = "" eachbyte() = StrConv(st, vbFromUnicode) For i = 0 To UBound(eachbyte) Select Case eachbyte(i) Case 0 Case 32 encodeurl = encodeurl & "%20" ' I am not encoding the lower parts, not necessary for me Case 1 To 127 encodeurl = encodeurl & Chr(eachbyte(i)) Case Else Dim myarr() As Byte myarr = utf16toutf8(eachbyte(i)) For j = LBound(myarr) To UBound(myarr) - 1 encodeurl = encodeurl & "%" & Hex(myarr(j)) Next j End Select Next i URL_Encode = encodeurl End Function Public Function utf16toutf8(ByVal thechars As Variant) As Variant Dim numbytes As Integer Dim byte1 As Byte Dim byte2 As Byte Dim byte3 As Byte Dim byte4 As Byte Dim byte5 As Byte Dim i As Integer Dim temp As Variant Dim stri As String byte1 = 0 byte2 = byte3 = byte4 = byte5 = 128 ' Test to see how many bytes the utf-8 char will need Select Case thechars Case 0 To 127 numbytes = 1 Case 128 To 2047 numbytes = 2 Case 2048 To 65535 numbytes = 3 Case 65536 To 2097152 numbytes = 4 Case Else numbytes = 5 End Select Dim returnbytes() As Byte ReDim returnbytes(numbytes) If numbytes = 1 Then returnbytes(0) = thechars GoTo finish End If ' prepare the first byte byte1 = 192 If numbytes > 2 Then For i = 3 To numbytes byte1 = byte1 / 2 byte1 = byte1 + 128 Next i End If temp = 0 stri = "" If numbytes = 5 Then temp = thechars And 63 byte5 = temp + 128 returnbytes(4) = byte5 thechars = thechars / 12 stri = byte5 End If If numbytes >= 4 Then temp = 0 temp = thechars And 63 byte4 = temp + 128 returnbytes(3) = byte4 thechars = thechars / 12 stri = byte4 & stri End If If numbytes >= 3 Then temp = 0 temp = thechars And 63 byte3 = temp + 128 returnbytes(2) = byte3 thechars = thechars / 12 stri = byte3 & stri End If If numbytes >= 2 Then temp = 0 temp = thechars And 63 byte2 = temp Or 128 returnbytes(1) = byte2 thechars = Int(thechars / (2 ^ 6)) stri = byte2 & stri End If byte1 = thechars Or byte1 returnbytes(0) = byte1 stri = byte1 & stri finish: utf16toutf8 = returnbytes() End Function
quelle
Die VBA-Tools-Bibliothek hat eine Funktion dafür:
http://vba-tools.github.io/VBA-Web/docs/#/WebHelpers/UrlEncode
Es scheint ähnlich wie
encodeURIComponent()
in JavaScript zu funktionieren .quelle