How to write to a "Google Spreadsheet" from Excel 2003 VBA - vba

I Have an Excel 2003 file with a line similar to this:
I need to click "the button" and it adds that line as the last one on a Google Spreadsheet
Similar to:
Is it possible?
Should I use the command-line Google tools?
Is there a better way? Easier way?
How would you do it?
(once I know how to add "stuff" from VBA to Google Docs, how the f do i add it to the last line?)
More info: I have an Excel 2003 "program" that saves all of the company's sales (with the customer info), and I'd like do make a global address book that's easily updated by my (non it) co-workers.

You don't need OAuth or the spreadsheet API. Google Spreadsheet allows data entry with a simple form, which means also that a HTTP POST will do the trick. You just need to prepare your spreadsheet to accept data entries via a form as follows:
Login to your Google Docs account
Create a spreadsheet or open an existing one
Click on Tools / Create a form
Add anything in the form description just to enable the Save button
Save the form
Copy the formkey value displayed in the link at the bottom of the form creation page
Now you can issue a simple post into the spreadsheet without OAuth
You can test the entry now with curl if you have it on your system (replace the formkey placeholder with the formkey from your table):
curl.exe -v -k "http://spreadsheets.google.com/formResponse?formkey=<formkey>" -d "entry.0.single=test&entry.1.single=test2&pageNumber=0&backupCache=&submit=Submit"
Next we try to execute the form POST from our Excel sheet via the following code. Add a reference to "Microsoft XML, v3.0" before. Replace column1 with your desired values.
Dim httpRequest as XMLHTTP
Set httpRequest = New XMLHTTP
httpRequest.Open "POST", "http://spreadsheets.google.com/formResponse?formkey=<formkey>&ifq", False
httpRequest.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
httpRequest.Send "entry.0.single=" + column1 + "&entry.1.single=" + column2 + "&pageNumber=0&backupCache&submit=Submit"
'Check result in the following vars
httpRequest.status
httpRequest.statusText
Hope that helps

I had started answering your question, but realized that it was much less trivial than I thought it was when I started playing with the OAuth 2.0 API. I think it would be a lot easier if you could make your Google spreadsheet public, but I doubt that is advisable with sales data.
The reason this is non-trivial is the authentication part. The ASP OAuth below is probably usable with some work, but I noticed it uses Session variables and some other ASP objects, so you'd have to do a lot of tweaking.
In that light, here is my original answer, if it helps.
There is a google spreadsheet API:
https://developers.google.com/google-apps/spreadsheets/#adding_a_list_row
The OAuth 2.0 link that the spreadsheet docs refer to is out-of-date. You can play with the OAuth requests here, which should help you get started.
API functions are called by GET/POST requests with XML, which you can call using the XMLHTTP object.
First, reference Microsoft XML in your Excel project (Tools->References->Microsoft XML, v6.0)
In your VBA, you essentially use the following to send XML requests:
Dim x as MSXML2.XMLHTTP
Set x = New MSXML2.XMLHTTP
x.Open "POST", "http://example.com/", False
x.Send "<xmldata></xmldata>"
You should be able to adapt this OAuth 2.0 ASP library for your VBA code.
This is an ASP example of how to use that OAuth library; again since both the ASP and the VBA are using the VBScript syntax, it could probably be adapted.

I spent the last couple of days trying to find a good easy solution to this problem.
None seemed to work for me so I had to utilize bits and pieces from various posts I found on-line.
Steps to follow:
Create a Google spreadsheet
Create a form (under “Tools” – “Create a form”) with a three fields (you can add fields later after testing)
Go back to the Google spreadsheet and it should have created a new sheet (called "Form Responses") with headings matching the field names given when setting up the form.
Column A will automatically have as a heading “Timestamp” with your field names as headings for columns B, C & D etc.
Now click on “Form” – “Go to Live Form”
Write-click and “Inspect” (Ctrl-Shift-I) and click on Network
Enter some data (anything) for each of the respective fields and click on “Submit”
Click on “Headers” Click on “formResponse”.
Under “General” copy the url of the form. Note a “?” is required at the end of the url.
Also under headers find “Form Data”. This will be used in MyURL
Look for the entry.123456789 for each of the fields.
You will need these numbers for each field.
Replace xxxxxxxx in your code with your form's respective numbers.
Open up your Excel spreadsheet and copy in the sub-routine shown below
In the VBA editor click on Tools – References select the Microsoft XML.v3.0, (Microsoft XML Core Services)
Code:
Sub Write_Info_To_Google()
Dim ScriptEngine
Dim http As Object
Dim myURL As String
Set http = CreateObject("MSXML2.ServerXMLHTTP")
Set ScriptEngine = CreateObject("MSScriptControl.ScriptControl")
ScriptEngine.Language = "JScript"
ScriptEngine.AddCode "function encode(str) {return encodeURIComponent(str);}"
myURL = "https://docs.google.com/forms/d/e/ . . . . /formResponse?" & _
"entry.xxxxxxxxx=" + Cells(2, 1).Text + _
"&entry.yyyyyyyyy=" + Cells(2, 2).Text + _
"&entry.zzzzzzzzz=" + Cells(2, 3).Text
http.Open "GET", myURL, False
http.setRequestHeader "User-Agent", "Google Chrome 70.03538.102 (compatible; MSIE _
6.0; Windows NT 5.0)"
http.send
End Sub
Run this macro and watch your data from row 2 appear in the Google spreadsheet

Rather than use VBA in Excel, use a full fledged VB.NET application with the Excel Interop COM package. It's syntax is largely similar to the VBA commands, but to do the transferring to Google docs will be much easier in VB.NET.
Use the Google Documents List API to create a new spreadsheet.
Use the Google Spreadsheets API to move the data into your online spreadsheet.
Both Google APIs are REST APIs, so you'll have to use HttpRequest objects in VB.NET. Here is a great example of how to use them, just change the URLs so they are appropriate for Google. Google Spreadsheets even offers a library that abstracts away many of those steps.

Related

How to insert spreadsheet (ODS or XLSX) to text document (ODT or DOCX) via api

I have a text document (ODT or DOCX) and a spreadsheet (ODS or XLSX). I use LibreOffice API (in Java) to open this document.
I want to insert a spreadsheet into text document as embedded object. I can do it manually (via GUI LibreOffice Writer - menu Insert\Object\OLE Object), but I need this via API.
P.S. Official documentation for LibreOffice (OpenOffice) API is very poor. In this very interesting article http://fivedots.coe.psu.ac.th/~ad/jlop/ this information is not found.
The following Basic code is given at https://ask.libreoffice.org/en/question/76781/create-macro-to-insert-and-link-a-ole-spreadsheet/:
Sub oleexample
oDoc = ThisComponent
txt=oDoc.getText
obj = oDoc.createInstance("com.sun.star.text.TextEmbeddedObject")
obj.CLSID = "47BBB4CB-CE4C-4E80-a591-42d9ae74950f"
obj.attach(ThisComponent.currentController().Selection.getByIndex(0))
oXEO = obj.ExtendedControlOverEmbeddedObject
oXEO.doVerb(0)
End Sub
There is also an example at https://forum.openoffice.org/en/forum/viewtopic.php?f=45&t=14342 that embeds a Math object.

URL redirection automation in UFT/Selenium

A URL of a webpage is being changed to a new URL.There are 200 such old URLs that have changed to new URLs.
Test scenario :1.200 old URls with their corresponding new URLs are present in two different columns in an Excel sheet.When an old URL is entered in the address bar,it will be directed to the new URL in the browser.
Can the above test be automated via Selenium or UFT for 200 URLs?
You can do it more easily and much quicker by using Java HttpURLConnection class unless you are forced in a solution with Selenium\QTP
Open up the connection with the old link with the openConnection() method of URL class. Check for the response from getResponseCode() method. If response is not in 300 series then you have a problem. If response is in 300 series you have correct behaviour and check the redirected URL from the Location header.
Have a look at this link which will make things easier - https://www.mkyong.com/java/java-httpurlconnection-follow-redirect-example/
You have to do the Exact same way in QTP. But i have a doubt.
i.e. If you have new URLs the nwhy u will enter old urls in Browser addressBar ?
anyway u can look at the following
as u have said in Excel file old & new URL are mentioned Adjacent cells.
Then you might either use Following things to read excel file.
1) Create Excel.Application object
or
2) Use DataTabe to import Excel Sheet
or
3) U can use Excel as ADODB connection
now just read the old URL from that Excel file & take value from the New url column cells & store it in a Varriable(let say : strNewURL).
Then you can do this & use FOR loop
set IE= CreateObject("InternetExplorer.Application)
IE.Visible = True
'For loop here
' [intsomecount] is variabel which is teh no of times loops gonna iterate, in This case the Number of URL mentioned
For iterator=0 to intsomecount step 1
IE.Navigate strNewURL
wait 3
Next
lemme know if you concerns. :)

SSRS Scheduled Subscription hyperlinks not working

I am Currently using Reporting Services 2014. I am using the following code to be able to use a javascript pop-up window on the sharepoint site itself. The code also addresses the export to Excel link through an iif statement that
evaluates whether the RenderFormat is being viewed on the site or if it is another format (Excel, Word, PDF etc). The iif statement uses a variable that replaces the ReportServerURL with the appropriate site. Everything works fine in when using the links on the site and when exporting to Excel from the site.
The problem occurs when I set up a scheduled subscription which sends an Excel file of the report. The ReportSerURL is different form the above situations. We have two sites that use http://gsp1/ReportServer and http://gsp2/ReportServer in the scheduled subscription excel file.
This is the code that I am currently using for using hyperlinks on the site and Export to Excel from the site. Is there a way that I can also incorporate some logic to address the scheduled subscription files?
SSRS URL Action (Uses Variable below)
=iif(
(Globals!RenderFormat.Name = "RPL"),
"javascript:void(window.open('"+ Variables!RxDrill.Value + "&rv:ParamMode=Hidden&rv:Toolbar=None&rv:HeaderArea=None&rp:StoreKey=" + Fields!StoreKey.Value.ToString + " &rp:RxNumber=" + Fields!RX.Value.ToString + "&rp:RefillNumber=" + Fields!RefillNumber.Value.ToString + "', 'RXOVERVIEW','width=1335,height=450,location=no'))",
Variables!RxDrill.Value + "&rp%3aStoreKey=" & Fields!StoreKey.Value & "&rp%3aRxNumber=" & Fields!RX.Value & "&rp%3aRefillNumber=" & Fields!RefillNumber.Value & "&rs%3aParameterLanguage=")
Variable
=Replace(Globals!ReportServerUrl,"/_vti_bin","/_layouts/15") + "/RSViewerPage.aspx?rv:RelativeReportUrl=/SSRS%20Library/Rx Transaction Detail.rdl"
This is the error I currently get when trying to open a link in a subscription excel email file.
I dropped a [&ReportServerUrl] textbox and found that the path is not the same in the scheduled subscription as it is in the browser or during export to excel. I have found that there are 2 possible ReportServerURLs that the subscription uses. http://gsp1/ReportServer or http://gsp2/ReportServer. In the Browser it is always https://abc.myinfocenter.net/_vti_bin/ReportServer, but as you can see from the variable code above the _vti_bin is replaced.
It appears that the problem lies in the fact that when you load the report via sharepoint, you are retrieving the sharepoint server information using the Globals!ReportServerUrl value. However, with the subscription on a different SSRS server, you're retrieving a different server value: the server generating the subscription. SharePoint knows what server it's on and can tell SSRS that when you access the report via the SharePoint site. However, when you're generating the report on the SSRS server directly, the SSRS server has no idea the SharePoint site even exists.
To solve this, then, you will need to tell the SSRS server the URL for the SharePoint site. You could hard-code the SharePoint URL into an expression for the variable or elsewhere, but then that's a little harder to maintain. I would recommend solving this problem in the following way that makes maintenance a bit easier and more transparent:
Create a new parameter in your report called SharePointURL. Set the default value to https://abc.myinfocenter.net/_vti_bin/ReportServer or whatever it is when the report generates correctly in the browser. The reason you're doing this as a parameter is so that it's easier to maintain should your SharePoint site change. Set this parameter to be hidden or internal.
Change the expression for your variable to incorporate the SharePointURL parameter.
New Variable Expression:
=Replace(IIF(Globals!RenderFormat.Name = "RPL",Globals!ReportServerUrl,Parameters!SharePointURL.Value),"/_vti_bin","/_layouts/15") + "/RSViewerPage.aspx?rv:RelativeReportUrl=/SSRS%20Library/Rx Transaction Detail.rdl"
Hopefully that will fix your issue.

document.customdocumentproperties not being saved

I have searched high and low on stackexchange and other sites (vbaexpress, MSDN, etc...). There is extensive dialog around this, I have tried most of the examples, and still nothing is working.
Scenario:
User clicks 'Create Report' button in Access.
vba creates a new instance of a Word doc from the default template associated with a SharePoint library.
The Word template is formatted with tables and bookmarks to accept data, AND already has a number of custom property fields stored (NULL at this time)
vba pulls data from tables (tables are linked to SharePoint lists) and populates the entire Memo.
the code then saves the new document to the SP library (same one with the template) and checks it in.
All of this works fine.
The vba also includes the code to store both built-in and the custom properties:
example of the code:
Set objWord = CreateObject("Word.Application")
Set objDoc = objWord.Documents.Add(tName)
objWord.Visible = True
objDoc.BuiltinDocumentProperties("Title") = "2040"
With objDoc.CustomDocumentProperties
.Add name:="DocLevel", _
LinkToContent:=False, _
Type:=msoPropertyTypeString, _
Value:="Confidential"
.Add name:="UserDiscipline", _
LinkToContent:=False, _
Type:=msoPropertyTypeString, _
Value:="Broker"
End With
objDoc.SaveAs (fPath)
objDoc.CheckIn
Also, assuming that the properties are already objects in the template, I tried this just setting without the .Add:
objDoc.CustomDocumentProperties name:="DocLevel", LinkToContent:=False, _
Type:=msoPropertyTypeString, Value:="Confidential"
Everything works - EXCEPT - the custom doc properties are not saved. Even the built ones are saved - but not the custom ones.
I have the MS Office 14.0 Object Library, 14.0 Access library and VB for extensibility included. Is there some other reference that I need?
Thanks in advance to the Overflow community for any help...
And The answer is....
There is a completely different method available for this: ContentTypeProperties!
'customdocumentproperties' are properties of the Word document. Since this was an attempt to supply custom content to the SharePoint library, a different method was required:
doc.ContentTypeProperties("UserDiscipline").Value = "Broker"
Posting this so hopefully others here won't have to redo this same research.
I have come across the similar issue in Word using VSTO: the custom document properties are there before you close Word but they cannot be saved. I tried to use ContentTypeProperties instead as user3662334 suggested however I cannot access ContentTypeProperties at all due to the following exception "This document must contain Content Type properties. Content Type properties are a common requirement for files in a document management system."
The solution I have found is extremely simple: you just need to update the document content slightly (e.g. add a space in the end of the text) and save the document:
document.Content.Text += " ";
document.Save();

How can I connect to Lotus thru ODBC using VBA?

I'm interested in setting up an Access db to run a report automatically. To save myself the trouble of going to each client computer and setting up the appropriate DSNs, I'd like to set up the ODBC connections in the VB script itself if possible.
I've googled and checked this site and found some good starter code, but not enough to make all the error messages go away. Can someone complete the code below?
Sub SetupODBC(Str_Server as string, Str_Db as string)
'Str_Server=Name of Server
'Str_db=Name of Database
Dim C as ADODB.Connection
Set C = new ADODB.Connection
C.ConnectionString = ??
C.Open
Debug.print C.State
Exit Sub
Welcome to the board. ConnectionStrings is indeed your friend, but the issue you are having is that you don't have the driver:) Lotus Notes is not a relational database it is a document oriented database. Historically there has not been a way to Access it like it is a relational database for that reason. However IBM eventually got around to writing a sort of translator in the form of NotesSQL. If you follow the link and get the driver you should be able to use ODBC. It is worth noting that Notes exposes itself to COM. So if push comes to shove you can automate the client.
This site is your friend: http://www.connectionstrings.com/access
I didn't follow your question correctly at first. I see you want to create a link from Access to Lotus to report on Lotus Notes data. Well there are a few ways to do so.
I frequently use a method of exposing Lotus Notes data as XML, then accessing that XML from the remote system. You can easily create a Notes Page with the XML start tag, root element, and then insert an embedded view in between the root element. That embedded view then needs to display as HTML and contain columns that resolve to xml tags. For instance, each row of the view would look similar to this:
<Person><FirstName>Ken</FirstName><LastName>Pespisa</LastName></Person>
and your column formulas would be:
"<Person><FirstName>" + FirstName + "</FirstName>"
for the first name column, and for the last name column it would be this:
"<LastName> + LastName + </LastName></Person>"
Note that this assumes that your Notes server has the HTTP service turned on and you can reach the database via a browser.
However as mentioned by other answers, you can use other methods such as NotesSQL and COM. It sounds like you are putting this solution on many workstations, though, and NotesSQL would require you to install the driver on each workstation. The COM method would work without requiring any extra work at the users' desks so I'd favor that solution in this case.
Looks like a great site for my needs, even if it hasn't been updated in a year. But still no cigar. Now, I'm getting "Data source name not found and default driver not specified"
(Obviously, ServerNameGoesHere and DatabaseNameGoesHere are subsitutions)
Sub dbX()
Dim C As adodb.Connection
Set C = New adodb.Connection
C.Open _
"Driver={Lotus NotesSQL 3.01 (32-bit) ODBC DRIVER (*.nsf)};" & _
" Server=ServerNameGoesHere;" & _
" Database=DatabaseNameGoesHere.nsf;"
C.Close
End Sub