![](/img/trans.png)
[英]Is there a simple way to parse comma separated Key:Value pairs in Excel, Power Query or VBA if the values contain unescaped commas?
[英]EXCEL - VBA . Getting the cell values as Key Value Pairs
我正在嘗試從“I”列的 excel 單元格中獲取地址值,並使用 VBA 將其作為查詢字符串傳遞給 URL。 在 excel 中嵌入了“Microsoft 對象瀏覽器”以加載頁面。
這甚至可能嗎? 因為我擔心作為查詢字符串傳遞的數據量太高(大約 1000 行)。
但是代碼不起作用,有什么辦法可以通過將查詢字符串作為數組傳遞來做同樣的事情嗎?
我還需要 VBA 語法來解析字典值。
我是 VBA 的新手。 請幫忙。
Dim Arr() As Variant ' declare an unallocated array.
Arr = Range("I:I") ' Arr is now an allocated array
Set dict = CreateObject("Scripting.Dictionary")
Dim iRow As Integer
iRow = 1
Dim parms As Variant
Dim rg As Range
For Each rg In Sheet1.Range("I:I")
' Print address of cells that are negative
'MsgBox (rg.Value)
'result = result & rg.Value
dict.Add rg.Value
iRow = (iRow + 1)
Next
MsgBox (dict.Item(1))
Set dict = Nothing
'WebBrowser1.Navigate2 "http://localhost/excelmaps/maps.php?adr=" & parms
End Sub
有很多事情要發生,所以我將嘗試解決字典部分,因為那是您標記的內容。
首先使用字典,您可以按如下方式添加項目:
dict(“your key”) = “your value”
我看到您已正確設置字典,並且始終確保在運行代碼之前在 VBA 編輯器中添加字典引用(轉到工具-> 引用-> Microsoft 腳本運行時) 。
在這種情況下,您的鍵值看起來像是增量整數。 那么為什么不直接使用數組,如下面的代碼所示?
另一個問題是循環一整列(全部 > 100 萬行)會產生溢出錯誤。 也許開始手動指定要在 for 循環中循環的行(請參閱“rowsToLoop”變量):
Sub der()
Dim rowsToLoop As Integer
rowsToLoop = 1000
Dim Arr() As Variant 'define empty array
ReDim Arr(rowsToLoop) 'redefine with variable length
Dim dict As Dictionary
Set dict = CreateObject("Scripting.Dictionary")
Dim x As Integer
For x = 1 To rowsToLoop
'With an array
Arr(x - 1) = Sheet1.Range("I1").Cells(x, 1).Value 'note array index starts at 0
'With a dictionary
dict(x - 1) = Sheet1.Range("I1").Cells(x, 1).Value
Next x
MsgBox "This is from array: " & Arr(1)
MsgBox "This is from dictionary: " & dict(1)
End Sub
似乎 IE 的最大 URL 長度是 2083 個字符:
https://support.microsoft.com/en-us/kb/208427
要構建查詢,我將使用字符串構建器(“System.Text.StringBuilder”)。 您還需要對所有參數進行 URL 編碼。
這是一個使用范圍 [A1:B10] 中的名稱/值構建 url 的示例:
Sub BuildURL
' Read the names/values from a sheet
Dim names_values()
names_values = [A1:B10].Value2
' Create a string builder
Dim sb As Object
Set sb = CreateObject("System.Text.StringBuilder")
sb.Append_3 "http://localhost/excelmaps/maps.php"
' Build the query
Dim i&, name$, value$
For i = 1 To UBound(names_values)
name = names_values(i, 1)
value = names_values(i, 2)
If i = 1 Then sb.Append_3 ("?") Else sb.Append_3 ("&")
sb.Append_3 URLEncode(name) ' Adds the name
sb.Append_3 "="
sb.Append_3 URLEncode(value) ' Adds the value
Next
' Print the result
Debug.Print sb.ToString()
End Sub
Public Function URLEncode(url As String, Optional space_to_plus As Boolean) As String
Static ToHex(15), IsLiteral%(127), buffer() As Byte, bufferCapacity&
Dim urlBytes() As Byte, bufferLength&, i&, u&, b&, space&
If space_to_plus Then space = 32 Else space = -1
If bufferCapacity = 0 Then GoSub InitializeOnce
urlBytes = url
For i = 0 To UBound(urlBytes) Step 2
If bufferLength >= bufferCapacity Then GoSub IncreaseBuffer
u = urlBytes(i) + urlBytes(i + 1) * 256&
If u And -128 Then ' U+0080 to U+1FFFFF '
If u And -2048 Then ' U+0800 to U+1FFFFF '
If (u And 64512) - 55296 Then ' U+0800 to U+FFFF '
b = 224 + (u \ 4096): GoSub WriteByte
b = 128 + (u \ 64 And 63&): GoSub WriteByte
b = 128 + (u And 63&): GoSub WriteByte
Else ' surrogate U+10000 to U+1FFFFF '
i = i + 2
u = ((urlBytes(i) + urlBytes(i + 1) * 256&) And 1023&) _
+ &H10000 + (u And 1023&) * 1024&
b = 240 + (u \ 262144): GoSub WriteByte
b = 128 + (u \ 4096 And 63&): GoSub WriteByte
b = 128 + (u \ 64 And 63&): GoSub WriteByte
b = 128 + (u And 63&): GoSub WriteByte
End If
Else ' U+0080 to U+07FF '
b = 192 + (u \ 64): GoSub WriteByte
b = 128 + (u And 63&): GoSub WriteByte
End If
ElseIf IsLiteral(u) Then ' unreserved ascii character '
buffer(bufferLength) = u
bufferLength = bufferLength + 2
ElseIf u - space Then ' reserved ascii character '
b = u: GoSub WriteByte
Else ' space character '
buffer(bufferLength) = 43 ' convert space to + '
bufferLength = bufferLength + 2
End If
Next
URLEncode = LeftB$(buffer, bufferLength)
Exit Function
WriteByte:
buffer(bufferLength) = 37 '%
buffer(bufferLength + 2) = ToHex(b \ 16)
buffer(bufferLength + 4) = ToHex(b And 15&)
bufferLength = bufferLength + 6
Return
IncreaseBuffer:
bufferCapacity = UBound(buffer) * 2
ReDim Preserve buffer(bufferCapacity + 25)
Return
InitializeOnce:
bufferCapacity = 2048
ReDim buffer(bufferCapacity + 25)
For i = 0 To 9: ToHex(i) = CByte(48 + i): Next '[0-9]'
For i = 10 To 15: ToHex(i) = CByte(55 + i): Next '[A-F]'
For i = 48 To 57: IsLiteral(i) = True: Next '[0-9]'
For i = 65 To 90: IsLiteral(i) = True: Next '[A-Z]'
For i = 97 To 122: IsLiteral(i) = True: Next '[a-z]'
IsLiteral(45) = True ' - '
IsLiteral(46) = True ' . '
IsLiteral(95) = True ' _ '
IsLiteral(126) = True ' ~ '
Return
End Function
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.