Microsoft KB Archive/165967: Difference between revisions

From BetaArchive Wiki
(importing KB archive)
 
m (Text replacement - "&" to "&")
 
(3 intermediate revisions by the same user not shown)
Line 53: Line 53:
<div class="errormessage">
<div class="errormessage">


&quot;Object doesn't support this property or method '&lt;object&gt;.&lt;method&gt;'&quot;
"Object doesn't support this property or method '<object>.<method>'"


</div>
</div>
Line 73: Line 73:
To 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.<br />
To 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.<br />
<br />
<br />
Scripts written in VBSCRIPT should use the TypeName function to check the data type of a variable. The TypeName function returns the string &quot;Variant(),&quot; excluding the quotes, when passed an array of VARIANTs.<br />
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.<br />
<br />
<br />
Scripts written in JSCRIPT should use the typeof operator to test the data type of a variable. The typeof operator returns the string &quot;unknown,&quot; excluding the quotes for datatypes unsupported by JSCRIPT.
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.


</div>
</div>
Line 114: Line 114:


         VARIANT vFlavors[3];
         VARIANT vFlavors[3];
         for (i = 0; i &lt; 3; i++)
         for (i = 0; i < 3; i++)
         {
         {
             VariantInit(&amp;vFlavors[i]);
             VariantInit(&vFlavors[i]);
             V_VT(&amp;vFlavors[i]) = VT_BSTR;
             V_VT(&vFlavors[i]) = VT_BSTR;
         }
         }


         V_BSTR(&amp;vFlavors[0]) = SysAllocString(OLESTR(&quot;Vanilla&quot;));
         V_BSTR(&vFlavors[0]) = SysAllocString(OLESTR("Vanilla"));
         V_BSTR(&amp;vFlavors[1]) = SysAllocString(OLESTR(&quot;Chocolate&quot;));
         V_BSTR(&vFlavors[1]) = SysAllocString(OLESTR("Chocolate"));
         V_BSTR(&amp;vFlavors[2]) = SysAllocString(OLESTR(&quot;Espresso Chip&quot;));
         V_BSTR(&vFlavors[2]) = SysAllocString(OLESTR("Espresso Chip"));
         if (!V_BSTR(&amp;vFlavors[0]) || !V_BSTR(&amp;vFlavors[1]) ||
         if (!V_BSTR(&vFlavors[0]) || !V_BSTR(&vFlavors[1]) ||
             !V_BSTR(&amp;vFlavors[2]))
             !V_BSTR(&vFlavors[2]))
         {
         {
             hr = E_OUTOFMEMORY;
             hr = E_OUTOFMEMORY;
Line 133: Line 133:
                 //Plug references to the data into the SAFEARRAY
                 //Plug references to the data into the SAFEARRAY
               LPVARIANT rgElems;
               LPVARIANT rgElems;
               if (FAILED(hr = SafeArrayAccessData(psa,(LPVOID*)&amp;rgElems)))
               if (FAILED(hr = SafeArrayAccessData(psa,(LPVOID*)&rgElems)))


             {
             {
               goto Error;
               goto Error;
             }
             }
             for (i = 0; i &lt; 3; i++)
             for (i = 0; i < 3; i++)
             {
             {
               rgElems[i] = vFlavors[i];
               rgElems[i] = vFlavors[i];
Line 151: Line 151:


   Error:
   Error:
         for (i = 0; i &lt; 3; i++)
         for (i = 0; i < 3; i++)
         {
         {
             if (V_BSTR(&amp;vFlavors[i])
             if (V_BSTR(&vFlavors[i])
             {
             {
               VariantClear(&amp;vFlavors[i]);
               VariantClear(&vFlavors[i]);
             }
             }
         }
         }
Line 162: Line 162:
                 </pre>
                 </pre>
Here is the JSCRIPT code from VBSARRAY.HTM, the test page included with the sample, that checks the datatype of a variable:
Here is the JSCRIPT code from VBSARRAY.HTM, the test page included with the sample, that checks the datatype of a variable:
<pre class="codesample">      &lt;SCRIPT LANGUAGE=JSCRIPT&gt;
<pre class="codesample">      <SCRIPT LANGUAGE=JSCRIPT>
       function JScriptSafeArrayTest()
       function JScriptSafeArrayTest()
       {
       {
         pvaBstr = SimpleComponent.TestBstrs()
         pvaBstr = SimpleComponent.TestBstrs()
         if (typeof(pvaBstr) == &quot;unknown&quot;)
         if (typeof(pvaBstr) == "unknown")
         {
         {
             Alert(&quot;JSCRIPT cannot handle the type returned by TestBstrs()&quot;)
             Alert("JSCRIPT cannot handle the type returned by TestBstrs()")
             SimpleComponent.TestPassedArray(pvaBstr)
             SimpleComponent.TestPassedArray(pvaBstr)
         }
         }


         pvaVariant = SimpleComponent.TestVariants()
         pvaVariant = SimpleComponent.TestVariants()
         if (typeof(pvaVariant) == &quot;unknown&quot;)
         if (typeof(pvaVariant) == "unknown")
         {
         {
         Alert(&quot;JSCRIPT cannot handle the type returned by TestVariants()&quot;)
         Alert("JSCRIPT cannot handle the type returned by TestVariants()")
             SimpleComponent.TestPassedArray(pvaVariant)
             SimpleComponent.TestPassedArray(pvaVariant)
         }
         }
       }
       }
       &lt;/SCRIPT&gt;
       </SCRIPT>
                 </pre>
                 </pre>
To demonstrate the problem and the solution, perform the following steps:<br />
To demonstrate the problem and the solution, perform the following steps:<br />

Latest revision as of 12:29, 21 July 2020

Article ID: 165967

Article Last Modified on 8/5/2004



APPLIES TO

  • Microsoft Visual Basic, Scripting Edition 1.1
  • Microsoft Visual Basic, Scripting Edition 2.0
  • Microsoft Visual Basic, Scripting Edition 3.0
  • Microsoft JScript 1.0
  • Microsoft JScript 2.0
  • Microsoft Internet Explorer 4.0 128-Bit Edition
  • Microsoft Active Server Pages 4.0



This article was previously published under Q165967

SYMPTOMS

When 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>'"

CAUSE

The 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.

RESOLUTION

To 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.

STATUS

This behavior is by design.

MORE INFORMATION

The 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:

  1. Follow the instructions below on obtaining the sample component VBSARRAY.DLL and sample page VBSARRAY.HTM.
  2. Register the component VBSARRAY.DLL using a tool such as REGSVR32.EXE.
  3. Launch Internet Explorer, and load the test page VBSARRAY.HTM.
  4. Follow the instructions on the page, clicking the various buttons and observing the resulting behavior.

The sample component was created using the Active Template Library version 2.1 including with Visual C++ 5.0 in the Visual Studio 97 environment. If you have Visual Studio 97, you can load the VBSARRAY project directly. Otherwise, you can open the relevant source file VBSA.CPP in any editor to see how the SAFEARRAY is constructed in both the VARIANT and the BSTR cases. Search for the implementation of both Cvbsa::TestVariants and Cvbsa::TestBstrs in the source file.

The following files are available for download from the Microsoft Download Center:

For additional information about how to download Microsoft Support files, click the following article number to view the article in the Microsoft Knowledge Base:

119591 How to Obtain Microsoft Support Files from Online Services


Microsoft scanned this file for viruses. Microsoft used the most current virus-detection software that was available on the date that the file was posted. The file is stored on security-enhanced servers that help to prevent any unauthorized changes to the file.

REFERENCES

Platform SDK Automation Reference

Microsoft Visual Basic Scripting Edition Language Reference

Keywords: kbdownload kbfile kbprb kbsample KB165967