aiter

word com error trapping possible bug in udf

15 posts in this topic

#1 ·  Posted (edited)

I am testing intercepting com errors in Word and I have found a possible bug in the UDF, it might not be a bug it just means a workaround.

I have found the com error bug in _Word_Create

Func _Word_Create($bVisible = Default, $bForceNew = Default)
    Local $oAppl, $bApplCloseOnQuit = False
    If $bVisible = Default Then $bVisible = True
    If $bForceNew = Default Then $bForceNew = False
    If Not $bForceNew Then $oAppl = ObjGet("", "Word.Application")  <------- here is the line which causees com error

This happens in the following example

#include <Word.au3>
main()
func main()
local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")
$oWord = _Word_Create()
$oDoc = _Word_DocOpen($oWord, @ScriptDir & "\Dear.docx", False, Default, True)
$myrange =  $oDoc.Range
$myrange.Select
sleep(3000)
_Word_DocClose($oDoc)
_Word_Quit($oWord)
endfunc


; User's COM error function. Will be called if COM error occurs
Func _ErrFunc($oError)
    ; Do anything here.
    ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _
            @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _
            @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _
            @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _
            @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _
            @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _
            @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _
            @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _
            @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _
            @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF)
EndFunc   ;==>_ErrFunc

This script causes a com error to occur and it has the following error

test.au3 (53) : ==> COM Error intercepted !
    err.number is:      0x80020006
    err.windescription: Unknown name.

    err.description is:     
    err.source is:      
    err.helpfile is:    
    err.helpcontext is:     
    err.lastdllerror is:    0
    err.scriptline is:  53
    err.retcode is:     0x00000000

Line 53 is

If Not $bForceNew Then $oAppl = ObjGet("", "Word.Application")

as I mentioned above.

When I force a new instance of Word, no error occurs eg

#include <Word.au3>
main()
func main()
local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")
$oWord = _Word_Create(True,True)
$oDoc = _Word_DocOpen($oWord, @ScriptDir & "\Dear.docx", False, Default, True)
$myrange =  $oDoc.Range
$myrange.Select
sleep(3000)
_Word_DocClose($oDoc)
_Word_Quit($oWord)
endfunc

So it seems that if I want to open up  existing Word instance (use _Word_Create() ) I will have to create my own _Word_Open to bypass this problem.

(If Word is already open the problem will not occur)

Comment?

 

Edited by aiter
Correction

Share this post


Link to post
Share on other sites



Which version of AutoIt do you run?


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2016-08-18 - Version 1.4.6.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2016-05-09 - Version 1.2.0.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

the latest version

Share this post


Link to post
Share on other sites

"Unknown name" is no error. It's an information that is handled by the UDF.
Means: The UDF checks if there is a running Word instance. If true it connects to this instance. If false, it creates a new one.

As - starting with AutoIt > 3.3.12.0 - all COM errors are now handled (means: ignored) in the _Word* functions you can't grab COM errors without a lot of modifications in this functions.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2016-08-18 - Version 1.4.6.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2016-05-09 - Version 1.2.0.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Running 3.3.14.2

Are you saying my com error handling is redundant?

When I put in my own com error handling as posted above, I encounter the com error (i.e it hits my com error function).

If I don't have the the com error handling and run it from dos within a framework, the program just hangs for doomsday, so I need the error handling. The reason it hangs is because any input that is required (whether console input or windows input) hangs it within the framework.

Anyway, I only need a new instance of word so no issue for me, but anyone else will encounter it if they have the same sort of script.

Edited by aiter

Share this post


Link to post
Share on other sites

When Jon changed the way COM errors are handled he needed to insert a COM error handler into the Excel and Word UDF.
It was implemented by inserting a local COM error handler into (nearly) each function. _Word_Create misses this error handler so you can grab the COM error with your global COM error handler. But this does not work for those functions with a local error handler.

But there should b no need to implement a global COM error handler. Check @error after each function call - that's all it needs to grab errors.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2016-08-18 - Version 1.4.6.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2016-05-09 - Version 1.2.0.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Unfortunately without my global com error handler the program hangs within the framework I run it in as I tried to explain the post above.  I see that the normal com error handler works nicely with a dialog if I run it from dos. When I run it within my framework (database system) it hangs because an error dialog is an input (okay, not this particular problem, but another one, say $oRange.lotofjunk. By using my own com error handler I can intercept this and output the message to console) . I will post the link to another problem I had just now.

Edited by aiter

Share this post


Link to post
Share on other sites

The Word UDF should never create a GUI to output error information. If it does then it's a bug.
Ignore the "unknown name" message by _Word_Create. I would be interested in all other messages originating by the Word UDF.
 


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2016-08-18 - Version 1.4.6.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2016-05-09 - Version 1.2.0.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

It does

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Change2CUI=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <Word.au3>
main()
func main()
;local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")
$oWord = _Word_Create()
$oDoc = _Word_DocOpen($oWord, @ScriptDir & "\Dear.docx", False, Default, True)
$myrange =  $oDoc.Rangeer  ;<--- deliberate error
$myrange.Select
sleep(3000)
_Word_DocClose($oDoc)
_Word_Quit($oWord)
endfunc

Run from cmd prompt, I get

 

 

error.png

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

It comes down to wanting apps compiled for CUI (console) to have pure console error output messages. No inputs (dialog or otherwise) required.

Edited by aiter

Share this post


Link to post
Share on other sites
8 minutes ago, aiter said:

It comes down to wanting apps compiled for CUI (console) to have pure console error output messages.

I think it comes down to write error free code or to handle errors correctly.
How do you expect the second line to work when line 1 is not able to create the object?

17 minutes ago, aiter said:

$myrange =  $oDoc.Rangeer  ;<--- deliberate error
$myrange.Select

I suggest

$oRange =  $oDoc.Rangeer  ;<--- deliberate error
If @error Then 
    ; Write error to log ...
    Exit
EndIf
$oRange.Select

 


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2016-08-18 - Version 1.4.6.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2016-05-09 - Version 1.2.0.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

If you still need to suppress error messages in a GUI you could use trancexx' solution I asked for many years ago:

 


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2016-08-18 - Version 1.4.6.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2016-05-09 - Version 1.2.0.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

Water, you biscuit :)

I thought I was alone in this problem.

I agree with you about error free code. The example was just a quick and nasty (when compiled though, it generates the error dialog before it hits the @error clause anyway)

The actual app I am writing I do error check everything, but I wanted what you posted above  just in case the unexpected happened.

Definitely "I stand on the shoulders of giants"

Edited by aiter

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

:D
If you like the solution then there is a button to tell me ;)

Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2016-08-18 - Version 1.4.6.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2016-05-09 - Version 1.2.0.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Similar Content

    • Ahile07
      Opening word in background
      By Ahile07
      Hello Guys,
      I'm trying to open a document with _WordDocOpen and replace some text in it with _Word_DocFindReplace and then print with _Word_DocPrint and finally close with _Word_DocClose and kill word with _Word_Quit. Works perfectly.
      My question is (can't find an answer anywhere): Can i do those commands in the background so i don't see word opening and replacing everything? Can't find anything in the proprieties of "WordDocOpen".
      Thank you.
      Flo
    • theak
      Wordperfect conversion to Word
      By theak
      Trying to find a quick way to convert 30k+ WordPerfect files into Word.
      Will probably run it locally from an admin machine or server so user permissions won't affect it.
      My idea was just to open the file, select all, copy, open new word doc, paste, file, save....
      What would be the best way to go about scripting something in this way?
    • aiter
      Word - Insert a row in table
      By aiter
      I am struggling to insert a row in a table in a Word document.
      $oDoc = _Word_DocAttach($oWord,"test.docx","FileName") $vRange = $oDoc.Tables(1).Rows(1).Select ; <-- ok - does select $vRange.Selection.InsertRowsBelow ; fails The documentation I have is (VBA) :-
      ActiveDocument.Tables(1).Rows(2).Select Selection.InsertRowsBelow I do not know why the autoscript is failing on this line
      $vRange.Selection.InsertRowsBelow I cannot specify
      Selection.InsertRowsBelow as the statement does not compile.
      Help appreciated.
    • aiter
      Word Office - moveStart
      By aiter
      I cannot get  the method movestart to work in my program
      $oRange = _Word_DocFind($oDoc, "3 4") ; return a range $oRange.MoveStart($WdLine,-1) ; supposed to move the start range to the beginning of the line I get an error '... requested action with this object has failed.'
      I have seen this statement used in Word.Udf, but cannot see why my statement is failing.
      Help appreciated.
    • milky
      Dos to Word Application
      By milky
      Hello,
      I wrote a small AutoIt App which takes DOS formatted textfiles and forwards them to MS Word. I searched a lot for a programm which does this, but I didn't find one.
      The reason for it is an old DOS program, which is used a lot, even today. The user wanted to print the output of that programm with some other font-size, font-style and so on... We used WinPrint, but this is a printing only app, so no formatting can be done afterwards...
      The solution was, to print with the DOS prgramm to an file, e.g. C:\12345\output.txt ... then read this file, convert it to unicode, put this into word with some pre-defined font / page size and so on ... and then the user can re-format or print it now.
      Here is the main function of the Dos2Word programm I wrote:
      Func Convert2Word() ; keine datei da... If Not FileExists($sFilePath) Then Return ; noch in Beaarbeitung... If _WinAPI_FileInUse($sFilePath) Then Return ; nun aber... Local $sFilePathTemp = $sFilePath & "_" & _WinAPI_CreateGUID() & ".txt" FileMove($sFilePath, $sFilePathTemp, $FC_OVERWRITE) ; open word and create new document Local $oWord = _Word_Create() If @error Then ErrorExit("Fehler bei _Word_Create()") Local $oDoc = _Word_DocAdd($oWord) If @error Then ErrorExit("Fehler bei _Word_DocAdd()") ; seite definieren With $oDoc.PageSetup .PageHeight = $sPageHeight .PageWidth = $sPageWidth .TopMargin = $sTopMargin .BottomMargin = $sBottomMargin .LeftMargin = $sLeftMargin .RightMargin = $sRightMargin EndWith ; schrift und absatz With $oDoc.Range .Font.Name = $sFontName .Font.Size = $sFontSize EndWith With $oDoc.Range.ParagraphFormat .SpaceBefore = 0 .SpaceAfter = 0 .LineUnitBefore = 0 .LineUnitAfter = 0 .LineSpacingRule = 0 EndWith Local $hFile = FileOpen($sFilePathTemp, BitOR($FO_READ, $FO_BINARY)) Local $iError Local $iLine = 1 Do Local $sLine = FileReadLine($hFile, $iLine) $iError = @error $iLine += 1 ; ignore special escape line of cm.exe If StringLeft($sLine, 2) = Chr(27) & Chr(64) Then $sLine = StringTrimLeft($sLine, 2) $oDoc.Range.insertAfter(_WinAPI_MultiByteToWideChar($sLine, $sCodePage, 0, True) & @CRLF) Until $iError <> 0 ; und am ende löschen, sofern gewünscht FileClose($hFile) If $sFilesDelete <> "0" Then FileDelete($sFilePathTemp) EndFunc ;==>Convert2Word The Homepage of the program is here: https://mcmilk.de/projects/Dos2Word/

      The full source code and precompild signed binaries for 32bit and 64bit systems are also there, the License is GPLv2
      With best regards, Milky
      Maybe someone finds it useful too