GP/QTP Automation: Overcoming VBScript limitation with Excel macros
All related posts: Reference Page – GP/QTP Automation
VBScript limitation
Since VBscript supports only Variant type attempts to use variable in a COM call with an argument defined as “[in, out] BSTR * “ reasonably end with “Type mismatch” error. This error is generated by the COM object itself rather then VBscript interpreter since the object gets string instead of a pointer.
ExecuteSanScript method uses “string pointer” for parameter exchange which is not supported in VBScript that has only and single “variant” data type. Passing in VBScript variables causes “Type Mismatch”.
There are 3 ways to overcome the identified limitation.
- Do not use “string pointer” type in the COM function. – Not applicable way in case of QTP/GP automation as we have the vendor provided code.
- Implement in C++ (or other similar language) COM compatible DLL module with the all library functions directly operating with Dynamics.Application object and serving as a wrapping bridge to convert “string pointer” type to “variant” and backward.
- Use existing COM object that may act both as Automation Server and Automation Client.
Excel.Application object is a good candidate as it has built-in internal Excel.VBA execution engine.
Documentation
The following portal could be useful both for beginners and advanced Excel.VBA programmers and users: http://www.functionx.com/excel/index.htm
Excel Object Model Overview from Microsoft contains full description and some examples
http://msdn.microsoft.com/en-us/library/wss56bz7(VS.80).aspx
Creating Excel macro module
1) Start Excel application and create new workbook
2) Go to “Main Menu \ Tools \ Macro \ Visual Basic Editor”
3) Right-click on the VBA Project panel and insert Code Module and Class Module
4) Select Class Module and on the Properties panel define its name: ParamHandlerClass. Get to the Code Editor and on the “General/Declarations” section define (type in or copy/paste) parameter names:
Public Value1 As String Public Value2 As String Public Value3 As String Public Value4 As String
5) Select Code Module and get to the Code Editor. Copy the following code.
Option Explicit
Public GPApp As Object
Public ParamHandler As ParamHandlerClass
Public Function Init()
Dim intRC
Set GPApp = GetObject("", "Dynamics.Application")
Set ParamHandler = New ParamHandlerClass
intRC = GPApp.SetParamHandler(ParamHandler)
End Function
Public Function Done()
Set GPApp = Nothing
Set ParamHandler = Nothing
End Function
Public Function GetDexActiveWindow()
Dim intRC As Integer
Dim sFormName As String
Dim sWindowName As String
Dim sDictName As String
Dim sTitle As String
'Clean
Workbooks.Item(1).Sheets.Item(1).Cells(2, 1) = ""
Workbooks.Item(1).Sheets.Item(1).Cells(2, 2) = ""
Workbooks.Item(1).Sheets.Item(1).Cells(2, 3) = ""
Workbooks.Item(1).Sheets.Item(1).Cells(2, 4) = ""
'Call method
intRC = GPApp.GetDexActiveWindow(sFormName, sWindowName, sDictName, sTitle)
'Store parameters
Workbooks.Item(1).Sheets.Item(1).Cells(2, 1) = sFormName
Workbooks.Item(1).Sheets.Item(1).Cells(2, 2) = sWindowName
Workbooks.Item(1).Sheets.Item(1).Cells(2, 3) = sDictName
Workbooks.Item(1).Sheets.Item(1).Cells(2, 4) = sTitle
End Function
'Note.
'SanScript's string data type is limited up to 255 chars
'Therefore contents of the list is retrieved in a loop of calls
'and one by one items are collected in VB
Public Function GetListContent()
Dim intRC As Integer
Dim intCount, Iter As Integer
Dim sCode, sErrMsg As String
Dim sListName, sResult As String
sListName = Workbooks.Item(1).Sheets.Item(1).Cells(2, 1)
'Get list content count
sCode = "local integer count; count = countitems(" & sListName & "); OLE_SetProperty(""Value1"", str(count));"
intRC = GPApp.ExecuteSanScript(sCode, sErrMsg)
If intRC <> 0 Then
Workbooks.Item(1).Sheets.Item(1).Cells(2, 5) = intRC
Workbooks.Item(1).Sheets.Item(1).Cells(2, 4) = sErrMsg
Exit Function
End If
intCount = ParamHandler.Value1
If intCount = 0 Then
Workbooks.Item(1).Sheets.Item(1).Cells(2, 5) = -1
Workbooks.Item(1).Sheets.Item(1).Cells(2, 4) = "The list is empty"
Exit Function
End If
'Get first element
sCode = "OLE_SetProperty(""Value1"", itemname(" & sListName & ", 1));"
intRC = GPApp.ExecuteSanScript(sCode, sErrMsg)
If intRC <> 0 Then
Workbooks.Item(1).Sheets.Item(1).Cells(2, 5) = intRC
Workbooks.Item(1).Sheets.Item(1).Cells(2, 4) = sErrMsg
Exit Function
End If
sResult = ParamHandler.Value1
'Loop and retrieve the rest
For Iter = 2 To intCount
sCode = "OLE_SetProperty(""Value1"", itemname(" & sListName & ", " & Iter & "));"
intRC = GPApp.ExecuteSanScript(sCode, sErrMsg)
If intRC <> 0 Then
Workbooks.Item(1).Sheets.Item(1).Cells(2, 5) = intRC
Workbooks.Item(1).Sheets.Item(1).Cells(2, 4) = sErrMsg
Exit Function
End If
sResult = sResult & Chr(10) & ParamHandler.Value1
Next
'Store result
Workbooks.Item(1).Sheets.Item(1).Cells(2, 5) = 0
Workbooks.Item(1).Sheets.Item(1).Cells(2, 1) = sResult
End Function
6) Save and close Excel and Excel.VBA windows.
Next posts will demonstrate examples on using VB macros called by VBScript from within QTP.
If someone experiences difficulties creating Excel file, you can download it.
If you have any additional questions on the code samples presented you’re welcome to put them in comments for this post.


2 responses to "GP/QTP Automation: Overcoming VBScript limitation with Excel macros"
I have read a few excellent stuff here. Certainly value bookmarking for revisiting.
I wonder how a lot effort you set to create this type of wonderful informative website.
Magnificient post, very informative.