SSRS Scheduled Subscription hyperlinks not working - vba

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.

Related

Query timeout in embedded RDLC vb 2008

How does one increase the query timeout when using local reportviewer from the default of 30 seconds.
I am not using code to create the dataset. I went through wizard choosing connection and setting the report to use a stored procedure to fill adapter.
I don't have access to change ds.querytimeout setting.
This is a not using SSRS. the report is local and embedded.
call the report as such
ReportForm2.SpRetrieveReportIncentiveSummaryTableAdapter.Fill(ReportForm2.Prdatalyons728DataSet.spRetrieveReportIncentiveSummary, tStart.Text, tEnd.Text, areas, pickers, " ", "hh:mm:ss", 0, " ")
ReportForm2.ReportViewer1.RefreshReport()
I was able to add it like this
ReportForm.SpRetrieveReportIncentiveSummaryTableAdapter1.SetCommandTimeOut=
Set the timeout on the table adapter

ms access visual basic 2010 report does not order by

this one is the screenshot on the visual basic report. as you can see it starts at august then december then february but it i already group by it on the access which is this.
this is a query in the access im not sure if i did the right thing but i is already ordered by the earliest .
here is the sql code from the ms access
SELECT MonthName(Month([Date_sold])) & ' ' & Year([Date_sold]) AS Month_Sold, Sum(tblSell.Total_Price) AS Total_Earnings, Sum(tblSell.Quantity_Bought) AS Total_Medicine_Sold, tblSell.Generic_name, tblSell.Brand_Name
FROM tblSell
GROUP BY MonthName(Month([Date_sold])) & ' ' & Year([Date_sold]), tblSell.Generic_name, tblSell.Brand_Name, Year([Date_sold]), Month([Date_sold])
ORDER BY Year([Date_sold]), Month([Date_sold]);
in short is it doesnt order by on my report on the visual basic it should show february first like the one on ms access but it shows august which is different.
Order by, I believe, gets over written by the reports Order By property in the Data tab, on the property sheet. Either set it there or make sure it is empty. Then set the reports properties like this:
Me.OrderBy = "[SomeField], [AnotherField]"
Me.OrderByOn = True
EDIT:
All Microsoft products allow developers access to a development environment using a language called VBA (Visual Basic for Applications). You can use this language to write programs and macros to enhance products. Take a look here, although it's a bit old it may still be relevant: http://visualbasic.about.com/od/learnvba/l/aa030803b.htm
For you, you will need to add the code I suggested to the OnLoad event of the report. To do this:
Open Access.
Open your report in Design View.
On the left hand side, you should see a tab called Property Sheet
Select the Event Tab
in the OnLoad event, click the "..." (ellipsis) button
This will bring up the VBA code.
Add This:
Private Sub Report_Load()
Me.OrderBy = "[SomeField], [AnotherField]"
Me.OrderByOn = True
End Sub
Try that and see if it works.
The reason why is it not sorting (I am having this same problem at work doing some shipment order reports) is because the code is not reading the date. It will list them aplhabetically because it is a text field and not a short date. I just went to the parameters and was able to fix it there.

How to write to a "Google Spreadsheet" from Excel 2003 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.

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

Intermittent error when attempting to control another database

I have the following code:
Dim obj As New Access.Application
obj.OpenCurrentDatabase (CurrentProject.Path & "\Working.mdb")
obj.Run "Routine"
obj.CloseCurrentDatabase
Set obj = Nothing
The problem I'm experimenting is a pop-up that tells me Access can't set the focus on the other database. As you can see from the code, I want to run a Subroutine in another mdb. Any other way to achieve this will be appreciated.
I'm working with MS Access 2003.
This is an intermittent error. As this is production code that will be run only once a month, it's extremely difficult to reproduce, and I can't give you the exact text and number at this time. It is the second month this happened.
I suspect this may occur when someone is working with this or the other database.
The dataflow is to update all 'projects' once a month in one database and then make this information available in the other database.
Maybe, it's because of the first line in the 'Routines' code:
If vbNo = MsgBox("Do you want to update?", vbYesNo, "Update") Then
Exit Function
End If
I'll make another subroutine without the MsgBox.
I've been able to reproduce this behaviour. It happens when the focus has to shift to the called database, but the user sets the focus ([ALT]+[TAB]) on the first database. The 'solution' was to educate the user.
This is an intermittent error. As this is production code that will be run only once a month, it's extremely difficult to reproduce, and I can't give you the exact text and number at this time. It is the second month this happened.
I suspect this may occur when someone is working with this or the other database.
The dataflow is to update all 'projects' once a month in one database and then make this information available in the other database.
Maybe, it's because of the first line in the 'Routines' code:
If vbNo = MsgBox("Do you want to update?", vbYesNo, "Update") Then
Exit Function
End If
I'll make another subroutine without the MsgBox.
I've tried this in our development database and it works. This doesn't mean anything as the other code also workes fine in development.
I guess this error message is linked to the state of one of your databases. You are using here Jet connections and Access objects, and you might not be able, for multiple reasons (multi-user environment, unability to delete LDB Lock file, etc), to properly close your active database and open another one. So, according to me, the solution is to forget the Jet engine and to use another connexion to update the data in the "other" database.
When you say "The dataflow is to update all 'projects' once a month in one database and then make this information available in the other database", I assume that the role of your "Routine" is to update some data, either via SQL instructions or equivalent recordset updates.
Why don't you try to make the corresponding updates by opening a connexion to your other database and (1) send the corresponding SQL instructions or (2) opening recordset and making requested updates?
One idea would be for example:
Dim cn as ADODB.connexion,
qr as string,
rs as ADODB.recordset
'qr can be "Update Table_Blablabla Set ... Where ...
'rs can be "SELECT * From Table_Blablabla INNER JOIN Table_Blobloblo
set cn = New ADODB.connexion
cn.open
You can here send any SQL instruction (with command object and execute method)
or open and update any recordset linked to your other database, then
cn.close
This can also be done via an ODBC connexion (and DAO.recordsets), so you can choose your favorite objects.
If you would like another means of running the function, try the following:
Dim obj As New Access.Application
obj.OpenCurrentDatabase (CurrentProject.Path & "\Working.mdb")
obj.DoCmd.RunMacro "MyMacro"
obj.CloseCurrentDatabase
Set obj = Nothing
Where 'MyMacro' has an action of 'RunCode' with the Function name you would prefer to execute in Working.mdb
I've been able to reproduce the error in 'development'.
"This action cannot be completed because the other application is busy. Choose 'Switch To' to activate ...."
I really can't see the rest of the message, as it is blinking very fast. I guess this error is due to 'switching' between the two databases. I hope that, by educating the user, this will stop.
Philippe, your answer is, of course, correct. I'd have chosen that path if I hadn't developed the 'routine' beforehand.
"I've been able to reproduce this behaviour. It happens when the focus has to shift to the called database, but the user sets the focus ([ALT]+[TAB]) on the first database. The 'solution' was to educate the user." As it is impossible to prevent the user to switch application in Windows, I'd like to close the subject.