vba-tools / vba-web Goto Github PK
View Code? Open in Web Editor NEWVBA-Web: Connect VBA, Excel, Access, and Office for Windows and Mac to web services and the web
Home Page: http://vba-tools.github.io/VBA-Web/
License: MIT License
VBA-Web: Connect VBA, Excel, Access, and Office for Windows and Mac to web services and the web
Home Page: http://vba-tools.github.io/VBA-Web/
License: MIT License
From traffic on Excel-REST / VBA-Web, the following SO questions reference Excel-REST and need to be updated for VBA-Web:
This has been a great help. Unfortunately i am running into a compatibility issue on Mac OS due to the instantiation of the ActiveX Control MSXML2.ServerXMLHTTP.6.0.
Is there an alternative that is available that would be cross-platform?
The received JSON contained "Amount":14.6000000000, which was correctly parsed and given to CDbl for conversion. But it threw the mentioned error. I see a problem in usage of CDbl for converting the string to double because it's locale-dependent (my locale has ',' as decimal separator, which is of course nonsence to use in JSON). Using the Val for conversion solves this issue.
Hi,
I am trying to add multiple QueryStringParam through AddQueryStringParam
, this all works great unless I start adding params with the same Key
. When adding multiple params with the same Key
it only adds the latest one. I assume this is because AddQueryStringParam
uses a dictionary and only unique Keys
are allowed?
I have no problem editing the code but I was wondering if somebody reported this already or if you are adding it to 4.0?
Eg. Assume I send a GET request where I want to filter and only pull three fields, the current server I use accepts the following:
'Specify unique item
Request.AddQuerystringParam "Number", "123"
Request.AddQuerystringParam "Name", "Test Name"
'Specify which columns to pull
Request.AddQuerystringParam "Field", "Number"
Request.AddQuerystringParam "Field", "Name"
Request.AddQuerystringParam "Field", "OriginalAmount"
`Output should be something like:
`url/products?Number=123&Name=Test+Name&Field=Number&Field=Name&Field=OriginalAmount
`Output is:
`url/products?Number=123&Name=Test+Name&Field=OriginalAmount
BTW, again great REST script - very excited for 4.0.
Thanks!
From http://oauth.net/core/1.0/#anchor14 the signature base string has very specific formatting for the request url and request parameters. This improper formatting caused issues with accessing the LinkedIn API.
Test against https://developer.linkedin.com/oauth-test-console
Todo:
Resource
) with request parameters (including cachebreaker)When encountering a json array of objects (ex [{key1:value, key2:value}, {key1:value, key2:value}]). The parser returns a collection of just the key values. This is due to the json_ParseArray function not checking for { before passing int json_ParseValue. I believe this could be resolved with a change to the json_ParseArray function (changes comment marked):
Private Function json_ParseArray(json_String As String, ByRef json_Index As Long, Optional json_ConvertLargeNumbersToString As Boolean = True) As Collection
Set json_ParseArray = New Collection
Dim json_Object As Dictionary 'New object for Dictionary handling
json_SkipSpaces json_String, json_Index
If VBA.Mid$(json_String, json_Index, 1) <> "[" Then
Err.Raise 10001, "JSONConverter", json_ParseErrorMessage(json_String, json_Index, "Expecting '['")
Else
json_Index = json_Index + 1
Do
json_SkipSpaces json_String, json_Index
If VBA.Mid$(json_String, json_Index, 1) = "]" Then
json_Index = json_Index + 1
Exit Function
ElseIf VBA.Mid$(json_String, json_Index, 1) = "," Then
json_Index = json_Index + 1
json_SkipSpaces json_String, json_Index
End If
'This check to see if the value is the start of an object
If VBA.Mid$(json_String, json_Index, 1) = "{" Then
Set json_Object = json_ParseObject(json_String, json_Index, json_ConvertLargeNumbersToString)
json_ParseArray.Add json_Object
Else
json_ParseArray.Add json_ParseValue(json_String, json_Index, json_ConvertLargeNumbersToString)
End If
Loop
End If
End Function
In my Company a Proxy configuration script is set for IE.
At Home I use standard Internet with my Router.
The Example to get Google Directions is working fine at home, but when I'm in the Company I get a timeout, because the Code did not use the Windows / IE default proxy configuration.
This also cause me some issue to track the traffic with Fiddler.
As Fiddler is hooking in the proxy configuration, I asume Excel-REST is bypassing this with a direct internet connection only which doesn't work in my company environement.
(Should be the last step before releasing v4.0.0)
Need to verify that VBA-Web is taking the right steps to be safe-by-default, but allows for adjusting security settings (e.g. self-signed certificates, #73)
Action items:
WinHttpRequest
(not available in cURL)WinHttpRequest
(disabled by default in cURL)Insecure
option for turning off SSL certificate validationHi Tim,
Outstanding job on VBA-Web! I love the simplicity as I use it to connect to web services on our internal software systems.
One suggestion is to remove the Application.OnTime
dependency on Microsoft Excel. This works great in Excel, but not in other VBA-enabled applications like Microsoft Access.
As an alternative, I set up an additional class to utilize the Windows API for timer execution. I took advantage of a class (found here http://www.vbforums.com/showthread.php?527281-VB6-SelfTimer-class-module-2008-06-15) that even works without a wrapper in a standard module.
Using the timer class is a piece of cake. Just declare it withevents
in WebAsyncWrapper and use the event to trigger the timeout functions.
Private WithEvents pTimer As SelfTimer ' API timer class
Private Sub pTimer_Timer(ByVal Seconds As Currency)
Call TimedOut
End Sub
This allows you to completely avoid the complexity of handling the returned timers in the standard module, and trying to sort the callbacks out to their calling instances.
Keep up the great work! I am really excited about this project, and will be using it extensively in the months ahead.
Hi Tim,
One of our web services had a very large response field (>1MB), which took several minutes to parse because of the way strings are reallocated when concatenated. I googled around and found an implementation of cStringBuilder.cls for JSONLib, and have merged the StringBuilder usage and some related JSONLib fixes into RestHelper.bas.
This JSONLib fixes and StringBuilder class came from http://code.google.com/p/vba-json/issues/detail?id=13.
I think StringBuilder initially came from http://www.vbaccelerator.com/home/VB/Code/Techniques/StringBuilder/article.asp,
and some fixes came from http://www.ediy.co.nz/vbjson-json-parser-library-in-vb6-xidc55680.html.
Is there a way to send you the updated RestHelpers.bas and cStringBuilder.cls without doing a Git fork and pull request?
Dean Wiles
Hi Tim,
Great project. I am building a client to a rest-server for sqlite database tables on it.
Just in case, I shall release my (poor) VBA soon along where the server is:
https://github.com/dkottow/g6-server
My "issue" was that I wanted empty cells to be mapped to nulls. To do that, I change the following in Module RestHelpers - maybe you agree..:
Private Function json_toString(ByRef Obj As Variant) As String
Select Case VarType(Obj)
Case vbNull
json_toString = "null"
Case vbEmpty
'dkottow check if the cell is empty to evtl. convert to null
If IsEmpty(Obj) Then
json_toString = "null"
Else
json_toString = """"""
End If
Greetings, Daniel.
Hi,
Seems that "Private web_pAsyncRequests As Dictionary" is raising a compilation error on my MAC (module WebHelper).
any clue ?
Regards,
Running a large number of POST request from an Excel Sheet, and after around 3000 calls are encountering the above error.
I'm wondering if this is an out-of-memory error. Looking at the code, it seems possible that the Http object created in prepareHttpRequest is never garbage collected (not sure this is the right term to use in the MS/VBA world?). Maybe an explicit "Set Http = Nothing" is required in the Execute method?
Is it possible to use digest authentication (if so, how?) and pass in cookies?
Hi Tim,
I really apreciate your effort in keeping Excel-Rest up-to-date.
Hope that my issue is a simple one.
I use a Web-Service returning a JSON String, but for performance it is GZIP encoded.
So I add a Header:
Request.AddHeader "Accept-Encoding", "gzip, deflate"
This works fine, so I get an gzip encoded response.
Now Im searching for a way how to decode this before it is handed over to the parser.
Regards
Stephan
Thanks Tim!
Is it possible to run these classes without Microsoft Scripting runtime ?
I understand that the dependency is only for Scripting.Dictionary. So, providing a standalone Dictionary implementation is what I was thinking and removing dependency on Scripting.runtime.
I am trying to use Dictionary implementation as below - http://sysmod.wordpress.com/2011/11/24/dictionary-vba-class-update/
but currently running into following error -
"Private Object modules can not be used in public object modules as parameters or return types for public procedures, as public data members, or as public user defined types"
Is there any support for passing in an array of urls to GetJSON so you can get multiple resources with one get request?
No issue, just wanted to say a big THANKS!
Wanted to produce some stats on my email usage and turned to CouchDB to hold the data as it uses a nice, simple REST interface & is lightweight for running on a single PC.
But trying to sort out JSON string issues AND PUT/POST, etc. was a pain.
It took me no time at all to get your "Excel" modules into Outlook and it works a dream. I push data from sent/recieved/changed emails to CouchDB with a simple web interface for viewing the stats showing me I'm averaging 70-110 incoming and around 20-30 outgoing emails per working day!
Next stage is a work management tool that lets me tag emails quickly pushing some details to CouchDB for a simple To Do type display with links back into the Outlook email items.
Couldn't do all of that without your help as there wouldn't be time - thanks again.
J.
Hi Tim,
Thanks for this great work.
I wanted to ask a question.
I made it work in Windows easily but for Mac OS I had the Dictionary problem. I downloaded the Dictionary implementation of yours but this time I am getting:
"Run-time error '429'
ActiveX component can't create object
error in Mac. In Windows everything is fine.
Any solutions/suggestions?
Regards,
Koray
Hi,
Im using the Excel-REST for quite a while with former JSON responses. Unfortunately the Web-Service was changed to deliver .bplist responses due to performance and traffic volume.
Is there a way to also support bplist as format for the Response ?
I found a Windows Plist editor, which helps to browse and check the Response.
http://www.icopybot.com/plist-editor.htm
the get samples were very helpful but I am having issues processing a post request. I assume having a sample in hand would make things easier
Hi!
I try to put data with the help of AddBodyString to my request and the server isn't able to process it since the content-length is missing...
Am I supposed to use "AddParameter" with: "Content-Length" after having done "AddBodyString " or am I missing something different?
Thanks for the help!
Sebastian
Public Enum WebStatusCode
is part of "WebHelpers" and "RestHelpers".
Originally reported with issue #22, seems that importing classes in Excel 2010/2013 64-bit is improperly treating them as modules and leaving behind header information that causes errors.
I was able to manually change all those Integers to Longs, but I have see API call, where Integers are passed. Dunno how it work then.
Maybe there better timer that will take Long type as param?
Thanks Tim! This code is awesome and I was able to easily use it from Microsoft Access. We needed to enhance an old Access 2003 app to use a REST-based web service. In case anyone else needs to use Excel-REST from Access, here are the few tweaks I did:
Thanks again for sharing Excel-REST!
Dean.
Attempting to access service with self-signed certificates throws the following: "The certificate authority is invalid or incorrect."
Will look into bypassing certificate checking in WinHttpRequest and cURL. If it's possible, default will remain checking the certificate with option added to override.
While adding LogDebug
was helpful for logging what is happening inside Excel-REST, it can be a little noisy for understanding what was sent with a request and received with the response.
Example:
' In WebClient.cls
Public Function Execute(Request As WebRequest) As WebResponse
On Error GoTo ErrorHandling
' An unknown error occurs or Err.Raise is used
ErrorHandling:
' Cleanup Execute
' Rethrow
Err.Raise Err.Number, "WebClient.Execute", "An error occurred: ..."
End Function
' -> Error should be: "An error occurred: ..."
' but it's generic: "Method 'Execute' of object 'WebClient' failed"
Easy to get in trouble with url segments currently (discovered while testing #89)
Hi,
thanks for the nice work with this project; I have only played a little with it, but it seems really nice and useful. I have some trouble, though, extracting a json result.
I have something like
Dim client as new RestClient
Dim req As New RestRequest
req.BaseUrl = ...
req.resource = ...
req.Format = json
req.Method = httpGET
Dim resp As RestResponse: Set resp = client.Execute(req)
From the Immidiate window:
Debug.Print resp.Content
{
"coef" : [
0.34,
-0.33,
0.08
],
"sigma2" : [
0.95
]
}
But resp.Data
is a collection with Item(1) = "coef"
and Item(2) = "sigma2"
, rather than a dictionary with the parsed results.
Am I missing something obvious?
When I open the "VBA-Web - Blank.xlsm" file, I am getting an error
Compile error:
The code in this project must be updated for use on 64-bit systems. Please review and update Declare statements and then mark them with the PtrSafe attribute.
It's specifically highlighting this line, and the "Function" word:
Private Declare Function utc_GetTimeZoneInformation Lib "kernel32" Alias "GetTimeZoneInformation" _
I am running this on Windows 10, Excel version 15.0.4675.1000
Thanks! Looking forward to working with this, seems very useful!
Ran into this issue with an API that needed form-urlencoded
for the request but json
for the response
Normalize method signatures and input/output types and add HMAC-SHA256
Headers have already been set when authenticator is called so adding/changing headers has no effect
Fairly new to github, so not sure if I should put this here.
The rest example for GetDirection in the readme doesn't work. I get an automation error. The JSON one works fine. What I don't see in the Rest example is the base URL set anywhere
It'd be awesome if you could provide an example of how to authenticate to the Google Analytics API, I've been trying to get it to work by modifying the example for Google Maps but without success.
Are you able to take a look?
Function GAClient() As RestClient
Set GAClient = New RestClient
' Set the base url for the service
'
' All requests will be appended to the base url
' e.g.
' BaseUrl = https://api.service.com/
' RequestA -> https://api.service.com/RequestA
' RequestB -> https://api.service.com/RequestB
'
GAClient.BaseUrl = "https://www.googleapis.com/auth/analytics.readonly"
End Function
Function MetricsRequest(ID As String, First As String, Last As String, Metrics As String) As RestRequest
Set MetricsRequest = New RestRequest
MetricsRequest.Resource = "metrics/{format}"
' Set the request format (Set {format} segment, content-types, and parse the response)
MetricsRequest.Format = json
' Replace any {...} url segments
' e.g. Resource = "resource/{id}"
' Request.AddUrlSegment("id", 123) -> "resource/123"
' Add parameters to the request (querystring for GET calls and body for everything else)
MetricsRequest.AddParameter "ids", ID
MetricsRequest.AddParameter "start-date", First
MetricsRequest.AddParameter "end-date", Last
MetricsRequest.AddParameter "metrics", Metrics
' (or force as querystring)
' (GET, POST, PUT, DELETE, PATCH)
MetricsRequest.Method = httpGET
' => GET https://maps.googleapis.com/maps/api/directions/json?origin=...&destination=...&sensor=false
End Function
Sub GetMetrics()
' Execute the request asynchonously and process later
GAClient.ExecuteAsync DirectionsRequest(""), "ProcessDirections"
End Sub
Public Sub ProcessMetrics(Response As RestResponse)
If Response.StatusCode = Ok Then
Dim Route As Dictionary
Set Route = Response.Data("routes")(1)("legs")(1)
Debug.Print "Visits " & Route("ga:visits")("text") & _
" to Bounces: " & Route("ga:bounces")("text")
End If
End Sub
Debugging what's not working by looking at variables in VBA editor in debug mode is not useful.
I'm unable to get this to compile on Office 2010 x64 or Office 2013 x64. Anybody else having this issue?
Hi,
I want to consume a service that runs on Windows authentication using Excel-REST. Is there a way to generate the authorization token using windows user ID and send it with the request to the REST service?
I found a defect in the HTTPAuthenticator
On OS X the password should be escaped to deal with special characters to bash. For example, I had a "!" in my password with failed the call. In the WebAuthenticator_PrepareCurl
method, I replaced:
Curl = Curl & " --basic --user " & Me.Username & ":" & Me.Password
with
Curl = Curl & " --basic --user " & Me.Username & ":" & Replace(Me.Password, "!", "\!")
Excerpt from recent request for assistance:
A couple of examples I am looking at to work with:
http://forceadventure.wordpress.com/2013/01/31/creating-a-custom-rest-api-in-salesforce/
This one provides the code on the SF end to serialize a SF standard object, say, the 'Account' object and provide it back to the requester. So assuming I set that up correctly, I 'just' need to set up the Excel-REST connector to be able to (1) authenticate with SF and (2) make that request/get that response!http://wiki.developerforce.com/page/Getting_Started_with_the_Force.com_REST_API
This is the standard documentation SF provides on a similar example.If you could provide an example of just how to send/retrieve a single standard object to/from SF, that would help immensely! I think this functionality is pretty generic and wouldn't be specific to your job but is generalizable to everybody who's looking for Excel<->SF integration. Right now I'm getting hung up on a basic step - what exactly should I be setting the 'callback url' in configuring the remote access screen (since I'm not creating a server application with Excel - there is no client-side callback url)
When I'm trying to re-use the same WebRequest for multiple subsequent API calls. It fails with error.
I discovered that the Sub Prepare() duplicates headers every time Client.Execute() is called.
I fixed it by modifying the Prepare() with code to update the header [key,value] in case the key is already present.
Tim,
Thanks for writing Excel-Rest, I am finding it great.
I have run into an issue, I hope you can point me in the right direction.
I want to set a parameter that is an integer, but
postRequest.AddParameter "myInteger", myInteger
gives a ByRef type compile error, since postRequest is expecting strings as parameters.
If I pass myInteger as a string the web service says it cant convert test to number.
I see you have an example of
postRequest.AddParameter "myInteger", 20
This compiles for me also (dont understand how this can work, but I have stopped asking "why" questions of Microsoft) but obviously a hard coded value is only useful in some cases.
Can you advise how to set a non string parameter?
Hi Tim,
Thank you for this awesome project !
I wanted to share the solution I found in order to automatically configure proxies in WebClient 4.0 (WinHTTP)
This allows me to do something like this:
Dim APIClient as new WebClient
APIClient.BaseURL = "http://api.somewhere.net/"
autoProxy APIClient
The APIClient object receives automatically the appropriate proxy for the base URL.
This works by retrieving IE settings, including auto-detect and auto-config scripts, then performing a WPAD search for the Base URL.
A broken JSON string is sent to Client when request body is populated with JSON dictionary containing a Double.
This happens when windows locale has , as decimal separator.
Throws the following (non-obvious) error:
-2147024713 (800700b7): Cannot create a file when that file already exists.
Resolve with addition of SetHeader
(add/replace) alternative to AddHeader
(add only)
Thinking of using your tool as soap request client. Do you have any feature request in the pipeline. I am planning to modify the RestClient to incorporate the soap calls - do you have any suggestions on the proposed approach.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.