Forum Discussion

nyczmagix's avatar
nyczmagix
Occasional Contributor
14 years ago

Table Environment Variable via COM

Hello,



I'm having a problem casting a table environment variable to it's correct type. I'm currently controlling TestComplete via COM and doing the following on the .NET (C#) side:



var proj = IntegrationObject.GetObjectByName("Project");

var tableVars = proj.Variables;

ItcTableVariable Table1 = (ItcTableVariable)tableVars.VariableByName("TheTableVariable")



After casting Table1 to ItcTableVariable, I got the following exception:



+  $exception {"Unable to cast COM object of type 'System.__ComObject' to interface type 'TestComplete.ItcTableVariable'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{1615C685-B588-40CB-8AAA-E4D74C963B59}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE))."} System.Exception {System.InvalidCastException}



I presume I'm going to hit the same problem casting to an ItcTableVariableIterator as well (which is what my next step would be).



Please advise. Thanks.



1 Reply

  • I'm afraid, the ItcTableVariable interface is currently COM-incompatible, so you can't cast to it. You'll need to use a generic object-type variable for a table variable and access its properties and methods using reflection. Casting the Iterator property value to ItcTableVariableIterator should work fine though. Here's an example:



    using System.Reflection;

    ...



    object Table1 = tableVars["TheTableVariable"];



    // Get the row and column count

    int rowCount = (int) Table1.GetType().InvokeMember("RowCount", BindingFlags.GetProperty, null, Table1, null);

    int colCount = (int) Table1.GetType().InvokeMember("ColumnCount", BindingFlags.GetProperty, null, Table1, null);

    Console.WriteLine("Rows: {0}; columns: {1}", rowCount, colCount);



    // Get the table iterator

    ItcTableVariableIterator iterator = (ItcTableVariableIterator) Table1.GetType().InvokeMember("Iterator", BindingFlags.GetProperty, null, Table1, null);

    while (!iterator.IsEOF())

    {

      // Do something

      iterator.Next();

    }





    Or, if you use C# 4, you can use dynamic late binding. Something along the lines of:



    dynamic Table1 = tableVars["TheTableVariable"];



    var iterator = Table1.Iterator;

    // -- or --

    // ItcTableVariableIterator iterator = (ItcTableVariableIterator) Table1.Iterator;