PRB: Script Error Occurs When Referencing Non-variant ArrayLast reviewed: September 29, 1997Article ID: Q165967 |
The information in this article applies to:
SYMPTOMSWhen a script attempts to reference the elements of an array returned by a component, the script engine reports:
"Object doesn't support this property or method '<object>.<method>'" CAUSEThe VBSCRIPT active scripting engine supplied by Microsoft only supports the indexing of SAFEARRAYs of VARIANTs. While VBSCRIPT is capable of accepting arrays of non-variant type for the purposes of boundary checking and passing it to other automation objects, the engine does not allow manipulation of the array contents at this time. The JSCRIPT active scripting engine does not provide support for testing the bounds or indexing SAFEARRAYs of any type including VARIANTs. However, JSCRIPT is capable of passing SAFEARRAYs from one automation object to another.
RESOLUTIONTo function correctly with applications and components that host VBSCRIPT, automation objects should create SAFEARRAYs of VARIANTs. Non-VARIANT data should be packaged in the VARIANT elements of the SAFEARRAY to be returned to the VBSCRIPT engine. Scripts written in VBSCRIPT should use the TypeName function to check the data type of a variable. The TypeName function returns the string "Variant()," excluding the quotes, when passed an array of VARIANTs. Scripts written in JSCRIPT should use the typeof operator to test the data type of a variable. The typeof operator returns the string "unknown," excluding the quotes for datatypes unsupported by JSCRIPT.
STATUSThis behavior is by design.
MORE INFORMATIONThe VBSARRAY is a simple Active Template Library (ATL) version 2.1 component object that demonstrates this behavior. The component implements a dual interface Ivbsa that supports three methods: TestBstrs, TestVariants, and TestPassArray. The first demonstrates the problem by returning a SAFEARRAY of BSTRs. The second demonstrates the solution by packaging each of the BSTRs in a VARIANT. The third demonstrates that an array of non-VARIANT type can be passed from component to VBSCRIPT or JSCRIPT to component. The data remains intact. Here is the implementation of TestVariants:
// Return a VARIANT array of VARIANTs which hold BSTRs STDMETHODIMP Cvbsa::TestVariants(VARIANT * pvaVariant) { HRESULT hr = NOERROR; LPSAFEARRAY psa; SAFEARRAYBOUND rgsabound[] = { 3, 0 }; // 3 elements, 0-based int i; if (!pvaVariant) { return E_INVALIDARG; } VariantInit(pvaVariant); psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound); if (!psa) { return E_OUTOFMEMORY; } VARIANT vFlavors[3]; for (i = 0; i < 3; i++) { VariantInit(&vFlavors[i]); V_VT(&vFlavors[i]) = VT_BSTR; } V_BSTR(&vFlavors[0]) = SysAllocString(OLESTR("Vanilla")); V_BSTR(&vFlavors[1]) = SysAllocString(OLESTR("Chocolate")); V_BSTR(&vFlavors[2]) = SysAllocString(OLESTR("Espresso Chip")); if (!V_BSTR(&vFlavors[0]) || !V_BSTR(&vFlavors[1]) || !V_BSTR(&vFlavors[2])) { hr = E_OUTOFMEMORY; goto Error; } { //Plug references to the data into the SAFEARRAY LPVARIANT rgElems; if (FAILED(hr = SafeArrayAccessData(psa,(LPVOID*)&rgElems))) { goto Error; } for (i = 0; i < 3; i++) { rgElems[i] = vFlavors[i]; } SafeArrayUnaccessData(psa); } V_VT(pvaVariant) = VT_ARRAY | VT_VARIANT; V_ARRAY(pvaVariant) = psa; return NOERROR; Error: for (i = 0; i < 3; i++) { if (V_BSTR(&vFlavors[i]) { VariantClear(&vFlavors[i]); } } return hr; }Here is the JSCRIPT code from VBSARRAY.HTM, the test page included with the sample, that checks the datatype of a variable: <SCRIPT LANGUAGE=JSCRIPT> function JScriptSafeArrayTest() { pvaBstr = SimpleComponent.TestBstrs() if (typeof(pvaBstr) == "unknown") { Alert("JSCRIPT cannot handle the type returned by TestBstrs()") SimpleComponent.TestPassedArray(pvaBstr) } pvaVariant = SimpleComponent.TestVariants() if (typeof(pvaVariant) == "unknown") { Alert("JSCRIPT cannot handle the type returned by TestVariants()") SimpleComponent.TestPassedArray(pvaVariant) } } </SCRIPT>To demonstrate the problem and the solution, perform the following steps:
The following file is available for download from the Microsoft Software Library:
~ Vbsarray.exe (size: 71069 bytes)For more information about downloading files from the Microsoft Software Library, please see the following article in the Microsoft Knowledge Base:
ARTICLE-ID: Q119591 TITLE : How to Obtain Microsoft Support Files from Online Services REFERENCESPlatform SDK Automation Reference Microsoft Visual Basic Scripting Edition Language Reference Keywords : AXSDKSripting kbsample kbprb Technology : kbAtl kbInetDev Version : Win:1.0,1.1,2.0,3.0 Platform : WINDOWS Issue type : kbprb Solution Type : kbfile |
================================================================================
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |