Sending Data from Excel to a Website - excel

I have been asked to make a Macro which sends the Excel Data to a Website. There should not be any database involved. I have been trying to use HTTP Post after reading examples on this website. I have made a ASP.NET webpage which runs on localserver. While debugging the macro, the control does reach the webpage Page_load event but I am unable to see the data there.
Can anybody help me find my mistake?
Excel Code:
Sub SendData()
'
' SendData Macro
'
Dim sdata As String
sdata = "Abhh"
'
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
URL = "localhost:2782/Default.aspx?"; + sdata
objHTTP.Open "POST", URL, False objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
objHTTP.send ("")
End Sub
C# Code
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
namespace Fetch
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = Request.Url.Query;
// I dont know where the data is in the Request object.(If it is there at all..)
}
}
}
Thanks
Abi

Does the 'website' have to be a standard webpage? Can you not send it to a 'website' running an ASP.NET WebService instead?
See here & here on how to write a webservice, and then read here & here on how to call the WebService via VBA.

Although I can't give you an exact example in Excel, I'm pretty certain Excel has a function or two to lookup values from any website using a GET request. The difference between a GET and POST request is that in the former all data passed is part of the URL string. Assuming the HTTP support in Excel is basic, I suspect you will have better luck using a GET request, carefully building your URL with the data with simple string manipulation. Although I do not know the exact syntax, imagine a formula in a cell like =lookuphtml("http://some.url.com/send?var1="&B2&"&var2="&B3), where cells B2 and B3 would contain your variable values (the values you want to pass to the script). This assumes the receiving end is capable of receiving data through GET requests (not only POST requests). Most decent server-side libraries allow data passed through both GET and POST request, although YMMV.

I'm not a .NET guy but it looks very much like URI.Query would only show the GET data because POST data isn't part of the URI.
You might want to look at using the standard form syntax of name1=value1&name2=value2&... in your sData string and then on the server use Request.Form as per the examples here

Related

VBA issues with sending SMS

I have a code for my Excel application. It generates a product invoice and every time the invoice generated it will send the current billed amount along with thanks message. I have purchased a bulk SMS account and they have provided me the API.
I am using the "ActiveWorkbook.FollowHyperlink" method to send SMS, but it is sending SMS 2 times. Can anyone tell me why this method sends sms 2 times??
I have written the following program:
Sub Macro1()
Dim murl As String
murl = "<< SMS API HERE >>"
ActiveWorkbook.FollowHyperlink Address:=murl
End Sub
Consider using a raw GET request to your API, here is an example using late-binding to send a GET request to a google page - the MsgBox line is simply showing the response from google and you can replace the google.co.uk URL with your own API URL.
Public Sub Send_GET()
Dim con As Object ' MSXML2.ServerXMLHTTP60
Set con = CreateObject("MSXML2.ServerXMLHTTP") ' New MSXML2.ServerXMLHTTP60
con.Open "GET", "https://www.google.co.uk", False
con.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
con.send
MsgBox con.responsetext
End Sub
I've used late binding but if you want to explore the proper objects and properties then add a reference to "Microsoft XML v6.0" in your VBA project and you can get rid of the Object and CreateObject parts - sending requests like this is SO USEFUL.
Don't forget to mark an answer as correct if it helps solve your problem.

Excel VBA MSXML2.XMLHTTP60 PUT request fail on "send" action

I'm creating an integration with Jira on Excel using VBA.
I'm able to login securely (using POST) and retrieve Jira issues (using GET) using Jira's API.
Now I'm trying to update issues, and the HTTP verb on Jira's API is GET. This shouldn't be a problem, but the fact is I can't even make the request.
Here's my current code - it's based on the POST code, but I'm not sure if I'm missing some other params.
I'm omitting some variable declarations - this is not the issue!
Public JiraService As New MSXML2.XMLHTTP60
JiraDataUrl = "https://atlassian.XXXXXXXX.com/jira/rest/api/2/issue/" & JiraId
body = "{""fields"" : {""customfield_13800"":""2011-10-03""}}"
Call JiraLogin(user, pass) 'This calls another Sub that log into Jira
JiraService.Open "PUT", JiraDataUrl, False
JiraService.setRequestHeader "Content-Type", "application/json"
JiraService.setRequestHeader "Accept", "application/json"
JiraService.setRequestHeader "X-Atlassian-Token:", "nocheck"
JiraService.send body
jsonText = JiraService.responseText
sStatus = JiraService.Status
When I run the script, it's interrupted by excel with the following messages:
I click on Debug and the JiraService.send body part is marked on the code
If I click on play, I get the final error (This method cannot be called after the send method has been called), that doesn't make any sense to me:
If I replace PUT for POST it runs normally, but Jira API returns with 405 HTTP error - as the method I'm trying to use requires a PUT.
Any idea on what am I doing wrong in this code?
I am doing the same thing right now, and I've figured out, that updating an issue requers async connection:
JiraService.Open "PUT", URL, True
In that case
JiraService.send data
will be succesful, but JiraService.status returns 1223! However, an issue field will be updated...
There is a discussion with the same "problem" with MSXML2.XMLHTTP60 and it seems, 1223 code is a kind of "success code":
https://social.msdn.microsoft.com/Forums/en-US/c4911cd8-caba-4c25-b71c-fe2e1a7ef8be/update-sharepoint-list-metadata-using-rest-from-vba-using-msxml2xmlhttp60

Excel Internet Explorer Automation Causes IE Environment to Crash

I've successfully automated a VBA Excel macro to iterate through a loop and hit a series of URL's to trigger a server-side script - this is simply done with:
myIE.Navigate ("http://someURL.php?VARIABLE=" & var_string)
where var_string is assigned within the loop as it iterates through. Before this, I've cleared cache, cookies and history with:
Shell "RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess #
I've tried many #'s including 8,2, 16 etc to see if any of these had an effect (and combination of #'s).
The issue I am having, is that although the entire script SOMETIMES works, if I were to run it a second time the line where I navigate to the URL fails to call the URL even though the domain/URL is fully live and functional. Any other URL I manually type into the IE window works just fine - just not the one I am calling inside the loop. IE is locking me out of that domain temporarily. If I come back to the script a few hours from last running it, it generally works.
Again the domain is functional and script is fine - I verify it all the time with another machine.
It's as if I am setting something environmentally and breaking Internet Explorer within VBA even though the script is absurdly simple.
I've tried CreateObject(), GetObject as well as InternetExplorerMedium for myIE object.
If all you need is to "touch" that URL for its side effects, you can as well use a XMLHTTP object. In VBA, go to menu Tools, then References and choose Microsoft XML, v6.0. Then:
Dim Request As New XMLHTTP
Request.open "GET", Url & "?VARIABLE=" & var_string, False
Request.send
' Check Request.status, probably for 200
Some notes:
You may want to use POST instead of GET, if you're having problems with caching
You should pass the data in the POST body, if the server can handle it
The value of var_string should be escaped, in this case, URL encoded
If you don't want to block waiting for responses, you can make requests asynchronously (True third argument to open)
Following these notes, here's a more elaborate example:
Dim Request As New XMLHTTP
Request.open "POST", Url, True
Dim Handler As New CXMLHTTPHandler
Handler.Initialize Request
Set Request.onreadystatechange = Handler
Request.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
Request.send UrlEncode("VARIABLE") & "=" & UrlEncode(var_string)
' This returns immediately, the check must now be done in the Handler
For the missing pieces, here's the code for CXMLHTTPHandler, which I actually found through stackoverflow, and a definition of UrlEncode at stackoverflow.
You should specialize CXMLHTTPHandler for your needs, probably even make it accept an AddressOf a procedure and call it in the actual default procedure. The default procedure should set the m_xmlHttp to Nothing when m_xmlHttp.readyState is 4.
EDIT 1: If your request code is in a loop, you need to break the Dim ... New statements in two, to ensure you're using fresh objects:
Dim Request As XMLHTTP
Set Request = New XMLHTTP
Request.open "POST", Url, True
Dim Handler As CXMLHTTPHandler
Set Handler = New CXMLHTTPHandler
Handler.Initialize Request
Set Request.onreadystatechange = Handler
Request.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
Request.send UrlEncode("VARIABLE") & "=" & UrlEncode(var_string)
' This returns immediately, the check must now be done in the Handler

Monotouch/iPhone - Call to HttpWebRequest.GetRequestStream() connects to server when HTTP Method is DELETE

My Scenario:
I am using Monotouch for iOS to create an iPhone app. I am calling ASP.NEt MVC 4 Web API based http services to login/log off. For Login, i use the POST webmethod and all's well. For Logoff, i am calling the Delete web method. I want to pass JSON data (serialized complex data) to the Delete call. If i pass simple data like a single string parameter as part of the URL itself, then all's well i.e. Delete does work! In order to pass the complex Json Data, here's my call (i have adjusted code to make it simple by showing just one parameter - UserName being sent via JSON):
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("http://localhost/module/api/session/");
req.ContentType = "application/json";
req.CookieContainer = jar;
req.Method = "Delete";
using (var streamWrite = new StreamWriter(req.GetRequestStream()))
{
string jSON = "{\"UserName\":\"" + "someone" + "\"}";
streamWrite.Write(jSON);
streamWrite.Close();
}
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
on the server, the Delete method looks has this definition:
public void Delete(Credentials user)
where Credentials is a complex type.
Now, here's the issue!
The above code, gets into the Delete method on the server as soon as it hits:
req.GetRequestStream()
And hence the parameter sent to the Delete method ends up being null
And here's the weird part:
If i use the exact same code using a test VS 2010 windows application, even the above code works...i.e it does not call Delete until req.GetResponse() is called! And in this scenario, the parameter to the Delete method is a valid object!
QUESTION
Any ideas or Is this a bug with Monotouch, if so, any workaround?
NOTE:
if i change the Delete definition to public void Delete(string userName)
and instead of json, if i pass the parameter as part of the url itself, all's well. But like i said this is just a simplified example to illustrate my issue. Any help is appreciated!!!
This seems to be ill-defined. See this question for more details: Is an entity body allowed for an HTTP DELETE request?
In general MonoTouch (based on Mono) will try to be feature/bug compatible with the Microsoft .NET framework to ease code portability between platforms.
IOW if MS.NET ignores the body of a DELETE method then so will MonoTouch. If the behaviour differs then a bug report should be filled at http://bugzilla.xamarin.com

HTTPS POST request using VBA for Excel

I use "WinHttp.WinHttpRequest.5.1" to send HTTP POST requests from VBA in Excel.
But I could not manage to do it for HTTPS, as I received an SSL certificate error.
What VBA code would you use to negotiate an SSL connection to a website from VBA in Excel ?
The WinHttpRequest object has a SetClientCertificate method. Try this code example taken from the MSDN (I tried to adapt it for VBA):
' Instantiate a WinHttpRequest object. '
Dim HttpReq as new ActiveXObject("WinHttp.WinHttpRequest.5.1")
' Open an HTTP connection. '
HttpReq.Open("GET", "https://www.test.com/", false)
' Select a client certificate. '
HttpReq.SetClientCertificate("LOCAL_MACHINE\Personal\My Certificate")
' Send the HTTP Request. '
HttpReq.Send()
While I have not used the COM component (WinHttpRequest), it seems you need a call to SetClientCertificate prior to calling send, as per the link.
Does that help?
I have the same situation (send a http request from a VBA in Excel); I created three objects:
Set HttpReq = CreateObject("WinHttp.WinHttpRequest.5.1")
-- for the http request class, and
Set fsobj = CreateObject("Scripting.FileSystemObject")
Set txtobj = fso.OpenTextFile("C:\PKCERT.PEM")
-- to get into a variable the certificate contents, to pass it to HttpReq.SetClientCertificate,
certificate_data = txtobj.ReadAll
HttpReq.SetClientCertificate (certificate_content)
So I can send the request including its public key certificate, as usual,
HttpReq.Send
P.S. I found a script at http://www.808.dk/?code-simplewinhttprequest -- it worked fine in my case, hope in yours too.

Resources