Discussions related to Visual Prolog
Peter Muraya
VIP Member
Posts: 147
Joined: 5 Dec 2012 7:29

COM exception: Member not found

Unread post by Peter Muraya »

Hi,
I'm trying to use Excel 2013 COM to access data in a data management product that is being developed in Visual Prolog 7.4 (VP). At some point I need to step through all the worksheets in an opened workbook for further processing. It is the first time I'm trying to use COM in VP. Everything in my code works fine until I get to the following statement...

Code: Select all

Outputs2 = Worksheets:invokeMethodWithOutput("item", [comdomains::in(comDomains::integer(I))]),  
... when the "Member not found" exception occurs.
I have looked for help without much success. Any help?
Here is part of the source code and the details of the exception.
Thanks.

Code: Select all

predicates     onFileOpen : window::menuItemListener. clauses     onFileOpen(_Source, _MenuTag):-          /*          Component class id for Microsoft Excel 2013*/          CLSID = core::nativeGuid(0x00024500, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46),          /*          Interface id for the Appliation interface*/          IID = core::nativeGuid(0x000208D5, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46),          /*          Create the application instance*/          Iunknown = comCreation::createInstance(CLSID, IID),          /*          The returned iUnknown interface supports the iDispatch interface, so it is save to do the conversion*/          Iapplication = uncheckedConvert(iDispatch, IUnknown),          /*          The hard way of getting/setting properties and evoking methods directly through the iDispatch interface is          simplified by the ComDispInterface as it allows us to use methods such as get/set properties more          naturally as well as invoking methods.  Let Application be the comDispatch interface*/          Application = comDispInterface::new(Iapplication),          /*          Query the Application idispatch inyerface for the interface named workbooks*/          Application:getProperty("workbooks", comDomains::iDispatch(Iworkbooks)),          /*          Show the Excel application*/          Application:setProperty("visible", comdomains::boolean(true)),          /*          Let Workbooks be the comDispatch interface that supports inherits from Iworkbbook*/          Workbooks = comDispInterface::new(Iworkbooks),          /*          Set the path of the Execl data file to open*/          Path = @"C:\Mutall project\Mutall foundation classes\applications\samples\1 No xpollinnation\CT1-SIDADA-MC.xlsm",          /*          Open the data file*/          Outputs1=Workbooks:invokeMethodWithOutput("open", [comdomains::in(comDomains::string(Path))]),          /*          Retrieve the first output as the worksheets collection item (as there can be more than          one output) from the invoke-with-output method*/          WorkbookVariant = list::nth(0, Outputs1),          /*          The workbbok variant must of the idispatch type; the idispatch interface is that of the worksheet*/          WorkbookVariant == comdomains::idispatch(Iworkbook),          /*          Simplify the idispatch interface of the item into a worksheet*/          Workbook = comdispinterface::new(Iworkbook),          /*           Query the workbook's interface for the worksheets property*/           Workbook:getProperty("worksheets", comDomains::iDispatch(Iworksheets)),           Worksheets = comDispInterface::new(Iworksheets),           /*           Get the number of sheets in in worksheets collection*/           Worksheets:getProperty("count", comDomains::integer(Count)),           /*           Loop throug all the worksheets*/           foreach std::fromto(1, Count)=I do                 /*                 Get the i'th worksheet interface ...........THIS IS WHERE THE EXCEPTION OCCURS.......*/                 Outputs2 = Worksheets:invokeMethodWithOutput("item", [comdomains::in(comDomains::integer(I))]),                 /*                 Retrieve the first output as the worksheets collection item (as there can be more than                 one output) from the invoke-with-output method*/                 Item = list::nth(0, Outputs2),                 /*                 The item variant must of the idispatch type; the idispatch interface is that of the worksheet*/                 Item == comdomains::idispatch(Iworksheet),                 /*                 Simplify the idispatch interface of the item into a worksheet*/                 Worksheet = comdispinterface::new(Iworksheet),                 /*                 Get the name of the worksheet*/                 Worksheet:getProperty("name", comDomains::string(WorksheetName)),                 note(Worksheetname)           end foreach.
Exception

  • ========================================
    Dump: 2014-11-28 14:16:46
    ----------------------------------------
    Exception: disp_e_membernotfound_exception (exceptionHandling_exception)

    Member not found

    Predicate name = invoke
    HRESULT code = 2147614723
    HRESULT hex code = 80020003
    hresultDescription = Member not found
    Source of the exception =
    ErrorDescription =
    Native Error Code = 0
    Native Scode = 0

    raised() 2014-11-28 14:16:42
    ThreadId: 204
    Class name: comDispInterface
    Predicate name: invoke


    c:\program files (x86)\visual prolog 7.4\pfc\exception\exception.pro(229)
    c:\Mutall project\dispatch\Exe\vip7kernel.dll (0x14008A27)
    c:\program files (x86)\visual prolog 7.4\pfc\exception\exception.pro(229)
    c:\program files (x86)\visual prolog 7.4\pfc\com\exceptionhandling\comexceptioncheck.pro(712)
    c:\program files (x86)\visual prolog 7.4\pfc\com\exceptionhandling\comexceptioncheck.pro(648)
    c:\program files (x86)\visual prolog 7.4\pfc\com\exceptionhandling\comexceptioncheck.pro(630)
    c:\program files (x86)\visual prolog 7.4\pfc\com\comsupport\comdispinterface.pro(165)
    taskwindow\taskwindow.pro(141)
    c:\program files (x86)\visual prolog 7.4\pfc\gui\window.pro(1016)
    c:\program files (x86)\visual prolog 7.4\pfc\gui\window.pro(1431)
    c:\program files (x86)\visual prolog 7.4\pfc\gui\drawwindow.pro(460)
    c:\program files (x86)\visual prolog 7.4\pfc\gui\documentwindow.pro(283)
    c:\Mutall project\dispatch\Exe\vip7kernel.dll (0x14008D75)
    c:\Mutall project\dispatch\Exe\vip7vpi.dll (0x15320023)
    c:\Mutall project\dispatch\Exe\vip7vpi.dll (0x15316862)
    c:\Mutall project\dispatch\Exe\vip7vpi.dll (0x15315471)
    c:\Mutall project\dispatch\Exe\vip7vpi.dll (0x1531D91B)
    C:\Windows\SYSTEM32\USER32.dll (0x769C775E)
    C:\Windows\SYSTEM32\USER32.dll (0x769C8C2A)
    C:\Windows\SYSTEM32\USER32.dll (0x769C84E5)
    C:\Windows\SYSTEM32\USER32.dll (0x769C93D1)
    c:\Mutall project\dispatch\Exe\vip7vpi.dll (0x1531B276)
    c:\program files (x86)\visual prolog 7.4\pfc\vpi\vpi.pro(23)
    c:\program files (x86)\visual prolog 7.4\pfc\application\exe\mainexe.pro(22)
    main.pro(17)
    c:\Mutall project\dispatch\Exe\vip7kernel.dll (0x14008DCC)
    c:\Mutall project\dispatch\Exe\vip7kernel.dll (0x1400903C)
    c:\Mutall project\dispatch\Exe\dispatch.exe (0x004F60FC)
    C:\Windows\SYSTEM32\ntdll.dll (0x77788F8B)
    C:\Windows\SYSTEM32\ntdll.dll (0x77788F61)

    ----------------------------------------
    OS information:

    Windows 8 64-bit (Build 9200)
    Number Of Processors: 8 PageSize: 4096 Processor: 8664 level: 6 revision: 10759
    ProcessorNameString: Intel(R) Core(TM) i7-2630QM CPU @ 2.00GHz
    VendorIdentifier: GenuineIntel
    Identifier: Intel64 Family 6 Model 42 Stepping 7
    ~MHz: 1995
Mutall Data Management Technical Support
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls »

The problem is that the "Item" is a property, even though it takes an argument. It is an indexed property.

The comDispInterface does not have support for indexed properties (I have not really been aware of their existence before now).
Regards Thomas Linder Puls
PDC
Peter Muraya
VIP Member
Posts: 147
Joined: 5 Dec 2012 7:29

Unread post by Peter Muraya »

Thank you Thomas for pointing me in the direction of indexed properties. I have now solved the problem by adding a new method to the comDispnterface that is declared as follows:-

Code: Select all

getIndexedProperty : (string Name, integer Index)->comDomains::variant Output.
I implemented it using the following clause:-

Code: Select all

/*    Returns an indexed property*/    getIndexedProperty(Name, Index)=Variant:-          /*          Get the disp id of the property*/          DispId = comDispInterface::getDispId(Name),          /*          Allocate memory for the output*/          OutComVariant = variant::allocateComVariant(),          /*          Formulate the input parameter*/          InVariant = comDomains::integer(Index),          /*          Convert to a com variat*/          InComVariant = variant::toCOMVariant(InVariant),            DispParams = comDomains::comDispParams(uncheckedConvert(pointer, InComVariant), ::null, 1, 0),          /*          Invoke the indexed item property*/          invoke(DispId, com_native::dispatch_propertyGet, DispParams, OutComVariant),           /*           Get the output variant*/           Variant = variant::toVariantAndClear(OutComVariant, comMemory::release()).
Mutall Data Management Technical Support
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls »

Excelent. We will add the predicate to the official version. And then we should also add generated support for it.
Regards Thomas Linder Puls
PDC
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls »

The getIndexedProperty predicate has been added to Visual Prolog 7.5 Build 7501.

Select Web -> Check for Updates in the IDE to updated to the latest version.
Regards Thomas Linder Puls
PDC
User avatar
Tonton Luc
VIP Member
Posts: 204
Joined: 16 Oct 2001 23:01

Unread post by Tonton Luc »

Hi,

What is the VP 7.3 corresponding syntaxe of the following code ?

Code: Select all

DispId = comDispInterface::getDispId(Name),
Post Reply