{"id":46,"date":"2012-08-26T15:31:00","date_gmt":"2012-08-26T15:31:00","guid":{"rendered":"\/lisa\/post\/2012\/08\/26\/Equal-Opportunity-Web-Services-SSRS-as-a-client-as-well-as-a-server.aspx"},"modified":"2012-08-26T15:31:00","modified_gmt":"2012-08-26T15:31:00","slug":"equal-opportunity-web-services-ssrs-as-a-client-as-well-as-a-server","status":"publish","type":"post","link":"https:\/\/spacefold.com\/lisa\/2012\/08\/26\/equal-opportunity-web-services-ssrs-as-a-client-as-well-as-a-server\/","title":{"rendered":"Equal Opportunity Web Services: SSRS as a client as well as a server"},"content":{"rendered":"<p>Tom wrote with another question that has really important implications for anybody who uses SSRS.<\/p>\n<blockquote>\n<p>Do you know if it is possible to do interaction with SSRS?&nbsp; IOW, can I use a button (or a link) in an SSRS report which, when clicked, will post back to the server (for example, send some data to the server and save)?&nbsp; I assume it can&#8217;t, but I want to listen to your suggestions&#8230;.&nbsp;<\/p>\n<\/blockquote>\n<p>Well, it&#8217;s heartwarming that he&#8217;s willing to listen to suggestions and I hope he&#8217;s also willing to roll&nbsp;up his sleeves!&nbsp; The important parts of my answer are:<\/p>\n<ul>\n<li>It&#8217;s definitely&nbsp;possible to do this.&nbsp; I do it a lot (and I&#8217;ll show you an example here).<\/li>\n<li>There&#8217;s some important work to do to achieve this, but the important work is not really done in SSRS at all!<\/li>\n<\/ul>\n<p>To&nbsp;understand why, what, and how, you need to take a step back.<\/p>\n<h2>Web services methods of access: start with SSRS as an example server.<\/h2>\n<p>&nbsp;In various posts on this blog, I&#8217;ve shown you how to access Report Server using SOAP &#8212;&nbsp;<a title=\"blog post with SSRS SOAP example\" href=\"\/lisa\/2010\/01\/16\/Walkthrough-Part-II-Dynamic-Interactive-Paging-and-another-fierce-look-at-parameters\/\" target=\"_blank\" rel=\"noopener\">here&#8217;s a sample post<\/a> &#8212; and also using URL access, which most people would call RESTfull interfaces&nbsp;&#8212; numerous examples, <a title=\"blog post showing SSRS with URL Access\" href=\"\/lisa\/2010\/02\/07\/YAPS-on-Custom-Excel-for-RS-Drive-Subscriptions-with-a-Stick-Shift\/\" target=\"_blank\" rel=\"noopener\">here&#8217;s one calling SSRS with URL access from within SSIS<\/a>.&nbsp;<\/p>\n<p>Why do you suppose the Microsoft team supports two APIs?<\/p>\n<p>The answer should be obvious: different clients have different abilities and prefer different methods of access.&nbsp; If you support multiple methods, you support more clients.<\/p>\n<h2>SSRS is&nbsp;a &#8220;differently abled&#8221; web service client.<\/h2>\n<p>I would like to think that Microsoft would have done this on general principles and because the more widely you support clients, the more widely you&#8217;ll be used.&nbsp; It&#8217;s just good manners and good sense.&nbsp;<\/p>\n<p>But the truth is that Microsoft probably had an ulterior motive here.&nbsp; By internal inclination&nbsp;they would have supported only a SOAP API.&nbsp;<\/p>\n<p class=\"NB\" style=\"padding-left: 30px;\">I&#8217;m guessing about this, I have no inside information, but it&#8217;s pretty obvious given the extensiveness of their SOAP API that it was the darling of their hearts and URL Access is the red-headed stepchild.<\/p>\n<p>They tacked on URL access to their feature set because somebody probably asked &#8220;what if we want to call a report from another report?&#8221;&nbsp;<\/p>\n<p>&#8220;Hah&#8221;,&nbsp;MS said, &#8220;we&#8217;ve already thought of that. There&#8217;s an &#8216;action&#8217; option to go to another report.&#8221;&nbsp;<\/p>\n<p>But that same somebody probably perserved.&nbsp; &#8220;Not good enough!&nbsp; What if we want to call another report that&#8217;s on another report server?&nbsp; You&#8217;ve allowed us to put links on text with an action to &#8216;go to a URL&#8217;, and you&#8217;re rendering our reports in an HTML interface in Report Manager.&nbsp; We want to call Report Manager or Report Server&#8221; &#8212; most people at that stage didn&#8217;t even know the difference &#8212; &#8220;from inside another report!&nbsp; And it should be as flexible to do this as to call any other web site!&#8221;<\/p>\n<p>&#8220;Hah&#8221;, MS said, &#8220;no problem.&nbsp; Just look at the URL for the other report in your browser, capture it,&nbsp;and put that into the action.&#8221;<\/p>\n<p>But that same somebody probably stuck to his or her guns.&nbsp; &#8220;Not good enough!&nbsp; What about the parameters, and what about the other options such as rendering to another format?&#8221;<\/p>\n<h2><strong>OH. <\/strong><\/h2>\n<p>And finally MS&nbsp;understood what was needed.&nbsp;<\/p>\n<p>They added URL Access as a method of using Report Server&#8230;&nbsp; <strong>because&nbsp;RESTful interaction&nbsp;was the only type of interaction that SSRS Reports themselves would be&nbsp;able to support as a web service client.<\/strong><\/p>\n<h2>In a country of&nbsp;one-version APIs, the two-API&#8217;d server is king.<\/h2>\n<p>They really should have known from the start.<\/p>\n<p>It&#8217;s really obvious, and if you are a .NET developer rather than a SQL developer you should already know this:&nbsp; When you build a web service you should make it available from as many types of clients as you can.&nbsp;<\/p>\n<p>Now, back to Tom&#8217;s question.&nbsp;The work is really on the server side, not on SSRS&#8217;s as a client.&nbsp;&nbsp; To have interaction from an SSRS report, he needs to specify a web service somewhere capable of serving an SSRS client, which simply means a web service that supports some form of REST.<\/p>\n<p>If his company has any brains, they&#8217;ll make sure the same web service can serve other clients, which might prefer SOAP, too.&nbsp; It won&#8217;t cost any more to build for both at the same time.<\/p>\n<h2>Here&#8217;s how I handle it.<\/h2>\n<p>As I&#8217;ve probably mentioned a nauseating number of times, the district runs a huge number of SSRS reports, and a fair number of them have the potential to allow interaction (I&#8217;ll show you one, below).&nbsp; I don&#8217;t want to create a new methodology every time somebody suggests this requirement.<\/p>\n<p>To resolve requests as quickly as possible and as flexibly as possible, I built a small ASP.NET application whose sole purpose is to address the database; it only has one method that can be called, but that method has a bunch of rules, addressable as standard&nbsp;argument by the client, to determine what stored procedure, in what database, using what connection string, the web service method will call internally.&nbsp;<\/p>\n<p>The method also has a standard argument which allows the client to specify whether it wants to receive an XML result or whether an XSLT stored on the server in a known location &#8212; which can be specific to your report, if you like &#8212; should be applied before the client receives the result.&nbsp; Your xslt, in turn, has standard arguments it&#8217;s passed (such as siteRoot, for use in displaying images).<\/p>\n<p>A final standard argument allows you to specify whether you are looking for a full result set from the stored procedure, which is provided as an XML-serialized dataset, or a single result value.<\/p>\n<p>Now for the non-standard arguments.&nbsp; These are like the ones that represent your report&#8217;s parameters, when you use SSRS&#8217;s URL Access,&nbsp;as contrasted with the ones&nbsp;that tell ReportServer that you want a PDF rather than HTML, etc. &nbsp;In URL Access, you prefix the SSRS-standard parameters; in my system, you prefix&nbsp;the names of the custom parameters instead.&nbsp; In my system, these custom parameters are the arguments you want passed to the stored procedure you&#8217;ve requested. You use the original parameter names required by the sproc, prefixing them with a special, documented&nbsp;prefix.&nbsp; The method strips off this prefix when calling the named sproc, obviously, and passes your values along when it invokes the sproc.&nbsp;<\/p>\n<p class=\"NB\" style=\"padding-left: 30px;\">The web service method&nbsp;also error-handles appropriately and provides a consistent method of passing back the errors to the client, whether because the sproc you called doesn&#8217;t exist, your arguments for the sproc weren&#8217;t correct or the sproc threw some other error, or because the sproc in question has not been cleared for this type of access.&nbsp; If you supply a custom XSLT in this system, naturally, there are some additional conventions your XSLT can support so that it displays error messages in conformance with its general UI requirements.<\/p>\n<p>It sounds complicated, but it&#8217;s pretty simple to do, especially when looked at from the client&#8217;s&nbsp;side, in this case SSRS.&nbsp;&nbsp; Here&#8217;s how simple the XML version accepted by this service looks, appropriate to being sent by a SOAPy client:<\/p>\n<p class=\"code\"><span style=\"color: #0000ff;\">&lt;SISXRequest&gt;<br \/><\/span><span style=\"color: #0000ff;\">&nbsp;&nbsp; &lt;p<\/span><span style=\"color: #be3232;\"> n<\/span><span style=\"color: #0000ff;\">=&#8221;<\/span><span style=\"color: black; font-weight: bold;\">_sp<\/span><span style=\"color: #0000ff;\">&#8220;&gt;<span style=\"color: #ff0000;\">sp_<\/span><span style=\"color: #ff0000;\">xxx<\/span>&lt;\/p&gt;<br \/><\/span><span style=\"color: #0000ff;\">&nbsp;&nbsp; &lt;p<\/span><span style=\"color: #be3232;\"> n<\/span><span style=\"color: #0000ff;\">=&#8221;<\/span><span style=\"color: black; font-weight: bold;\">_cn<\/span><span style=\"color: #0000ff;\">&#8220;&gt;<span style=\"color: #ff0000;\">yyy<\/span>&lt;\/p&gt;<br \/><\/span><span style=\"color: #0000ff;\">&nbsp;&nbsp; &lt;p<\/span><span style=\"color: #be3232;\"> n<\/span><span style=\"color: #0000ff;\">=&#8221;<\/span><span style=\"color: black; font-weight: bold;\">_db<\/span><span style=\"color: #0000ff;\">&#8220;&gt;<span style=\"color: #ff0000;\">zzz<\/span>&lt;\/p&gt;<br \/><\/span><span style=\"color: #0000ff;\">&nbsp;&nbsp; &lt;p<\/span><span style=\"color: #be3232;\"> n<\/span><span style=\"color: #0000ff;\">=&#8221;<\/span><span style=\"color: black; font-weight: bold;\">_x<\/span><span style=\"color: #0000ff;\">&#8220;&gt;<span style=\"color: #ff0000;\">my.xslt<\/span>&lt;\/p&gt;<br \/><\/span><span style=\"color: #0000ff;\">&nbsp;&nbsp; &lt;p<\/span><span style=\"color: #be3232;\"> n<\/span><span style=\"color: #0000ff;\">=&#8221;<\/span><span style=\"color: black; font-weight: bold;\">_pLogin<\/span><span style=\"color: #0000ff;\">&#8220;&gt;<span style=\"color: #ff0000;\">aaa<\/span>&lt;\/p&gt;<br \/><\/span><span style=\"color: #0000ff;\">&nbsp;&nbsp; &lt;p<\/span><span style=\"color: #be3232;\"> n<\/span><span style=\"color: #0000ff;\">=&#8221;<\/span><span style=\"color: black; font-weight: bold;\">_pMyOtherParameter<\/span><span style=\"color: #0000ff;\">&#8220;&gt;<span style=\"color: #ff0000;\">bbb<\/span>&lt;\/p&gt;<br \/><\/span><span style=\"color: #0000ff;\">&lt;\/SISXRequest&gt;<\/span><\/p>\n<p>&#8230; and an equivalent RESTful version&nbsp;of the request above&nbsp;might look like this:&nbsp;<\/p>\n<p class=\"code\"><span style=\"color: #0000ff;\">http:\/\/myserver\/myWebRequestURL.aspx?<\/span><br \/><strong>_sp<span style=\"color: #0000ff;\">=<\/span><\/strong><span style=\"color: #ff0000;\">sp_xxx<\/span><span style=\"color: #0000ff;\">&amp;<\/span><strong>_cn<\/strong><span style=\"color: #0000ff;\">=<\/span><span style=\"color: #ff0000;\">yyy<\/span><span style=\"color: #0000ff;\">&amp;<\/span><strong>_db<\/strong><span style=\"color: #0000ff;\">=<\/span><span style=\"color: #ff0000;\">zzz<\/span><span style=\"color: #0000ff;\">&amp;<\/span><strong>_x<\/strong><span style=\"color: #0000ff;\">=<\/span><span style=\"color: #ff0000;\">my.xslt<\/span><span style=\"color: #0000ff;\">&amp;<\/span><strong>_pLogin<\/strong>=<span style=\"color: #ff0000;\">aaa<\/span><span style=\"color: #0000ff;\">&amp;<\/span><strong>_pMyOtherParameter<\/strong><span style=\"color: #0000ff;\">=<\/span><span style=\"color: #ff0000;\">bbb<\/span><\/p>\n<p>&nbsp;&#8230; an internal process turns the two request versions into an appropriate collection object, exactly the same in both cases of course, and passes that object into the sproc-handler in the engine.<\/p>\n<p>What&#8217;s left for the client to do?&nbsp; Nothing that an SSRS report can&#8217;t handle.&nbsp; On the client (RDL) side, the work to be &#8220;interactive&#8221; now looks&nbsp;like what you see below.&nbsp;<\/p>\n<h2>Here&#8217;s one I prepared earlier.<\/h2>\n<p>In this example, one RDL, showing students&#8217; readiness for college according to some California state university requirements, drills down to another RDL, which provides a list of courses which the student has not yet taken, and which would fulfill some as-yet-unfullfilled requirements for this student:&nbsp;<\/p>\n<p style=\"text-align: center;\"><img decoding=\"async\" src=\"\/lisa\/wp-non\/migrated\/2012\/8\/EO-1.png\" alt=\"\" \/><\/p>\n<p style=\"text-align: left;\">&#8230; the second RDL is the &#8220;interactive&#8221; one.&nbsp; When a counselor helping the student clicks a course number, a Course Request is submitted to the Student Information&nbsp;System for that student, with that course information.<\/p>\n<p style=\"text-align: left;\">As you might expect, internally (or at design-time), the second RDL&#8217;s clickable link&nbsp;works like this:<\/p>\n<table border=\"0\">\n<tbody>\n<tr>\n<td>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" src=\"\/lisa\/wp-non\/migrated\/2012\/8\/EO-2.png\" alt=\"\" width=\"375\" height=\"431\" \/><\/p>\n<\/td>\n<td valign=\"top\">\n<p>&#8230;where the full Action URL looks like this:<\/p>\n<p><img decoding=\"async\" src=\"\/lisa\/wp-non\/migrated\/2012\/8\/EO-3.png\" alt=\"\" \/><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p style=\"text-align: left;\">&nbsp;&#8230; the function to which the Action URL refers is very simple; however, notice that it opens a new, small&nbsp;window for the response to be returned by the webservice.&nbsp; While this is a small thing, it&#8217;s critical for the user to stay on the report and simply get feedback about each individual action in this response window:<\/p>\n<p class=\"code\"><span style=\"font-size: small;\">&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">Function<\/span><\/span><\/span><span style=\"font-family: Consolas;\"><span style=\"font-family: Consolas;\"> GetCourseRequestURL( _<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><span style=\"font-family: Consolas;\"><span style=\"font-family: Consolas;\">tUser <\/span><\/span><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">As <\/span><\/span><\/span><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">String<\/span><\/span><\/span><span style=\"font-family: Consolas;\"><span style=\"font-family: Consolas;\">, tTemplate <\/span><\/span><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">As <\/span><\/span><\/span><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">String<\/span><\/span><\/span><span style=\"font-family: Consolas;\"><span style=\"font-family: Consolas;\">, _<br \/><\/span><\/span><span style=\"font-family: Consolas;\"><span style=\"font-family: Consolas;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tStudent <\/span><\/span><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">As <\/span><\/span><\/span><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">String<\/span><\/span><\/span><span style=\"font-family: Consolas;\"><span style=\"font-family: Consolas;\">, tCourse <\/span><\/span><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">As <\/span><\/span><\/span><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">String<\/span><\/span><\/span><span style=\"font-family: Consolas;\"><span style=\"font-family: Consolas;\">, tYear <\/span><\/span><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">As <\/span><\/span><\/span><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">String<\/span><\/span><\/span><span style=\"font-family: Consolas;\"><span style=\"font-family: Consolas;\">) _<br \/><\/span><\/span><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; As <\/span><\/span><\/span><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">String<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">Dim<\/span><\/span><\/span><span style=\"font-family: Consolas;\"><span style=\"font-family: Consolas;\"> url <\/span><\/span><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">As <\/span><\/span><\/span><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">String<\/span><\/span><\/span><span style=\"font-family: Consolas;\"><span style=\"font-family: Consolas;\"> = <\/span><\/span><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">String<\/span><\/span><\/span><span style=\"font-family: Consolas;\"><span style=\"font-family: Consolas;\">.Format( _<br \/><\/span><\/span><span style=\"font-family: Consolas;\"><span style=\"font-family: Consolas;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tTemplate, tUser, Trim(tStudent), Trim(tCourse), tYear)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">Return<\/span><\/span><\/span><span style=\"color: #a31515; font-family: Consolas;\"><span style=\"color: #a31515; font-family: Consolas;\"><span style=\"color: #a31515; font-family: Consolas;\">&#8220;javascript:void window.open(&#8216;&#8221;<\/span><\/span><\/span><span style=\"font-family: Consolas;\"><span style=\"font-family: Consolas;\"> &amp; _<br \/><\/span><\/span><span style=\"font-family: Consolas;\"><span style=\"font-family: Consolas;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; url &amp; <\/span><\/span><span style=\"color: #a31515; font-family: Consolas;\"><span style=\"color: #a31515; font-family: Consolas;\"><span style=\"color: #a31515; font-family: Consolas;\">&#8220;&#8216;, &#8216;myWindowSISXResponse&#8217;,&#8221;<\/span><\/span><\/span><span style=\"font-family: Consolas;\"><span style=\"font-family: Consolas;\"> &amp; _<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><span style=\"color: #a31515; font-family: Consolas;\"><span style=\"color: #a31515; font-family: Consolas;\"><span style=\"color: #a31515; font-family: Consolas;\">&#8220;&#8216;status=1,height=300,width=300,resizable=1&#8217;);&#8221;<br \/><\/span><\/span><\/span><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">&nbsp;&nbsp; End<\/span><\/span><\/span><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\"><span style=\"color: #0000ff; font-family: Consolas;\">Function<\/span><\/span><\/span><\/span><\/p>\n<p style=\"text-align: left;\">The &#8220;template&#8221;&nbsp;argument to the function, supplied by a hidden or internal report parameter value, of course, is a straightforward URL that has appropriate placeholders for the parameter requirements, for the sproc to be called, and for the request inferred from the current report row; something like this:<\/p>\n<p class=\"code\" style=\"text-align: left;\">http:\/\/myserver\/myWebRequestURL.aspx?<br \/>_sp=CreateCourseRequest&amp;_cn=eSP&amp;_x=html&amp;_pChangeUID={0}&amp;_pStudentID={1}&amp;_pCourse={2}&amp;_pYear={3}<\/p>\n<p style=\"text-align: left;\">&nbsp;&#8230; See?<\/p>\n<p style=\"text-align: center;\"><img decoding=\"async\" src=\"\/lisa\/wp-non\/migrated\/2012\/8\/EO-4.png\" alt=\"\" \/><\/p>\n<p style=\"text-align: left;\">Simple as that.&nbsp; No harder than any other dynamic link for&nbsp;an RDL to accomplish, except for a small little thoughtful trick involving the use of a separate window, supplied through javascript, for the response.&nbsp;<\/p>\n<p class=\"NB\" style=\"text-align: left;\">Caveat: In your environment, if&nbsp;this report&nbsp;supports PDF and\/or exports, you may want to pass the <a title=\"Robert Bruckner's blog post on RenderFormat Globals\" href=\"http:\/\/blogs.msdn.com\/b\/robertbruckner\/archive\/2010\/05\/02\/globals-renderformat-aka-renderer-dependent-report-layout\/\" target=\"_blank\" rel=\"noopener\">RenderFormat global values<\/a> into the Code function, so that you can decide&nbsp;whether or not you want to use the javascript.&nbsp; For exports, you don&#8217;t want&nbsp;or need to specify the separate result window in this way.&nbsp;<\/p>\n<p style=\"text-align: left;\">Now Tom&nbsp;has to talk to his peers about getting a similar system working.&nbsp;He&#8217;ll have to negotiate the requirements for his environment and for collaboration within his team, but, if he does convince them to put these pieces together, they&#8217;re going to think he&#8217;s very, very clever indeed. &nbsp;\ud83d\ude09<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Tom wrote with another question that has really important implications for anybody who uses SSRS. Do you know if it is possible to do interaction with SSRS?&nbsp; IOW, can I use a button (or a link) in an SSRS report which, when clicked, will post back to the server (for example, send some data to<a class=\"more-link\" href=\"https:\/\/spacefold.com\/lisa\/2012\/08\/26\/equal-opportunity-web-services-ssrs-as-a-client-as-well-as-a-server\/\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,5,6,10],"tags":[],"class_list":["post-46","post","type-post","status-publish","format-standard","hentry","category-asp-net","category-reporting","category-sql-server","category-xml-xslt"],"_links":{"self":[{"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/posts\/46","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/comments?post=46"}],"version-history":[{"count":0,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/posts\/46\/revisions"}],"wp:attachment":[{"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/media?parent=46"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/categories?post=46"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/tags?post=46"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}