![]() | ![]() | ![]() | ![]() |
This sample demonstrates how to use Visual Basic Script (VBScript) and the SAS Integrated Object Model (IOM) Object Linking and Embedding Database (OLE DB) Data Provider to move data between a SAS IOM Server and Microsoft Access and between a SAS IOM Server and Microsoft Excel.
Specifically, this sample demonstrates how to use the SAS IOM OLE DB Data Provider to:
The techniques described in this sample can be used with all SAS OLE DB Providers.
The import.excel.vbs file demonstrates how to use Visual
Basic Script to transfer data from a SAS IOM Server to a
Microsoft Excel spreadsheet. To simplify the sample and focus
on the code necessary to move the data, the following
assumptions are made:
You can change any of these assumptions. Refer to Configuration in this section.
In the Constants section, return codes, flags, Active X Data Objects (ADO) constants, and Excel constants are defined for use later in the code.
'----------------------------------------------------------------------------- '--- Constants const ERR_NOBOOK = -1 const ERR_NOSHEET = -2 const ERR_NORECORDSET = -3 const adOpenForwardOnly = 0 const adLockReadOnly = 1 const adCmdTableDirect = 512 const adCmdText = 1 const xlThin = 2 const xlEdgeBottom = 9
Configuration values tell the rest of the code where to get data and where to send data. You can change any of these values to match the setup on your machine.
'----------------------------------------------------------------------------- '--- Configuration vars Dim Filename, SASConnectionString, DatasetName, DatasetType '--- Full path to the .xls file Filename = "C:\myexisting.xls" '--- Connection string for SAS OLE DB provider SASConnectionString = "Provider=SAS.IOMProvider.1;Data Source=_LOCAL_" '--- libref.member or SELECT SQL query DatasetName = "sashelp.adomsg" '--- If DatasetName is libref.member then DatasetType should be adCmdTableDirect. '--- If DatasetName is SELECT SQL statement then DatasetType should be adCmdText. DatasetType = adCmdTableDirect
The GetRecordset function is used to open an ADO Recordset object on the data set and server named in the Configuration section.
'----------------------------------------------------------------------------- '--- GetRecordset
Private Function GetRecordset()
Dim Connection
Set Connection = WScript.CreateObject("ADODB.Connection")
Set GetRecordset = WScript.CreateObject("ADODB.Recordset")
Connection.Open SASConnectionString
GetRecordset.Open DatasetName, Connection, _
adOpenForwardOnly, adLockReadOnly, DatasetType
End Function
This sample first calls the GetBook function to open the Excel file specified in the Configuration section. If an empty string was specified, then the user is prompted to pick a file to open. This opened file is then passed to the GetSheet function which attempts to create a new sheet in the file named after the data set that is being imported. If a sheet with that name already exists, then the user is prompted to overwrite the sheet or quit the program.
'----------------------------------------------------------------------------- '--- GetBook
Private Function GetBook( appXL )
If Filename = "" Then
Set GetBook = appXL.Workbooks.Open( appXL.GetOpenFilename() )
Else
Set GetBook = appXL.Workbooks.Open( Filename )
End If
End Function
Private Function GetSheet( Book )
Dim res
on error resume next
Set GetSheet = Nothing
Set GetSheet = Book.Sheets( DatasetName & " data" )
on error goto 0
If not GetSheet Is Nothing Then
res = MsgBox( DatasetName & " worksheet found." & vbNewLine & _
"Click ""Ok"" to continue and overwrite data on this sheet.", _
vbOKCancel Or vbExclamation, "SAS Import Data Wizard" )
If res = vbCancel Then
Set GetSheet = Nothing
end if
else
Set GetSheet = Book.Sheets.Add()
GetSheet.Name = DatasetName & " data"
End If
End Function
Now that both the data set and the Excel sheet are open, the sample transfers data from the data set into the sheet. Starting at the cell "A1", the sample copies the names of the columns into the first row. A border is then placed under these names, and the values from the data set are copied. One sheet in Excel can hold only 256 columns and 65,536 rows. Any data in either dimension that will not fit on one sheet is ignored. The method AutoFit is then called on the columns collection of the Sheet object to make sure that all the data are visible.
'----------------------------------------------------------------------------- '--- CopyData
Private Sub CopyData( Sheet, Recordset )
Dim maxRows, maxCols
Dim i, j
Dim Rng
maxRows = 65536
maxCols = 256
Set Rng = Sheet.Range("a1")
j = 0
While j < Recordset.Fields.Count and j < maxCols
Rng.Offset(0, j).value = Recordset.Fields(j).name
Rng.Offset(0, j).Borders.Item(xlEdgeBottom).Weight = xlThin
j = j + 1
WEnd
i = 1
While Not Recordset.EOF and i < maxRows
Set Rng = Rng.Offset(1)
j = 0
While j < Recordset.Fields.Count and j < maxCols
Rng.Offset(, j).Value = Recordset.Fields(j).Value
j = j + 1
WEnd
Recordset.MoveNext
i = i + 1
WEnd
Sheet.Columns.AutoFit
End Sub
The export.excel.vbs file demonstrates how to use Visual
Basic Script to transfer data from a Microsoft Excel
spreadsheet to a SAS IOM Server. To simplify the sample and
focus on the code necessary to move the data, the following
assumptions are made:
You can change any of these assumptions. Refer to Configuration in this section.
In the Constants section, return codes, flags, ADO constants, and Excel constants are defined for use later in the code.
'----------------------------------------------------------------------------- '--- Constants const ERR_NOBOOK = -1 const ERR_NOSHEET = -2 const ERR_NORECORDSET = -3 const ERR_NORANGE = -4 const adOpenForwardOnly = 0 const adOpenDynamic = 2 const adLockReadOnly = 1 const adLockOptimistic = 3 const adCmdTableDirect = 512 const adCmdText = 1 const xlThin = 2 const xlEdgeBottom = 9
Configuration values tell the rest of the code where to get data and where to send data. You can change any of these values to match the setup on your machine.
'----------------------------------------------------------------------------- '--- Configuration vars Dim Filename, SheetName, Selection, SASConnectionString, DatasetName, DatasetType '--- Full path to the .xls file Filename = "C:\myexisting.xls" '--- Name of the sheet to export SheetName = "Sheet1" '--- Name of the selection to export Selection = "A1:D20" '--- Connection string for SAS OLE DB provider SASConnectionString = "Provider=SAS.IOMProvider.1;Data Source=_LOCAL_" '--- libref.member DatasetName = "sasuser.mydata" '--- DatasetType should be adCmdTableDirect. DatasetType = adCmdTableDirect
This sample first calls the GetBook function to open the Excel file specified in the Configuration section. This opened file is then passed to the GetSheet function which attempts to find the sheet specified in the Configuration section. If the sheet cannot be found, then the user is notified, and the sample exits. A Range object is then obtained for the cells specified in the Configuration section.
'----------------------------------------------------------------------------- '--- GetBook
Private Function GetBook( appXL )
Set GetBook = appXL.Workbooks.Open( Filename )
End Function
Private Function GetSheet( Book )
Dim res
On Error Resume Next
Set GetSheet = Nothing
Set GetSheet = Book.Sheets( SheetName )
On Error GoTo 0
If GetSheet Is Nothing Then
MsgBox SheetName & " worksheet not found.", vbOK Or vbExclamation, _
"SAS Export Data Wizard"
End If
End Function
Private Function GetRange( Sheet )
Set GetRange = Sheet.Range(Selection)
End Function
The sample then attempts to create a new data set on the SAS IOM Server. The name of the new data set and the server on which the data set will be created are specified in the Configuration section. The structure of the data set is determined by the first row found in the selected range. This row must indicate the name, type, and width of each column. The format is "name:type:width".
For example, a column named "Col1" that is numeric and has a width of 4 must have "Col1:num:4" in the first cell of that column. Character columns are specified as type "chr". Other methods to obtain column information are beyond the scope of this sample. If the data set already exists, then the user is prompted to overwrite it or exit.
'----------------------------------------------------------------------------- '--- GetSASRecordset
Private Function GetSASRecordset( Rng, Types )
Dim res, i, j, bFirst, elm, typename, colname, width, pos, sql
Dim Connection
ReDim Types( Rng.Columns.Count - 1 )
Set Connection = WScript.CreateObject("ADODB.Connection")
Set GetSASRecordset = WScript.CreateObject("ADODB.Recordset")
Connection.Open SASConnectionString
On Error Resume Next
GetSASRecordset.Open DatasetName, Connection, adOpenForwardOnly, _
adLockReadOnly, adCmdTableDirect
If Err.Number = 0 Then
GetSASRecordset.Close
res = MsgBox( DatasetName & " table found." & vbNewLine & _
"Click ""Ok"" to continue and overwrite this table.", _
vbOKCancel Or vbExclamation, "SAS Export Data Wizard")
If res = vbCancel Then
Set GetSASRecordset = Nothing
Exit Function
End If
ElseIf Err.Number <> -2147217865 Then
MsgBox "Unexpected error: " & Err.Description & ": " & Err.Number
Set GetSASRecordset = Nothing
Exit Function
End If
On Error GoTo 0
sql = "create table " & DatasetName & " ("
bFirst = True
i = 1
j = 1
For j = 1 to Rng.Columns.Count
Set elm = Rng.Cells(i, j)
If IsEmpty(elm) Then Exit For
typename = ""
colname = elm.Value
width = "8"
pos = InStr(elm.Value, ":")
If pos <> 0 Then
typename = Mid(elm.Value, pos + 1)
colname = Left(elm.Value, pos - 1)
pos = InStr(typename, ":")
If pos <> 0 Then
width = Mid(typename, pos + 1)
typename = Left(typename, pos - 1)
End If
End If
Types(j - 1) = typename
If Not bFirst Then sql = sql & ", "
bFirst = False
If typename = "chr" Then
sql = sql & colname & " char(" & width & ")"
ElseIf typename = "num" Or typename = "" Then
sql = sql & colname & " num(" & width & ")"
End If
Next
sql = sql & ")"
Connection.Execute sql
GetSASRecordset.Open DatasetName, Connection, adOpenDynamic, _
adLockOptimistic, adCmdTableDirect
End Function
Now that both the data set and the Excel sheet are open, the sample transfers data from the sheet into data set. Starting at the second row in the specified range (because the first one contains column information), the sample copies the data from each cell.
'----------------------------------------------------------------------------- '--- CopyData
Private Sub CopyData( Rng, Types, Recordset )
Dim i, j, elm, vt
For i = 2 To Rng.Rows.Count
Recordset.AddNew
For j = 1 To Rng.Columns.Count
Set elm = Rng.Cells(i, j)
If Not IsEmpty(elm) Then
vt = VarType(elm.Value)
If vt = 8 Then ' elm.Value is character data
If Types(j - 1) = "chr" Then ' column is character data
Recordset.Fields(j - 1) = elm.Value
Else ' column is numeric data
Recordset.Fields(j - 1) = Null ' CDbl(elm.Value)
End If
ElseIf vt = 5 Then ' elm.Value is numeric data
If Types(j - 1) = "chr" Then ' column is character data
Recordset.Fields(j - 1) = CStr(elm.Value)
Else ' column is numeric data
Recordset.Fields(j - 1) = elm.Value
End If
End If
End If
Next
Recordset.Update
Next
End Sub
The import.access.vbs file demonstrates how to use Visual
Basic Script to transfer data from a SAS IOM Server to a
Microsoft Access database. To simplify the sample and focus on
the code necessary to move the data, the following assumptions
are made:
You can change any of these assumptions. Refer to Configuration in this section.
In the constants section, return codes, flags, ADO constants, and Excel constants are defined for use later in the code.
'----------------------------------------------------------------------------- '--- Constants const ERR_NOSASRECORDSET = -1 const ERR_NOACCESSRECORDSET = -2 const adOpenForwardOnly = 0 const adOpenDynamic = 2 const adLockReadOnly = 1 const adLockBatchOptimistic = 4 const adCmdTableDirect = 512 const adCmdText = 1 const adSchemaTables = 20 const adChar = 129 const adVarChar = 200 const adWChar = 130 const adVarWChar = 202 const adDouble = 5
Configuration values tell the rest of the code where to get data and where to send data. You can change any of these values to match the setup on your machine.
'----------------------------------------------------------------------------- '--- Configuration vars Dim Filename, SASConnectionString, DatasetName, DatasetType '--- Full path to the .mdb file Filename = "c:\myexisting.mdb" '--- Connection string for SAS OLE DB provider SASConnectionString = "Provider=SAS.IOMProvider.1;Data Source=_LOCAL_" '--- libref.member or SELECT SQL query DatasetName = "sashelp.adomsg" '--- If DatasetName is libref.member then DatasetType should be adCmdTableDirect. '--- If DatasetName is SELECT SQL statement then DatasetType should be adCmdText. DatasetType = adCmdTableDirect '----------------------------------------------------------------------------- '--- Global vars Dim AccessConnectionString AccessConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Filename
The GetSASRecordset function is used to open an ADO Recordset object on the data set and server named in the Configuration section.
'----------------------------------------------------------------------------- '--- GetSASRecordset
Private Function GetSASRecordset()
Dim Connection
Set Connection = WScript.CreateObject("ADODB.Connection")
Set GetSASRecordset = WScript.CreateObject("ADODB.Recordset")
Connection.Open SASConnectionString
GetSASRecordset.ActiveConnection = Connection
GetSASRecordset.CacheSize = 55
GetSASRecordset.Properties("Maximum Open Rows") = 110
GetSASRecordset.Open DatasetName, , adOpenForwardOnly, _
adLockReadOnly, DatasetType
End Function
The GetAccessRecordset method is used to create a new table in the specified Access database named after the data set that is being imported. If a table with this name already exists, then the user is prompted to overwrite or exit the sample. The structure of this new table is based on that of the SAS data set opened in the GetSASRecordset method.
'----------------------------------------------------------------------------- '--- GetAccessRecordset
Private Function GetAccessRecordset( SASRecordSet )
Dim Connection, TablesRS, Tbl, res, bFirst, bContinue, fld, sql, Name
Name = ConvertToAccessName( DatasetName )
Set Connection = WScript.CreateObject("ADODB.Connection")
Set GetAccessRecordset = WScript.CreateObject("ADODB.Recordset")
Set TablesRS = WScript.CreateObject("ADODB.Recordset")
Connection.Open AccessConnectionString
Set TablesRS = Connection.OpenSchema( adSchemaTables )
bContinue = True
While bContinue And Not TablesRS.EOF
If TablesRS.Fields("TABLE_NAME").Value = Name Then
res = MsgBox( Name & " table found." & vbNewLine & _
"Click ""Ok"" to continue and overwrite this table.", _
vbOKCancel Or vbExclamation, "SAS Import Data Wizard" )
If res = vbCancel Then
Set GetAccessRecordset = Nothing
Exit Function
End If
Connection.Execute "DROP TABLE [" & Name & "]"
bContinue = False
End If
TablesRS.MoveNext
WEnd
bFirst = True
sql = "CREATE TABLE [" & Name & "] ("
For Each fld In SASRecordSet.Fields
If Not bFirst Then sql = sql & ", "
sql = sql & "[" & fld.name & "]"
If fld.Type = adChar Or _
fld.Type = adVarChar Or _
fld.Type = adWChar Or _
fld.Type = adVarWChar Then
sql = sql & " TEXT(" & fld.DefinedSize & ")"
ElseIf fld.Type = adDouble Then
sql = sql & " FLOAT"
End If
bFirst = False
Next
sql = sql & ")"
Connection.Execute sql
GetAccessRecordset.Open Name, Connection, adOpenDynamic, _
adLockBatchOptimistic, adCmdTableDirect
End Function
Now that a Recordset is open on both the SAS data set and the Access table, the actual data are copied. The src and dst parameters both must be open Recordset objects.
'----------------------------------------------------------------------------- '--- CopyData
Private Sub CopyData( src, dst )
Dim col
While Not src.EOF
dst.AddNew
For col = 0 To src.Fields.Count - 1
dst.Fields(col).Value = src.Fields(col).Value
Next
dst.UpdateBatch
src.MoveNext
Wend
End Sub
The export.access.vbs file demonstrates how to use Visual
Basic Script to transfer data from a Microsoft Access database
to a SAS IOM Server. To simplify the sample and focus on the
code necessary to move the data, the following assumptions are
made:
You can change any of these assumptions. Refer to Configuration in this section.
In the constants section return codes, flags, ADO constants, and Excel constants are defined for use later in the code.
'----------------------------------------------------------------------------- '--- Constants const ERR_NOSASRECORDSET = -1 const ERR_NOACCESSRECORDSET = -2 const adOpenForwardOnly = 0 const adOpenDynamic = 2 const adLockReadOnly = 1 const adLockBatchOptimistic = 4 const adCmdTableDirect = 512 const adCmdText = 1 const adSchemaTables = 20 const adChar = 129 const adVarChar = 200 const adWChar = 130 const adVarWChar = 202 const adDouble = 5
Configuration values tell the rest of the code where to get data and where to send data. You can change any of these values to match the setup on your machine.
'----------------------------------------------------------------------------- '--- Configuration vars Dim Filename, SASConnectionString, TableName, DatasetName, DatasetType '--- Full path to the .mdb file Filename = "c:\myexisting.mdb" '--- Connection string for SAS OLE DB provider SASConnectionString = "Provider=SAS.IOMProvider.1;Data Source=_LOCAL_" '--- Access tablename TableName = "sashelp_adomsg" '--- libref.member DatasetName = "sasuser.mydata" '--- DatasetType should be adCmdTableDirect. DatasetType = adCmdTableDirect '----------------------------------------------------------------------------- '--- Global vars Dim AccessConnectionString AccessConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Filename
The sample then attempts to open a Recordset on the Access table specified in the Configuration section.
'----------------------------------------------------------------------------- '--- GetAccessRecord
Private Function GetAccessRecordset()
Dim Connection
Set Connection = WScript.CreateObject("ADODB.Connection")
Set GetAccessRecordset = WScript.CreateObject("ADODB.Recordset")
Connection.Open AccessConnectionString
GetAccessRecordset.Open TableName, Connection, adOpenForwardOnly, _
adLockReadOnly, DatasetType
End Function
The sample then attempts to create a new data set on the SAS IOM Server. The name of the new data set and the server on which the data set will be created are specified in the Configuration section. If the table exists, then the user is prompted to overwrite it or exit the program.
'----------------------------------------------------------------------------- '--- GetSASRecordset
Private Function GetSASRecordset( AccessRecordset )
Dim Connection, TablesRS, Tbl, res, bFirst, bContinue, fld, sql, Name
Set Connection = WScript.CreateObject("ADODB.Connection")
Set GetSASRecordset = WScript.CreateObject("ADODB.Recordset")
Set TablesRS = WScript.CreateObject("ADODB.Recordset")
Connection.Open SASConnectionString
Set TablesRS = Connection.Execute( _
"select libname, memname from dictionary.tables")
bContinue = True
While bContinue And Not TablesRS.EOF
If lcase(TablesRS.Fields("libname").Value & _
"." & _
TablesRS.Fields("memname")) = lcase(DatasetName) Then
res = MsgBox( DatasetName & " table found." & vbNewLine & _
"Click ""Ok"" to continue and overwrite this table.", _
vbOKCancel Or vbExclamation, "SAS Import Data Wizard")
If res = vbCancel Then
Set GetSASRecordset = Nothing
Exit Function
End If
Connection.Execute "DROP TABLE " & DatasetName
bContinue = False
End If
TablesRS.MoveNext
WEnd
bFirst = True
sql = "CREATE TABLE " & DatasetName & " ("
For Each fld In AccessRecordset.Fields
If Not bFirst Then sql = sql & ", "
sql = sql & fld.name
If fld.Type = adChar Or _
fld.Type = adVarChar Or _
fld.Type = adWChar Or _
fld.Type = adVarWChar Then
sql = sql & " CHAR(" & fld.DefinedSize & ")"
ElseIf fld.Type = adDouble Then
sql = sql & " NUM"
End If
bFirst = False
Next
sql = sql & ")"
Connection.Execute sql
GetSASRecordset.Open DatasetName, Connection, adOpenDynamic, _
adLockBatchOptimistic, adCmdTableDirect
End Function
Now that both the data set and the Access table are open, the sample transfers data from the table into data set. The src and dst parameters both must be open Recordset objects.
'----------------------------------------------------------------------------- '--- CopyData
Private Sub CopyData( src, dst )
Dim col
While Not src.EOF
dst.AddNew
For col = 0 To src.Fields.Count - 1
dst.Fields(col).Value = src.Fields(col).Value
Next
dst.UpdateBatch
src.MoveNext
Wend
End Sub
These sample files and code examples are provided by SAS Institute Inc. "as is" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and fitness for a particular purpose. Recipients acknowledge and agree that SAS Institute shall not be liable for any damages whatsoever arising out of their use of this material. In addition, SAS Institute will provide no support for the materials contained herein.
These sample files and code examples are provided by SAS Institute Inc. "as is" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and fitness for a particular purpose. Recipients acknowledge and agree that SAS Institute shall not be liable for any damages whatsoever arising out of their use of this material. In addition, SAS Institute will provide no support for the materials contained herein.
There are four source files provided with this sample:
import.excel.vbs imports the "sashelp.adomsg" data set from a local IOM Server into the Microsoft Excel spreadsheet at "C:\myexisting.xls".
export.excel.vbs exports the selection "A1:D20" from "Sheet1" in the Microsoft Excel spreadsheet at "C:\myexisting.xls" to "sasuser.mytable" on a local SAS IOM Server.
import.access.vbs imports the "sahelp.adomsg" data set from a local SAS IOM Server into the Microsoft Access database at "C:\myexisting.mdb".
export.access.vbs exports the table "mytable" from the Microsoft Access database at "C:\myexisting.mdb" to "sasuser.mytable" on a local SAS IOM Server.Each source file included in this sample can be run from the command line to import or export to and from the Microsoft Office applications. Each file currently operates on a static path to an Office file, a static connection string to identify a local IOM Server, and a static libname.memname to identify a data set. The user can modify the files to indicate other files, servers, or data sets as they wish.
To run this sample, you must have the following software installed on your computer:
To install this sample, download the sample package and extract the files to a directory on your computer.
The sample package contains the following files:
import.excel.vbsexport.excel.vbsimport.access.vbsexport.access.vbsYou can run the samples from a command prompt as follows:
| Command | Command Prompt |
| to import into Microsoft Excel | cscript import.excel.vbs |
| to export from Microsoft Excel | cscript export.excel.vbs |
| to import into Microsoft Access | cscript import.access.vbs |
| to export from Microsoft Access | cscript export.access.vbs |
Note: The "Configuration vars" section of each .vbs file must be edited before the samples will run correctly. For more information see the following sections:
| Type: | Sample |
| Date Modified: | 2005-06-09 03:00:15 |
| Date Created: | 2005-06-07 17:12:51 |
| Product Family | Product | Host | SAS Release | |
| Starting | Ending | |||
| SAS System | SAS Integration Technologies | Windows | n/a | n/a |



