Chapter 12: Remote Data Service (RDS) tutorial
Applies to: Access 2013, Office 2013
This tutorial illustrates using the RDS programming model to query and update a data source. First, it describes the steps necessary to accomplish this task. Then the tutorial is repeated in Microsoft Visual Basic Scripting Edition and Microsoft Visual J++, featuring ADO for Windows Foundation Classes (ADO/WFC).
This tutorial is coded in different languages for two reasons:
The documentation for RDS assumes the reader codes in Visual Basic. This makes the documentation convenient for Visual Basic programmers, but less useful for programmers who use other languages.
If you are uncertain about a particular RDS feature and you know a little of another language, you might be able to resolve your question by looking for the same feature expressed in another language.
This tutorial is based on the RDS programming model. It discusses each step of the programming model individually. In addition, it illustrates each step with a fragment of Visual Basic code.
The code example is repeated in other languages with minimal discussion. Each step in a given programming language tutorial is marked with the corresponding step in the programming model and descriptive tutorial. Use the number of the step to refer to the discussion in the descriptive tutorial.
The RDS programming model is stated below. Use it as a roadmap as you proceed through the tutorial.
RDS programming model with objects
Specify the program to be invoked on the server, and obtain a way (proxy) to refer to it from the client.
Invoke the server program. Pass parameters to the server program that identifies the data source and the command to issue.
The server program obtains a Recordset object from the data source, typically by using ADO. Optionally, the Recordset object is processed on the server.
The server program returns the final Recordset object to the client application.
On the client, the Recordset object is optionally put into a form that can be easily used by visual controls.
Changes to the Recordset object are sent back to the server and used to update the data source.
Step 1: Specify a server program
In the most general case, use the RDS.DataSpace object CreateObject method to specify the default server program, RDSServer.DataFactory, or your own custom server program (business object). A server program is instantiated on the server, and a reference to the server program, or proxy, is returned.
This tutorial uses the default server program:
Sub RDSTutorial1()
Dim DS as New RDS.DataSpace
Dim DF as Object
Set DF = DS.CreateObject("RDSServer.DataFactory", "https://yourServer")
...
Step 2: Invoke the server program
When you invoke a method on the client proxy, the actual program on the server executes the method. In this step, you'll execute a query on the server.
Part A
If you weren't using RDSServer.DataFactory in this tutorial, the most convenient way to perform this step would be to use the RDS.DataControl object. The RDS.DataControl combines the previous step of creating a proxy, with this step, issuing the query.
Set the RDS.DataControl object Server property to identify where the server program should be instantiated.
Set the Connect property to specify the connect string to access the data source.
Set the SQL property to specify the query command text.
Issue the Refresh method to cause the server program to connect to the data source, retrieve rows specified by the query, and return a Recordset object to the client.
This tutorial does not use the RDS.DataControl, but this is how it would look if it did:
Sub RDSTutorial2A()
Dim DC as New RDS.DataControl
DC.Server = "https://yourServer"
DC.Connect = "DSN=Pubs"
DC.SQL = "SELECT * FROM Authors"
DC.Refresh
...
Nor does the tutorial invoke RDS with ADO objects, but this is how it would look if it did:
Dim rs as New ADODB.Recordset
rs.Open "SELECT * FROM Authors","Provider=MS Remote;Data Source=Pubs;" & _
"Remote Server=https://yourServer;Remote Provider=SQLOLEDB;"
Part B
The general method of performing this step is to invoke the RDSServer.DataFactory object Query method. That method takes a connect string, which is used to connect to a data source, and a command text, which is used to specify the rows to be returned from the data source.
This tutorial uses the DataFactory object Query method:
Sub RDSTutorial2B()
Dim DS as New RDS.DataSpace
Dim DF
Dim RS as ADODB.Recordset
Set DF = DS.CreateObject("RDSServer.DataFactory", "https://yourServer")
Set RS = DF.Query ("DSN=Pubs", "SELECT * FROM Authors")
...
Step 3: Server obtains a Recordset
The server program uses the connect string and command text to query the data source for the desired rows. ADO is typically used to retrieve this Recordset, although other Microsoft data access interfaces, such as OLE DB, could be used.
A custom server program might look like this:
Public Function ServerProgram(cn as String, qry as String) as Object
Dim rs as New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.Open qry, cn
rs.ActiveConnection = Nothing
Set ServerProgram = rs
End Function
Step 4: Server returns the Recordset
RDS converts the retrieved Recordset object to a form that can be sent back to the client (that is, it marshals the Recordset). The exact form of the conversion and how it is sent depends on whether the server is on the Internet or an intranet, a local area network, or is a dynamic-link library. However, this detail is not critical; all that matters is that RDS sends the Recordset back to the client.
On the client side, a Recordset object is returned and assigned to a local variable.
Sub RDSTutorial4()
Dim DS as New RDS.DataSpace
Dim RS as ADODB.Recordset
Dim DF as Object
Set DF = DS.CreateObject("RDSServer.DataFactory", "https://yourServer")
Set RS = DF.Query("DSN=Pubs", "SELECT * FROM Authors")
...
Step 5: DataControl is made usable
The returned Recordset object is available for use. You can examine, navigate, or edit it as you would any other Recordset. What you can do with the Recordset depends on your environment. Visual Basic and Visual C++ have visual controls that can use a Recordset directly or indirectly with the aid of an enabling data control.
For example, if you are displaying a webpage in Internet Explorer, you might want to display the Recordset object data in a visual control. Visual controls on a webpage cannot access a Recordset object directly. However, they can access the Recordset object through the RDS.DataControl. The RDS.DataControl becomes usable by a visual control when its SourceRecordset property is set to the Recordset object.
The visual control object must have its DATASRC parameter set to the RDS.DataControl, and its DATAFLD property set to a Recordset object field (column).
In this tutorial, set the SourceRecordset property:
Sub RDSTutorial5()
Dim DS as New RDS.DataSpace
Dim RS as ADODB.Recordset
Dim DC as New RDS.DataControl
Dim DF as Object
Set DF = DS.CreateObject("RDSServer.DataFactory", "https://yourServer")
Set RS = DF.Query ("DSN=Pubs", "SELECT * FROM Authors")
DC.SourceRecordset = RS ' Visual controls can now bind to DC.
...
Step 6: Changes are sent to the server
If the Recordset object is edited, any changes (that is, rows that are added, changed, or deleted) can be sent back to the server.
The default behavior of RDS can be invoked implicitly with ADO objects and the Microsoft OLE DB Remoting Provider. Queries can return Recordsets, and edited Recordsets can update the data source. This tutorial does not invoke RDS with ADO objects, but this is how it would look if it did:
Dim rs as New ADODB.Recordset
rs.Open "SELECT * FROM Authors","Provider=MS Remote;Data Source=Pubs;" & _
"Remote Server=https://yourServer;Remote Provider=SQLOLEDB;"
... ' Edit the Recordset.
rs.UpdateBatch ' The equivalent of SubmitChanges.
...
Part A
Assume for this case that you have only used the RDS.DataControl and that a Recordset object is now associated with the RDS.DataControl. The SubmitChanges method updates the data source with any changes to the Recordset object if the Server and Connect properties are still set.
Sub RDSTutorial6A()
Dim DC as New RDS.DataControl
Dim RS as ADODB.Recordset
DC.Server = "https://yourServer"
DC.Connect = "DSN=Pubs"
DC.SQL = "SELECT * FROM Authors"
DC.Refresh
...
Set RS = DC.Recordset
' Edit the Recordset.
...
DC.SubmitChanges
...
Part B
Alternatively, you could update the server with the RDSServer.DataFactory object, specifying a connection and a Recordset object.
Sub RDSTutorial6B()
Dim DS As New RDS.DataSpace
Dim RS As ADODB.Recordset
Dim DC As New RDS.DataControl
Dim DF As Object
Dim blnStatus As Boolean
Set DF = DS.CreateObject("RDSServer.DataFactory", "https://yourServer")
Set RS = DF.Query ("DSN=Pubs", "SELECT * FROM Authors")
DC.SourceRecordset = RS ' Visual controls can now bind to DC.
' Edit the Recordset.
blnStatus = DF.SubmitChanges "DSN=Pubs", RS
End Sub
Appendix A: RDS tutorial (VBScript)
This is the RDS tutorial, written in Microsoft Visual Basic Scripting Edition. For a description of the purpose of this tutorial, see the introduction to this topic.
In this tutorial, RDS.DataControl and RDS.DataSpace are created at design time; that is, they are defined with object tags. Alternatively, they could be created at run time with the Server.CreateObject method.
For example, the RDS.DataControl object could be created like this:
Set DC = Server.CreateObject("RDS.DataControl")
<!-- RDS.DataControl -->
<OBJECT
ID="DC1" CLASSID="CLSID:BD96C556-65A3-11D0-983A-00C04FC29E33">
</OBJECT>
<!-- RDS.DataSpace -->
<OBJECT
ID="DS1" WIDTH=1 HEIGHT=1
CLASSID="CLSID:BD96C556-65A3-11D0-983A-00C04FC29E36">
</OBJECT>
<SCRIPT LANGUAGE="VBScript">
Sub RDSTutorial()
Dim DF1
Step 1: Specify a server program
VBScript can discover the name of the IIS web server it is running on by accessing the VBScript Request.ServerVariables method available to Active Server Pages:
"https://<%=Request.ServerVariables("SERVER_NAME")%>"
However, for this tutorial, use the imaginary server, "yourServer."
Note
Pay attention to the data type of ByRef arguments. VBScript does not let you specify the variable type, so you must always pass a Variant. When using HTTP, RDS will allow you to pass a Variant to a method that expects a non-Variant if you invoke it with the RDS.DataSpace object CreateObject method. When using DCOM or an in-process server, match the parameter types on the client and server sides or you will receive a "Type Mismatch" error.
Set DF1 = DS1.CreateObject("RDSServer.DataFactory", "https://yourServer")
Step 2, Part A: Invoke the server program with RDS.DataControl
This example is merely a comment demonstrating that the default behavior of the RDS.DataControl is to perform the specified query.
<OBJECT CLASSID="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33" ID="DC1">
<PARAM NAME="SQL" VALUE="SELECT * FROM Authors">
<PARAM NAME="Connect" VALUE="DSN=Pubs;">
<PARAM NAME="Server" VALUE="https://yourServer/">
</OBJECT>
...
<SCRIPT LANGUAGE="VBScript">
Sub RDSTutorial2A()
Dim RS
DC1.Refresh
Set RS = DC1.Recordset
...
Skip to the following step.
Step 4: Server returns the Recordset
Set RS = DF1.Query("DSN=Pubs;", "SELECT * FROM Authors")
Step 5: DataControl is made usable by visual controls
' Assign the returned recordset to the DataControl.
DC1.SourceRecordset = RS
Step 6, Part A: Changes are sent to the server with RDS.DataControl
This example is merely a comment demonstrating how the RDS.DataControl performs updates.
<OBJECT CLASSID="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33" ID="DC1">
<PARAM NAME="SQL" VALUE="SELECT * FROM Authors">
<PARAM NAME="Connect" VALUE="DSN=Pubs;">
<PARAM NAME="Server" VALUE="https://yourServer/">
</OBJECT>
...
<SCRIPT LANGUAGE="VBScript">
Sub RDSTutorial6A()
Dim RS
DC1.Refresh
...
Set RS = DC1.Recordset
' Edit the Recordset object...
' The SERVER and CONNECT properties are already set from Step 2A.
Set DC1.SourceRecordset = RS
...
DC1.SubmitChanges
Step 6, Part B: Changes are sent to the server with RDSServer.DataFactory
DF.SubmitChanges"DSN=Pubs", RS
End Sub
</SCRIPT>
</BODY>
</HTML>
Appendix B: RDS tutorial (Visual J++)
ADO/WFC does not completely follow the RDS object model in that it does not implement the RDS.DataControl object. ADO/WFC only implements the client-side class, RDS.DataSpace.
The DataSpace class implements one method, CreateObject, which returns an ObjectProxy object. The DataSpace class also implements the InternetTimeout property.
The ObjectProxy class implements one method, call, which can invoke any server-side business object.
import com.ms.wfc.data.*;
public class RDSTutorial
{
public void tutorial()
{
// Step 1: Specify a server program.
ObjectProxy obj =
DataSpace.createObject(
"RDSServer.DataFactory",
"https://YourServer");
// Step 2: Server returns a Recordset.
Recordset rs = (Recordset) obj.call(
"Query",
new Object[] {"DSN=Pubs;", "SELECT * FROM Authors"});
// Step 3: Changes are sent to the server.
... // Edit Recordset.
obj.call(
"SubmitChanges",
new Object[] {"DSN=Pubs;", rs});
return;
}
}