Windows Client Development |
The preceding sections provide many examples of using the IOM interfaces in a full Visual Basic environment (or in a Visual Basic for Applications (VBA) environment like Microsoft Word and Excel).
You can also use the IOM interfaces from a VBScript environment. VBScript is a commonly-used scripting language that is available in Active Server Pages (ASP), Dynamic HTML (DHTML), Microsoft Outlook 97/98, and Windows Scripting Host. For configuration information, see Configuring COM/DCOM for Active Server Page Access.
Scripto is an ActiveX DLL that has been developed by SAS in order to provide workarounds for the following common VBScript limitations:
Scripto is provided with SAS Integration Technologies so that developers who choose to use VBScript can effectively use the SAS automation interfaces. However, there is nothing in Scripto that makes it SAS-specific, and Scripto can be used with other automation interfaces.
The performance of VBScript is usually less than a VB application for several reasons. First, VBScript provides only late binding (it uses IDispatch instead of v-table calls). Also, VBScript is interpreted, not compiled. In addition, the way that VBScript invokes methods (InvokeMethod) causes additional overhead since all parameters must be copied again to get them in the proper format in which VBScript expects them.
This is especially evident in the case of safearrays in which SAS expects to contain the actual type of element in the array (such as string or an enum value). VBScript expects it to contain only VARIANTS, which in turn contain the appropriate type of element. InvokeMethod takes care of this conversion. However, it causes an additional copy of the array.
Scripto does not address these performance issues. We at SAS recommend that if performance is an issue, consider something other than a scripting language for your implementation. We also recommend that you only use Scripto when calling methods whose signatures require it.
There are 2 components implemented by the Scripto DLL: Scripto and StreamHelper.
IScripto is the single interface to the Scripto component. It provides two methods:
The interface specified must support IDispatch, and that IDispatch implementation must support type info. If either of these is not true, SetInterface will return E_INVALIDARG(&H80070057).
An instance of the Scripto component can deal with only a single interface at a time. Although you can create multiple instances of Scripto that each deal with a different interface, you typically only need a single instance of Scripto and you use this instance for all interfaces that need the service. Switching between interfaces does not consume a significant amount of system resources.
SetInterface performs an AddRef function on the interface that is specified. You can release this reference when you are finished with the interface with the following statement:
SetInterface NothingAlso, when you release IScripto, it will release any interface that Scripto still has a reference to.
Note that once you set an interface, you can still make calls on it without using Scripto.
methodName is a string that contains the name of the method to invoke on the interface that has been set.
params is an array whose elements contain the parameters for the method to be invoked. The order of the parameters placed in the array must be in reverse order of how they are specified in the method signature. The array must have exactly the same number of elements as there are parameters to the method. Otherwise, InvokeMethod returns DISP_E_BADPARAMCOUNT(&H8002000E) .
Note: If the method has a parameter that uses the [retval] modifier, then this parameter is returned as the return value to InvokeMethod and you do not need an element in the params array for it.
retParam is the return value from the method you are invoking, if that method returns a value.
Note: If the method returns a reference to an object, make sure to use the set keyword. For example:
Set obServer = obScripto.InvokeMethod("CreateWorkspaceByServer", ServerDefParms)
The StreamHelper interface contains three methods related to working with the SAS BinaryStream (available through the SAS FileService). These methods are only useful when working with SAS; these methods make calls on IBinaryStream to read/write binary data.
Microsoft supplies the FileSystemObject which can be used to read and write text files. The FileSystemObject does not work with binary files, so SAS has provided these methods. The StreamHelper interface is implemented in Scripto.dll using the SASScripto.StreamHelper progid.The first example illustrates using the Scripto component to reverse the order of parameters when invoking a method. Assuming the method has been defined with the following IDL:
HRESULT MethodToInvoke([in]param1, [out]param2, [out]param3)
To make this call with Scripto:
Dim f(2) 'An array of 3 VARIANTS obScripto.SetInterface myInterface f(2) = param1 obScripto.InvokeMethod "MethodToInvoke", f param3 = f(0) ' note that the order of parameters is reversed param2 = f(1)
The next example uses the IOM LanguageService to submit SAS Language statements to the IOM server. It then uses Scripto to invoke the FlushLogLines method of the LanguageService. Using Scripto provides two important advantages over invoking the method directly from VBScript:
set obSAS = CreateObject("SAS.Workspace") Set obScripto = CreateObject("SASScripto.Scripto") obSAS.LanguageService.Submit "proc options;run;" obScripto.SetInterface obSAS.LanguageService ' This example uses Scripto to invoke the FlushLogLines method ' instead of invoking the method directly from VBScript ' as shown in the following statement: ' obSAS.LanguageService.FlushLogLines 1000, carriageControls, linetypes, logLines Dim flushLogLinesParams(3) ' Note that the FlushLogLines method takes 4 parameters: ' 1) numLinesRequested (in) Specifies an upper limit on number of lines to be returned. ' 2) carriageControls (out) An array that indicates carriage control for each line returned. ' 3) lineTypes (out) An array that indicates the line type for each line returned. ' 4) logLines (out) Contains the SAS log output lines retrieved by this call. flushLogLinesParams(3) = 1000 obScripto.InvokeMethod "FlushLogLines", flushLogLinesParams ' flushLogLinesParams(0) now has logLines ' flushLogLinesParams(1) now has lineTypes ' flushLogLinesParams(2) now has carriageControls wscript.echo flushLogLinesParams(0)(0) ' This prints the first line
The next example illustrates using ReadBinaryArray with Microsoft Active Server Pages. Assume a SAS program has already run that uses SAS/Graph to write a GIF image to a fileref called img. This example then uses the FileService to read that file back to the browser, with no intermediate files on the web server
set obFref = obSAS.FileService.UseFileref("img") set obBinaryStream = obFref.OpenBinaryStream(1) ' SAS.StreamOpenModeForReading=1 set obStreamHelper = CreateObject("SASScripto.StreamHelper") response.contenttype = "image/gif" response.binarywrite obStreamHelper.ReadBinaryArray(obBinaryStream, 0)
The last example shows how to use WriteBinaryFile to copy a SAS ResultPackage. Demo.sas is a stored procedure which creates a resultpackage in an archive.
obSAS.LanguageService.StoredProcessService.Execute "demo.sas", parameters
The next four lines move the package that was just created from the SAS server to the local machine.
Set obRemotePackageFileRef = obSAS.FileService.AssignFileref("", "", "./demo.spk", "", "")
Open a binary stream on the SAS Server for the package file.
Set obRemotePackageBinaryStream = obRemotePackageFileRef.OpenBinaryStream(1) 'StreamOpenModeForReading
Because VBScript cannot handle binary files, use the Scripto object to write the binary file on the local machine.
Set obStreamHelper = Server.CreateObject("SASScripto.StreamHelper") obStreamHelper.WriteBinaryFile obRemotePackageBinaryStream, "c:\myfile.spk"
Windows Client Development |