_variant_t eigentlichen Typ bei VT_DISPTACH rausfinden



  • Ich bekomme _variant_t Objekte und dahinter verbergen sich in der regel long, int und double Werte, mitunter aber auch Strings.

    Wenn ich nun aber mit V_VT(x) versuche den Typ rauszufinden ist es immer eine VT_DISPATCH. Wie "dispatche" ich diesen denn am besten um rauszufinden was wirklich dahinter steckt?



  • WOHER bekommst Du denn diese Objekte? Da solltest Du mal dort im Handbuch nachschauen.... Du kannst nat├╝rlich auch "GetTypeInfo" aufrufen um zu ermitteln, was Du alles mit dem Objekt machen kannst... aber dazu ist es wohl einfacher Du verwendest eine Skript-Sprache um das zu testen...



  • Die Werte kommen aus der COM Schnittstelle von Excel direkt aus einem .xls File (Aus einem Range Objekt).
    Die Schnittstelle ist zumindest in bezug auf C++ eher schlecht dokumentiert, aber dieser IDispatch Typ schien mir ein allgemeines COM Konzept zu sein - nur werd ich aus der Doku nicht schlau wie ich das ding nun Dispatche ­čśë

    Ich kann den _variant_t auch ohne Probleme z.B. zu einem double casten wenn der Typ zwar IDispatch ist aber sich dahinter zumindest eine Zahl verbirgt. Nur mir bliebe dann nichts anderes ├╝ber als per try + catch Fehler abzufangen wenn es halt mal keine Zahl ist - w├╝rde das gerne vorher schon feststellen. Au├čerdem w├Ąre es ganz praktisch diesen IDispatch quatsch mal zu verstehen ­čśë



  • Du kannst da nix casten!

    F├╝r ein Beispiel siehe hier:
    http://www.a-m-i.de/tips/office/officeautomation.php#cppexample_Excel


  • Mod

    Ein Range liefert eben ein IDispatch Objekt, das auch ein Value Property hat.
    Das m├╝sste Dir dann den Wert liefern.

    Ansonsten zeige auns was Du wi emachst...



  • /*ref existiert halt einfach mal...*/
    Excel::_Worksheet* pWorksheet = (Excel::_Worksheet*)ref;
    Excel::RangePtr pRange = pWorksheet->GetCells();
    _variant_t var = pRange->GetItem(row, col);
    

    Es scheint jetzt immer folgendes zu gelten:

    V_VT(&var) == VT_DISPATCH
    

    und halt nicht wie im "Beispiel":

    vResult.vt == VT_I4 oder vResult.vt == VT_R4
    

    Das funktioniert trotzdem solange sich hinter dem Dispatch halt eine Zahl verbirgt:

    double foo = var;
    

    Mir ist jetzt nicht klar wie ich "GetTypeInfo" ├╝berhaupt bedienen m├╝sste und von einem Value Property seh ich auch nirgends was ...



  • Versuchs mal mit

    _variant_t var = pRange->GetItem(row, col)->Value;
    

    Dass es ohne ->Value auch geht, liegt daran dass Value die "Default-Property" des Interface ist. Und da du anscheinend #import verwendest, erstellt MSVC entsprechend schlaue Wrapper-Klassen, die eine direkte Konvertierung erlauben.

    (Die Property muss nicht immer Value heissen, ist aber ein sehr ├╝blicher Name)



  • pRange->GetItem(row, col)
    

    Liefert schon den _variant_t und der unterst├╝tzt ->Value nicht.

    Range unterst├╝tzt allerdings:

    _declspec(property(get=GetValue,put=PutValue))
       _variant_t Value[];
    
    _variant_t GetValue (
        const _variant_t & RangeValueDataType = vtMissing );
    

    Muss nochmal gucken wie das funzt und ob die _variant_t dann einen anderen Type haben...

    Edit: Wenn man ├╝ber die GetValue Methode geht dann werden die "richtigen" Types angezeigt (wie VT_I4 und nicht mehr VT_IDISPATCH). Man muss dann nur vorher die Range auf ein Element eingrenzen - will man direkt ├╝ber Cells gehen funktioniert auch sowas (wie ich vorher schon erw├Ąhnte):

    /*methode die typ x zur├╝ck gibt...*/
    try {
    	return var;
    } catch(_com_error & error) {
    	return /*wenn's nicht funzt dann eben irgend nen standard wert*/;
    }
    

    Ansonsten muss man wohl IDispatch einfach mal IDispatch sein lassen ...


Log in to reply