ahha Posted May 29, 2021 Share Posted May 29, 2021 (edited) I'm new to COM error handling and trying to understand how to pass something back to the routine in which a COM exception/error occurred so the routine can act on it. The example program below shows how it can be done using a Global variable, however when I try and use SetError, which I thought was Global, it fails. Any hints on what I'm doing wrong would be appreciated as I'm stuck. expandcollapse popup; #AutoIt3Wrapper_run_debug_mode=Y ;use this to debug in console window <--- LOOK ;https://www.autoitscript.com/forum/topic/196419-error-handling-help/ ;https://www.autoitscript.com/forum/topic/191401-com-error-handling-in-a-udf-best-practice/ Global $GlobalExceptionFlag = 0 ;init value Global $Test1Flag = 0 ;init value Global $oGlobalCOMException = ObjEvent("AutoIt.Error", "_GlobalCOMException") ;Global Exception ;Global test Pause("Before Global COM Exception" &@CRLF& "$GlobalExceptionFlag = " & $GlobalExceptionFlag) Global $oNonSense = ObjCreate("Nonsense.Application") ;trigger Global Exception Pause("After Global COM Exception" &@CRLF& "$GlobalExceptionFlag = " & $GlobalExceptionFlag) ;Local tests LocalTest_1() ;be careful with use of word Local LocalTest_2() ;be careful with use of word Local Exit ;----------- functions ;----------- Func _GlobalCOMException() $GlobalExceptionFlag = 1 ;set it Pause("IN: _GlobalCOMException()" &@CRLF& "$GlobalExceptionFlag = " & $GlobalExceptionFlag) EndFunc Func LocalTest_1() $oLocal1COMException = ObjEvent("AutoIt.Error", "_Local1COMException") ;Local Exception Pause("We are in LocalTest_1() before local exception" &@CRLF& "$Test1Flag = " & $Test1Flag) $oX1 = ObjCreate("MoreNonsense.Application") ;create exception Pause("We are in LocalTest_1() after local exception" &@CRLF& "$Test1Flag = " & $Test1Flag) EndFunc Func LocalTest_2() ;the problem with LocalTest_1 is that it requires a Global flag in the main program ;which is not a good idea if the functions we are providing are to be used by other ;people - they will not want to put in a Global however that is exactly what we need ;there is a solution as @error is Global for all programs ;so let's try it $oLocal2COMException = ObjEvent("AutoIt.Error", "_Local2COMException") ;Local Exception Pause("We are in LocalTest_2() before local exception" &@CRLF& "@error = " & @error) $oMoreNonSense = ObjCreate("MoreNonsense.Application");create more nonsense $iError = @error ;grab @error as we are getting @error = -2147221005 rather than 23. It makes no difference still get -2147221005 ;Pause("We are in LocalTest_2() after local exception, @error = " & @error) Pause("We are in LocalTest_2() after local exception" &@CRLF& "@error = " & $iError) EndFunc Func _Local1COMException() $Test1Flag = 1 ;set it Pause("IN: _Local1COMException()" &@CRLF& "$Test1Flag = " & $Test1Flag) EndFunc Func _Local2COMException() $Local1ExceptionFlag = 1 ;set it Pause("IN: _Local2COMException()" &@CRLF& "@error = " & @error) SetError(23) ;set it as last entry (Return SetError(23) makes no difference) EndFunc Func Pause($text="") MsgBox(262144, "DEBUG", $text) EndFunc Edited June 1, 2021 by ahha Link to comment Share on other sites More sharing options...
TheXman Posted May 29, 2021 Share Posted May 29, 2021 (edited) 1 hour ago, ahha said: I'm new to COM error handling and trying to understand how to pass something back to the routine in which a COM exception/error occurred so the routine can act on it. Can you be more specific as to what "something" might be and why you need to be able to pass that "something" back to the calling function? Unless you encounter a catastrophic or non-trappable COM error, as long as your local or global COM error handler doesn't exit the script, control/execution will be passed back to the caller. You can just test for @error after any given COM statement and do whatever processing needs to take place. The variable you used to define the local COM error handler (ObjEvent()) will contain the COM error object if an exception occurs. You can use the properties of that error object to see what error has occurred and handle it as necessary. Note that some COM errors cannot be trapped and will cause your script to exit with or without a COM error handler. Luckily, most of those type of errors can be avoided by coding defensively. (See example 2 of the ObjEvent() function, in the help file, for an example of local COM error handling. ) FYI, your locally defined COM error handler function is passed a COM error object. That allows you to be able to interrogate any of the COM error information in the error handler. Of course the information is also available in the calling function as I stated above. Func _Local1COMException($oComError) Edited May 29, 2021 by TheXman CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
TheXman Posted May 29, 2021 Share Posted May 29, 2021 (edited) The example below shows how the error object can be used within the function. Notice that all the COM error handler function does is return control back to the caller so that it can process the error. #AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w- 5 -w 6 -d #include <Constants.au3> example() Func example() Local $oComErr, $oApp ;Define local COM error handler $oComErr = ObjEvent("AutoIt.Error", "com_error_handler") If @error Then Exit MsgBox($MB_ICONERROR + $MB_TOPMOST, "ERROR", "Unable to create COM error handler - @error = " & @error) ;Generate a COM error to show how it can be handled within the function $oApp = ObjCreate("SomeApp.Application") If @error Then With $oComErr ConsoleWrite(@CRLF & "COM ERROR DETECTED!" & @CRLF) ConsoleWrite(" Error ScriptLine....... " & .scriptline & @CRLF) ConsoleWrite(" Error Number........... " & "0x" & Hex(.number) & " (" & .number & ")" & @CRLF) ConsoleWrite(" Error WinDescription... " & StringStripWS(.windescription, $STR_STRIPTRAILING) & @CRLF) ConsoleWrite(" Error Description...... " & StringStripWS(.description , $STR_STRIPTRAILING) & @CRLF) ConsoleWrite(" Error RetCode.......... " & "0x" & Hex(Number(.retcode)) & " (" & Number(.retcode) & ")" & @CRLF) EndWith Exit EndIf EndFunc Func com_error_handler($oError) Return ; Return so @error can be trapped by the calling function EndFunc Console COM ERROR DETECTED! Error ScriptLine....... 16 Error Number........... 0x800401F3 (-2147221005) Error WinDescription... Invalid class string Error Description...... Error RetCode.......... 0x00000000 (0) Edited May 29, 2021 by TheXman JockoDundee 1 CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
ahha Posted May 29, 2021 Author Share Posted May 29, 2021 TheXman, I am accessing a cell in a Word table. When the Table has a merged cell that I try and access an exception is thrown. I can see the Error and the exception data. I want to continue the main program, however, I'd like to let the program know that it hit an exception, so that it can continue operation. That is if I'm traversing a 2x4 table where the Row 1 Col 1 and Row 2 Col 1 are merged and I try to access it it throws the error "The requested member of the collection does not exist." which I detect. Now I want to let the main program know that it hit a merged cell. The example program whittles the issue down to how to avoid using a Global variable and use instead SetError. When you run the program you'll see the Global works fine but SetError(23) returns -2147221005 rather than 23. This is where I'm stuck. Link to comment Share on other sites More sharing options...
ahha Posted May 29, 2021 Author Share Posted May 29, 2021 Crossing responses. Your example returns but I do not see any values returned. Link to comment Share on other sites More sharing options...
TheXman Posted May 29, 2021 Share Posted May 29, 2021 (edited) 17 minutes ago, ahha said: I do not see any values returned. That's my point. There's no need to pass any values back. The error object and all of it's properties already exist within the function. As you can see, the function was able to recognize the exception by checking @error after the COM statement and then it displayed several properties from the error object. Most exceptions can be prevented by coding more defensively. You obviously are trying trying to process cells that don't exist. That's a coding problem. But if you don't want to fix you logic/coding issue, you can check for @error after the offending line to intercept the exception and handle it as needed. You appear to be concentrating too much on your solution to your problem instead of the actual problem itself. Your problem isn't really related to COM error handling. It has more to do with properly processing tables in Word. Edited May 29, 2021 by TheXman CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
ahha Posted May 29, 2021 Author Share Posted May 29, 2021 re: fix you logic/coding issue I have searched and searched and all I find is that the Word Object simply does not support cleanly addressing merged cells in a Table. In the above example of the 2x4 Table the Word Object does not tell you which are merged cells just that it's 2x4. So I'm left having to detect an exception. I agree it's a lousy way of detecting but I have found no other way. I was hoping that rather than just detecting @error I could use SetError to try and be a little more intelligent. Link to comment Share on other sites More sharing options...
TheXman Posted May 30, 2021 Share Posted May 30, 2021 (edited) 5 minutes ago, ahha said: In the above example of the 2x4 Table the Word Object does not tell you which are merged cells just that it's 2x4. I must be missing something. I don't see any reference to Word in you example above. Where's the script, a sample document, and an explanation of the desired result? Edited May 30, 2021 by TheXman CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
ahha Posted May 30, 2021 Author Share Posted May 30, 2021 (edited) There is no reference to Word. I tried to whittle down the issue to point to the exact issue I'm having which is that it appears that one cannot use SetError to pass back from a COM error handler. It appears only that @error is set and that's what you must use. Thanks "always wanted"😉 Edited May 30, 2021 by ahha misc Link to comment Share on other sites More sharing options...
TheXman Posted May 30, 2021 Share Posted May 30, 2021 I see. Yes, it appears that you are correct. One cannot set/change the @error and @extended values when returning from a COM error handler. Like I said, there's probably a better way to process the table in Word. I can take a look at it if you provide the necessary information. CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
ahha Posted May 30, 2021 Author Share Posted May 30, 2021 TheXman, Thanks for the offer but I don't expect you to solve my coding issues. Water has done a Word UDF that is excellent, the _Word_DocTableRead tries a different approach to get the cell contents (but no CR LF). I want to be able to get the cell contents, merged or not and I'm hoping to be able to read the CRLF in a cell as most merged cells have several lines of text. FYI here's the MS link https://docs.microsoft.com/en-us/visualstudio/vsto/working-with-tables?view=vs-2019 As I said thanks for the offer. Link to comment Share on other sites More sharing options...
TheXman Posted May 30, 2021 Share Posted May 30, 2021 You're welcome. 4 minutes ago, ahha said: Thanks for the offer but I don't expect you to solve my coding issues. Looking through your previous posts just now, it looks like you've already asked for help solving your coding issue related to the Word table. But if you don't want me to try to help with it, I understand and won't bother. Good luck with it. CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
JockoDundee Posted May 30, 2021 Share Posted May 30, 2021 38 minutes ago, ahha said: In the above example of the 2x4 Table the Word Object does not tell you which are merged cells just that it's 2x4. So I'm left having to detect an exception. I meant to mention this the other day: you should take a look at the Uniform property in the Word VBA object model: Quote True if all the rows in a table have the same number of columns. Read-only Boolean. expression.Uniform expression Required. An expression that returns a Table object. Perhaps checking this would make it so you don’t wait for an exception to be thrown? Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
ahha Posted May 30, 2021 Author Share Posted May 30, 2021 TheXman - Once I'm stuck again I'll seek help - it's not fair to bother anyone until I have nailed down my issue. JackoDundee - thanks. However knowing the table has a split/merged cells still does not solve the issue of traversing the table. I'm working on it now and as noted it appears throwing an exception is one way to be alerted that the accessed cell is a split/merged cell. This keyboard cowboy is back to the QWERTY mines 🤪 TheXman 1 Link to comment Share on other sites More sharing options...
ahha Posted June 1, 2021 Author Share Posted June 1, 2021 All, Thanks for the help. I have posted how I solved the Word Table merged cell problem here: Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now