A question to COMate experts
A question to COMate experts
Hello!
Could you please advise how to read properties from an COMate Enumeration object?
This COMate object doesn't support GetString/Integer etc. methods but in my case, besides the collection itself it returns a number of elements and other useful properties.
Of course I can create two objects with CreateEnumeration() and GetObjectProperty() but it triggers 2x same queries to the DB which is not good
Could you please advise how to read properties from an COMate Enumeration object?
This COMate object doesn't support GetString/Integer etc. methods but in my case, besides the collection itself it returns a number of elements and other useful properties.
Of course I can create two objects with CreateEnumeration() and GetObjectProperty() but it triggers 2x same queries to the DB which is not good
Re: A question to COMate experts
Yes COMate destroys the temporary object it creates whilst getting hold of the relevant Enum interface pointer in the COMateClass_CreateEnumeration() procedure. You are thus correct in thinking that you would need to create 2 separate objects in your case in order to make use of any additional properties etc.
You can easily modify the above procedure to, say, not destroy the temporary object and instead place it in a separate buffer so that you can make use of it separately. Just make sure you destroy that object when you are done with it using the COMate \Release() method. Alternatively, create a bespoke version of the COMateClass_CreateEnumeration() procedure just for your use.
You can easily modify the above procedure to, say, not destroy the temporary object and instead place it in a separate buffer so that you can make use of it separately. Just make sure you destroy that object when you are done with it using the COMate \Release() method. Alternatively, create a bespoke version of the COMateClass_CreateEnumeration() procedure just for your use.
I may look like a mule, but I'm not a complete ass.
Re: A question to COMate experts
Hello srod,
Thank you for your explanation!
Just checked the COMate code and I think I found the temp object destroyer
but there are too many asterisks for my programming level so I'm not sure how to modify it to return 2x objects and not to spoil anything else
(through a structure?)
Thank you for your explanation!
Just checked the COMate code and I think I found the temp object destroyer
Code: Select all
If command$
COMateClass_Release(*tempCOMateObject)
EndIf

Re: A question to COMate experts
Struggling for time right now to do anything with this. I'll sort something out as soon as I can. In the meantime just use the two separate objects.
I may look like a mule, but I'm not a complete ass.
Re: A question to COMate experts
Thank you in advance!
Re: A question to COMate experts
Hang on a cotton picking minute! COMatePLUS will already do what you are after - doh!
If you invoke the \CreateEnumeration() method with an empty string as a parameter then it will simply return the enumeration object associated with the underlying object!
So taking some code from one of the COMate demo programs, instead of the following :
We can use the following instead :
This second version gives you access to the original 'NodesObject' and the enumeration object 'DomENUMObject' without any additional (and repeated) object creation (well no more than would be the case under the first snippet above). Tested and works fine with the above demo program.
Wonder why this didn't end up in the COMatePLUS manual?

If you invoke the \CreateEnumeration() method with an empty string as a parameter then it will simply return the enumeration object associated with the underlying object!
So taking some code from one of the COMate demo programs, instead of the following :
Code: Select all
;Declare COMate objects.
Define.COMateObject DomObject, NodeObject
;Declare COMateEnum objects.
Define.COMateEnumObject DomENUMObject
DomObject = COMate_CreateObject("MSXML.DOMDocument")
If DomObject
DomObject\Invoke("LoadXml('" + XML$ + "')")
;Begin enumeration.
DomENUMObject = DomObject\CreateEnumeration("SelectNodes('addresses/address')")
If DomENUMObject
etc.
Code: Select all
;Declare COMate objects.
Define.COMateObject DomObject, NodesObject, NodeObject
;Declare COMateEnum objects.
Define.COMateEnumObject DomENUMObject
DomObject = COMate_CreateObject("MSXML.DOMDocument")
If DomObject
DomObject\Invoke("LoadXml('" + XML$ + "')")
;Begin enumeration.
NodesObject = DomObject\GetObjectProperty("SelectNodes('addresses/address')")
If NodesObject
DomENUMObject = NodesObject\CreateEnumeration("")
If DomENUMObject
etc.
Wonder why this didn't end up in the COMatePLUS manual?
I may look like a mule, but I'm not a complete ass.
Re: A question to COMate experts
Hi srod!
Thank you so much! It works like a charm!)
May I ask you a couple of other questions regarding COMate?
1- "COM Error [1]: The operation completed, but was only partially successful." during enumeration processing (I filter it out but I wonder why it appears)
2 - When I'm using COMate with Excel with one common event callback procedure + objExcel and objWorkbook objects, as soon as I resize the Excel window (from the program, didn't tried manual resize) any attempt to use objWorkbook causes COMate crash but if I disable events before resize, it works. Can it happens because I need to attach events handling to the Workbook as well?
Thank you so much! It works like a charm!)
May I ask you a couple of other questions regarding COMate?
1- "COM Error [1]: The operation completed, but was only partially successful." during enumeration processing (I filter it out but I wonder why it appears)
2 - When I'm using COMate with Excel with one common event callback procedure + objExcel and objWorkbook objects, as soon as I resize the Excel window (from the program, didn't tried manual resize) any attempt to use objWorkbook causes COMate crash but if I disable events before resize, it works. Can it happens because I need to attach events handling to the Workbook as well?
Re: A question to COMate experts
1. I would need more info.
2. I am not that familiar with the Excel object, but can you post some code for me to look at? Just did some basic tests and it all seemed to work fine.
2. I am not that familiar with the Excel object, but can you post some code for me to look at? Just did some basic tests and it all seemed to work fine.
I may look like a mule, but I'm not a complete ass.
Re: A question to COMate experts
1 - it appears when no more objects in the enumeration left and \GetNextObject() returns zero. I think it shall be silent...
2 - I can't make it working separately.. I don't know why but it stops processing events after workbook is opened and 4 events received
It works normally in my project. I can tell only that everything is forking if I'm operating only with Excel object like
But it doesn't with
2 - I can't make it working separately.. I don't know why but it stops processing events after workbook is opened and 4 events received


It works normally in my project. I can tell only that everything is forking if I'm operating only with Excel object like
Code: Select all
\objExcel\SetProperty( "WindowState ="+ #xlMaximized)
\objExcel\GetStringProperty( "ActiveWorkbook\Name")
\objExcel\GetIntegerProperty( "ActiveWorkbook\Sheets\Count")
Code: Select all
\objExcel\SetProperty( "WindowState ="+ #xlMaximized)
\objWorkbookl\GetStringProperty( "Name")
\objWorkbook\GetIntegerProperty( "Sheets\Count")
Re: A question to COMate experts
Code: Select all
\objExcel\SetProperty( "WindowState ="+ #xlMaximized)
I tested using the "WindowState" property of the "Application" object and it resized the window fine and all events seemed to work fine with no crashes.
I may look like a mule, but I'm not a complete ass.
Re: A question to COMate experts
PB casts them automatically so Str( 100) = ""+ 100
The problem is not in the resizing but what happening with objWorkbook after that if events handling is active.
Can you try this please (but it has a different problem I mentioned earlier)
The problem is not in the resizing but what happening with objWorkbook after that if events handling is active.
Can you try this please (but it has a different problem I mentioned earlier)
Code: Select all
XIncludeFile "\COMatePLUS.pbi"
;--#xlWindowState
#xlMaximized = -4137
#xlMinimized = -4140
#xlNormal = -4143
objExcel.COMateObject
objWorkbook.COMateObject
Declare ComEventCallback( _object.COMateObject, _sEventName.s, _objUnknowneterCount.i, *_result.VARIANT)
objExcel = COMate_CreateObject( "Excel.Application")
If objExcel
objExcel\SetEventHandler( #COMate_CatchAllEvents, @ComEventCallback(), #COMate_OtherReturn)
objExcel\SetProperty( "Visible = #True")
objWorkbook = objExcel\GetObjectProperty( "Workbooks\Open('C:.............................') = #True")
If objWorkbook
Debug objWorkbook\GetStringProperty( "Name")
Debug objExcel\GetStringProperty( "ActiveWorkbook\Name")
objExcel\SetProperty( "WindowState ="+ #xlMaximized)
Debug objWorkbook\GetStringProperty( "Name") ;<<<< COMate crashes here
Debug objExcel\GetStringProperty( "ActiveWorkbook\Name") ;<<<< this one will work If above is commented
EndIf
Repeat
Until objExcel = 0
EndIf
End
Procedure ComEventCallback( _object.COMateObject, _sEventName.s, _objUnknowneterCount.i, *_result.VARIANT)
Shared objExcel
Debug "Event: < "+ _sEventName +" > Params: "+ _objUnknowneterCount
Select _sEventName
Case "WorkbookBeforeClose"
objExcel\SetEventHandler( #COMate_CatchAllEvents, #Null, #COMate_OtherReturn)
objExcel\Release()
EndSelect
EndProcedure
Re: A question to COMate experts
You have an infinite loop running hogging all the program time! Remove that (stick a message requester in there) and it all runs fine here.
I may look like a mule, but I'm not a complete ass.
Re: A question to COMate experts
Yep... I tried to use Delay() there but it seems it doesn't release CPU and WaitWindowEvent( xx) doesn't work without window :/
With the messagebox it works and has no crashes so I need to look into my code, thank you!
Another question: is it possible to clear the COMate error code after it was processed and what is the bestest way to realise "OnError" for COMate?
With the messagebox it works and has no crashes so I need to look into my code, thank you!
Another question: is it possible to clear the COMate error code after it was processed and what is the bestest way to realise "OnError" for COMate?
Re: A question to COMate experts
Hello Stephen,
hope u r fine, and thank you for your presence !
I add some remarks, but it s imho : can be corrected.
@Yuri hello first,
1)Normally, it seems to work fine. Give details of the argument (milliseconds) of your Delay() invoking. But normally 100 ms is good.
2) WaitWindowEvent() requires a window : all right, and it is not a problem. A window can be invisible by setting its flag during its opening, or by sizing (or resizing) to a null dimension, or by moving to an extraneous position. The first of these 3 ways seems to be the best way.
3) You declare objExcel. All right, but declare it globalllyAnd, if you do not like global var, what it could be normal sometimes... No reason to sing nake everytime... In this way, you have to insure by inserting a shared directive in every procedure which uses such a variable, obviously, in your example, in the callback procedure. Actually neither Global, neither Shared : Sure there is a problem.
Also I wish you a good pleasure to use Comate. I used it only once, 9 years ago but appreciate a lot this feature added by SRod.
hope u r fine, and thank you for your presence !
I add some remarks, but it s imho : can be corrected.
@Yuri hello first,
1)
Code: Select all
Repeat
Delay(100)
Until objExcel
2) WaitWindowEvent() requires a window : all right, and it is not a problem. A window can be invisible by setting its flag during its opening, or by sizing (or resizing) to a null dimension, or by moving to an extraneous position. The first of these 3 ways seems to be the best way.
3) You declare objExcel. All right, but declare it globallly
Code: Select all
Global objExcel.TaratataMagic
Also I wish you a good pleasure to use Comate. I used it only once, 9 years ago but appreciate a lot this feature added by SRod.
Re: A question to COMate experts
Hello community!
Once again your help wanted, could you please help?
There are few VBA methods which can do a single or batch data manipulation.
I know how to perform single opertations
VBA usage (single):
but I don't understand how to create an array of objects and to feed it to these methods to perform batch operations
VBA usage (batch):
I think I shall create a safearray of objects but how to do it - no ideas(
If somebody knows, please explain.
Once again your help wanted, could you please help?
There are few VBA methods which can do a single or batch data manipulation.
Code: Select all
Create(DObject[], async As Boolean)
Delete(DObject[], async As Boolean)
......
VBA usage (single):
Code: Select all
Dim user As DObject >>>>>>>>>>>>>>>>>>>>>>> Define.COMateObject objUser
Set user = Api.CreateObject("user") >>>>>>>>>>>> objUser = objAPI\GetObjectProperty( "CreateObject('user')")
user("name") = "Test0" >>>>>>>>>>>>>>>>>>>>>> objUser\SetProperty( "Item('Name')\Value = 'Test0'")
user.Create() >>>>>>>>>>>>>>>>>>>>>>>>>>>>> objUser\Invoke("Create")
VBA usage (batch):
Code: Select all
Dim users(2) As DObject >>>>>>>>>>>>>>>>>>>>>>>> ???
Set users(0) = dApi.CreateObject("user") >>>>>>>>>>>> ??? = objAPI\GetObjectProperty( "CreateObject('user')")
users(0)("name") = "Test0" >>>>>>>>>>>>>>>>>>>>>> ???\SetProperty( "Item('Name')\Value = 'Test0'")
Set users(1) = dApi.CreateObject("user") >>>>>>>>>>>> ??? = objAPI\GetObjectProperty( "CreateObject('user')")
users(1)("name") = "Test1" >>>>>>>>>>>>>>>>>>>>>> ???\SetProperty( "Item('Name')\Value = 'Test1'")
'call batch method
dApi.Create users, False >>>>>>>>>>>>>>>>>>>>>>>> objAPI\Invoke("Create ????, #False")
If somebody knows, please explain.