Closed Sophist-UK closed 8 years ago
I had previously used a Dictionary
for headers, querystring params, and cookies, but I changed them to Collection
since there can by multiple values for the same key.
a[]=1&a[]=2 => a = [1,2]
(although VBA-Web doesn't do this processing) (see https://github.com/VBA-tools/VBA-Web/issues/68).While I recognize creating a Dictionary
for the key-value is more intensive than an array, I felt like the tradeoff for readability and not having to mess with array indices was worth it.
Based on these issues, I think the best approach (for VBA-Web 5) would be to treat them as array of values for a single key:
' Cache-Control: no-cache
' Cache-Control: no-store
Response.Headers("Cache-Control") = Array("no-cache", "no-store")
' a[]=1&a[]=2
Request.AddQuerystringParam "a", Array(1, 2)
' Set-cookie: a=1&path=/;Path=/;Version=1
' Set-cookie: a=2&path=/example;Path=/example;Version=1
Response.Cookies("a") = Array("1&path=/", "2&path=/")
This would require a good bit of work in ParseUrlEncoded
/ConvertToUrlEncoded
(encoding arrays and objects are a contentious subject) and the various Request
and Response
methods and I don't think it's a good idea to jump to this approach at this time, but I'll keep it mind for the next major release.
Hmm - in my own code I was trying to store a user defined type in a collection (which worked) and retrieve it - which gave a compile error (about coercing a variant (type stored in a collection) to a UDT). You can use an object just fine (like the current saving a Dict to a Collection), but not a UDT. Something to bear in mind.
Yep, definitely tried that. I have also run into the issue of not being able to use UDT in class functions (as parameters/return values) repeatedly, a very frustrating limitation of VBA.
Tim - I was wondering whether you could enlighten me as to why CreateKeyValue exists.
From reading the code, CreateKeyValue seems to create a Dictionary object with a single entry, and this is then stored in a Collection. But surely you could just use a Dictionary rather than a Collection to store in, and just add it. Creating and destroying objects is a relatively costly process in VBA - so one of the following alternative approaches would seem to me to potentially perform better:
a. Use a Dictionary to store the item - i.e. instead of
you use
Note: This seems far cleaner, though would be likely to create backwards compatibility issues - or you would need to code to handle both collections of Key/Value Dictionaries and pure Dictionaries.
b. Use a Variant Array store the Key/Value Pair - i.e. instead of
you use
Likely to be more compatible.
Just to give an idea, I ran a quick performance test using the following code:
and the results were
So Option a. is c. 24 times faster. Switching Dictionary (VBA-Dict) to Scripting.Dictionary in the above code is a bit faster still - c. 30 times faster. I have tried a few variants to eliminate e.g. calling webhelpers, and it definitely seems to be the object creation which is the killer.
I should also add that a few seconds after running this - Outlook hangs for several seconds - presumably as it does garbage collection for all the Dictionary objects which have been freed.