none
Excel: Angeklickte Zelle identifizieren RRS feed

  • Frage

  • Hallo *,

    ich programiere in C++. Nachdem eine Excel Zelle vom Benutzer
    angeklickt wurde, muß ich sie identifizieren. Ich bekomme das Event
    "SheetSelectionChange" und habe anschließend den nachstehenden Code
    implementiert:

    XL::Range range;
    LPDISPATCH lpActiveCell;
    VARIANT varRow,varCol,varExternal,varRelativeTo,varValue;
    lpActiveCell=appExcel.GetActiveCell();
    range.AttachDispatch(lpActiveCell);

    Wie kann ich die Koordinaten (z.B. D12) aus dem range-Objekt
    ausleden?

    Danke,
    Vaclav
    ---



    Access
    Mittwoch, 15. Dezember 2010 08:15

Antworten

  • Die Lösung:

    HRESULT _stdcall CMyEventDispatch::Invoke(
          DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
          DISPPARAMS *pDispParams, VARIANT *pVarResult,
          EXCEPINFO *pExcepInfo, UINT *puArgErr)
    {
       char *ptr = "Unknown-Event";
       try {
         switch(dispIdMember) {
     case 0x616: { ptr = "SheetSelectionChange";
       XL::Range range;
       LPDISPATCH pActiveCell = appExcel.GetActiveCell();
       range.AttachDispatch(pActiveCell);
       //
       long lZeile = range.GetRow();
       long lSpalte = range.GetColumn();
       range.ReleaseDispatch();
       break;
      }

    Václav


    Access
    Freitag, 17. Dezember 2010 13:11

Alle Antworten

  • IMHO hat Active Cell die Properties Row und Column.

    Ich würde Dir raten das nicht über LPDISPTACH zu machen sondern entsprechende Smart-Pointer zu benutzen.
    Da Du appExcel ja schon verwendest ist dies vermutlich schon eine Klasse, die durch einen #import definiert wurde.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Mittwoch, 15. Dezember 2010 11:35
    Moderator
  • Hallo Martin,

    deinem Rat folgend:

    HRESULT _stdcall CMyEventDispatch::Invoke(
          DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
          DISPPARAMS *pDispParams, VARIANT *pVarResult,
          EXCEPINFO *pExcepInfo, UINT *puArgErr)
    {
      try {
       switch(dispIdMember) {
     case 0x616: { ptr = "SheetSelectionChange"; 
             LPDISPATCH pRange; COleVariant varCell1,varCell2;
             CString   sName;
             sName=m_xlMyWorksheet.GetName();  //<--- Alles OK
             pRange=m_xlMyWorksheet.GetRange(varCell1,varCell2); //<--- COleException 0
    ...

    ...

    }

    hänge ich nun bei der fetten Programmzeile. Das Objekt "m_xlMyWorksheet" ist garantiert intakt.

    Hättest du noch einen Tipp für mich?

    Danke, Václav


    Access
    Donnerstag, 16. Dezember 2010 09:32
  • Und was sagt die Exception?
    Du kannst ReportError aufrufen und bekommst genau gesagt was faul ist.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Donnerstag, 16. Dezember 2010 10:26
    Moderator
  • Ich korrigiere mich: Es ist eine COleDispatchException = 0.

    ReportError zeigt nur eine leere MessageBox mit dem Ausrufezeichen und der OK-Schaltfläche.

    Václav


    Access
    Donnerstag, 16. Dezember 2010 13:54
  • Die Lösung:

    HRESULT _stdcall CMyEventDispatch::Invoke(
          DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
          DISPPARAMS *pDispParams, VARIANT *pVarResult,
          EXCEPINFO *pExcepInfo, UINT *puArgErr)
    {
       char *ptr = "Unknown-Event";
       try {
         switch(dispIdMember) {
     case 0x616: { ptr = "SheetSelectionChange";
       XL::Range range;
       LPDISPATCH pActiveCell = appExcel.GetActiveCell();
       range.AttachDispatch(pActiveCell);
       //
       long lZeile = range.GetRow();
       long lSpalte = range.GetColumn();
       range.ReleaseDispatch();
       break;
      }

    Václav


    Access
    Freitag, 17. Dezember 2010 13:11
  •     LPDISPATCH pActiveCell = appExcel.GetActiveCell();
        range.AttachDispatch(pActiveCell);
        //
        long lZeile = range.GetRow();
        long lSpalte = range.GetColumn();
        range.ReleaseDispatch();
        break;

    Du bekommst durch GetActiveCell ein temporäres Objekt zurück und meines Erachtens keinen LPDISPATCH Zeiger. Wenn dem so ist, wird der LPDISPATCH Zeiger sofort wieder frei gegeben...
    Oder irre ich mich?

    Was ist appExcel für ein Objekt?
    Wie hast Du die Typelib von Excel bei Dir integriert?


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Montag, 20. Dezember 2010 11:58
    Moderator