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


Anmelden zum Antworten