1. Neil Sutter
  2. PowerBuilder
  3. Friday, 16 March 2018 20:22 PM UTC

Looking for advise on coding or alternative approach. 

Using Microsoft Word 2013 for spell checking. Getting occasional error returned. Some users get the error every time, some none of the time, and some occasionally. 

Here's the gist of the code: 

// Connect to Word and do a spell-checkl
TRY
    lole_Spell = CREATE OLEObject                                // Create an OLE object
    ll_RC = lole_Spell.ConnectToNewObject('Word.Application')    // Connect to Word
    IF ll_RC <> 0 THEN                                                    // Handle no-go
        DESTROY lole_Spell
        RETURN ll_RC
    END IF
    
    lole_Spell.Application.Visible = TRUE        // Make Word visible
    lole_Spell.Application.WindowState = 1       // Maximize Word
    lole_Spell.Documents.Add()                   // Add a Word document
    f_BringWindowToTop(' - Word')                // Make Word the top window - application function
    lole_Spell.Activate                          // Make Word active
    lole_Range = lole_Spell.Selection.Range      // Get Word selection range
    lole_Range.Text = ls_Block                   // Copy our text to the Word document
    lole_Document = lole_Spell.ActiveDocument    // Get reference to our document            
    lws_State = gw_frame.WindowState             // Remember our PB app window state
    gw_frame.WindowState = Minimized!            // Minimize our PB app
    lole_Document.CheckSpelling()                // Check the spelling
    YIELD()                                      // Wait a bit
    gw_frame.WindowState = lws_State             // Reset our PB app window state
    lole_Range.WholeStory                        // Select all text in the Word document <<== error occurs here
    ls_Block = lole_Range.Text                   // Copy back to our string
    lole_Document.Saved = TRUE                   // Reset the Word dirty flag
    lole_Document.CLOSE(FALSE)                   // Close the Word document
    lole_Spell.Application.Quit                  // Quit Word
    lole_Spell.DisconnectObject()                // Disconnect OLE reference object
    YIELD()                                      // Wait a bit
    DESTROY lole_Spell                           // Destroy the OLE reference object
CATCH(OLERuntimeError MyOLEError)
    MessageBox('Spell Check Error', 'Error when spell checking data in Word' + &
        '~r~n' + MyOLEError.GetMessage())
    RETURN -1
END TRY
 
The error occurs where shown - WholeStory. When the error occurs, it's always "Name not found accessing external object property whilestory at line nnn in function f_DoSpellcheck. If the error does not occur, the spell check function works as intended. 
 
Anyone have experience with OLE and Word automation? See anything obvious? Have suggestions / alternatives? 
Any help much appreciated. 
 
Accepted Answer
Miguel Leeuwee Accepted Answer Pending Moderation
  1. Saturday, 17 March 2018 16:52 PM UTC
  2. PowerBuilder
  3. # Permalink

Are you using windows 8 or 10? This just in case if your window might sometimes be minimized when the error occurs.

I'm also not sure what you have in gw_frame, but I suppose it's the MDI frame window.

  • Maybe you have to work instead with the Active Sheet window if that's applicable?

I'm saying this, because the other day I spend 15 hours on trying to figure out why, working with an Excel sheet, the function .Add() failed in a similar way.

It worked perfectly on windows 7 with office 2010, but always failed on windows 10 with office 2016.

Finally I discovered that it was because the sheet was "Minimized" and all worked when the sheet wasn't, even when not being visible.

So .. I'm not really sure if it's office 2016 or windows 10, but my guess is that it's due to windows 10:

In windows 8 and 10 the whole functionality of windows being minimized has been changed drastically by microsoft (like not popping up when you want it to).

 

my 2cts.

Comment
  1. Mark Goldsmith
  2. Sunday, 1 August 2021 17:45 PM UTC
No worries Miguel and thanks for the additional info...I understand your explanation. The machine I'm currently using has Office 365 32 bit and so maybe there is a slight difference with Office 64 bit. I'm going to see if I can spin up an image with Office 365 64 bit and play around with it to see if I experience any differences from that of Office 365 32 bit.



As for when you issue the Activate, my experience has been to always issue one if there is the potential for any time to pass by before you attempt to have another interaction with the OLEObject...just in case the user has done something that throws off the previous activation (opens another doc, closes your doc etc.). You may also wish to use the ActiveDocument property of the Application object to check if the "correct" document, the one you want to work with, is currently active. Keep in mind too that there is an Activate method on the Application object and an Activate method on the Document object (which allows you to specify which document to Activate). You can also cycle through the Documents collection object to ensure that the document you want to work with is in fact still open.



Regards,

Mark
  1. Helpful
  1. Miguel Leeuwe
  2. Sunday, 1 August 2021 18:13 PM UTC
hi Mark,

This morning I re-installed 32 bit office to do some testing: The same problem still exists. I also tried to do an Activate of the Application, but that didn't solve the problem either. (BTW. you cannot use that if things are invisible, the activate blows up, so that would cause extra 'flashing').

It all works pretty well for the method used on the richtext edit, but the failing behaviour that I'm describing now, is for the dw control, where I'm doing a .Paste() of the copied text onto the OLE object. That worked pretty well before, but now only sometimes. Even after using my new method of using the Move() function, it failed a few times (after fresh re-install of 365 32 bit and a reboot). Started to work after saving my u_dw object again (not really having any change) and now it always works.

So for now I'm hanging on to the Move() method and not minimizing and setting invisible.

To be honest: I'd rather not use Word at all for this. MS used to break things in newer versions, but now they seem to do it on same versions. I've got an I-pad for work and I'm gettin office updates like every 3 days. What are theys people doing?

:)

  1. Helpful
  1. Mark Goldsmith
  2. Monday, 2 August 2021 00:17 AM UTC
Lol, yeah, never a dull day when working with MS products ...then again an occasional dull day would be nice ;-)
  1. Helpful
There are no comments made yet.
Miguel Leeuwe Accepted Answer Pending Moderation
  1. Saturday, 31 July 2021 22:36 PM UTC
  2. PowerBuilder
  3. # 1

Hi all,

I made some pretty long comments recently, since I detected some "changed" behaviour.

"setting invisible and minimizing" sometimes worked (first time not), then the second time it might.
Previously this always worked for me.

Now just to resume the long comments:

I think it's because for testing purposes, I changed my office 32 to 64 bit installation and there probably are some differences

regards.

Comment
There are no comments made yet.
Miguel Leeuwe Accepted Answer Pending Moderation
  1. Thursday, 16 July 2020 22:56 PM UTC
  2. PowerBuilder
  3. # 2

Ok, I think I found it. See the attached file. This is pb 12.6, so you might be prompted to migrate when opening the workspace.

 

Attachments (1)
Comment
  1. Daniel Mullings
  2. Monday, 15 February 2021 15:28 PM UTC
Hi Miguel. I'm just getting back to this. Thanks for posting the app, again. Will take a look when I get a chance.
  1. Helpful
  1. Miguel Leeuwe
  2. Monday, 15 February 2021 17:11 PM UTC
Hi Daniel,

Totally forgot about the spell check thing. To be honest, I'd rather use something else without depending on MS Word, but my manager here seems to like Word. I'm going to have a look (one of these days) if MS has resolved the bug of "taking over your OLE instantiated variable". It would be so much nicer / faster if you could have a global OLE variable connected / instantiated, without MS taking over that instance when a user opens up word and then closes it while you application is still running. If it hasn't been fixed, I'd still recommend using a global variable, but checking on its validity before re-using it.

regards
  1. Helpful
  1. Miguel Leeuwe
  2. Monday, 15 February 2021 17:13 PM UTC
I really don't understand very well what MS is doing lately. I have office, teams and onedrive installed on an I-pad and I've been getting updates like every 2 days. LOL
  1. Helpful
There are no comments made yet.
Andrew Barnes Accepted Answer Pending Moderation
  1. Thursday, 16 July 2020 17:04 PM UTC
  2. PowerBuilder
  3. # 3

My OLE Word SpellCheck code is just a bit different as well, but we had been getting similar name not found sort of error.  The error occurred identically in Word 2013 as well as Word 2016.  When run from our office desktop workstations, the errors were occasional, but when run from remote terminal servers in the Covid19 world much more common.

I was able to get around the problem by adding a delay after the Documents.Add() method as shown in the snippet below.

Regarding the retry loop, that dates back twenty years or more to the Word 97 days.  I don't know if the problem it solved is ever an issue with later versions of Word, but we have retained it rather than remove it and risk breaking something. 

 
 // create an empty document.  Occasionally the document doesn't get added
 // on the first attempt, so retry until it does (10 tries max)
 ll_retry_count = 0
 DO 
  lole_Spell.Documents.Add()
 
  // wait a second for the doc to be added.  This seems to eliminate a lot of spurious errors
  Yield()
  SetPointer(HourGlass!)
  Sleep(1)
 
  ll_retry_count ++
  ll_doc_count = lole_Spell.Documents.Count
 LOOP WHILE ll_doc_count = 0 AND ll_retry_count < 10

Comment
There are no comments made yet.
Miguel Leeuwee Accepted Answer Pending Moderation
  1. Saturday, 17 March 2018 17:06 PM UTC
  2. PowerBuilder
  3. # 4

I've checked on what I do with our spellcheck here and there are some differences (not saying my way is better, but so far no problems at all, working with office 2010, 2016, windows7 and windows 10)

 

1) I use a global instance variable for the oleObject to make repeated checking faster and only have to create and destroy once the oleobject 

2) I don't maximize gw_frame but restore to normal "gnv_app.iole_wordSpellCheck.Application.WindowState = 2", which is the word spell check window, not a powerbuilder window

3) I don't use "wholestory"

-- maybe it works for You:

regards,

MiguelL.

-----------------------------------------------------------------------------------------------------------

// u3, mjl, 30/08/17: spell-check using word:
string ls_caption
string ls_colName, ls_text
 
if not isvalid(gnv_app.iole_wordSpellCheck) then
return
end if
 
ls_colName = this.GetColumnName()
if isnull(ls_colName) then
return
end if
if ls_colName = "" then
return
end if
 
ls_text = this.GetText()
if isnull(ls_text) then ls_text = ""
if ls_text = "" then
return
end if
 
string ls_restoreClipBoard
 
// save whatever is on the clipboard() at this moment
ls_restoreClipBoard = ::clipboard()
// place the text from current column on the system clipboard 
::Clipboard(ls_text)
 
gnv_app.iole_wordSpellCheck.Application.Visible = False
gnv_app.iole_wordSpellCheck.Application.WindowState = 2
 
ls_caption = iw_master.Title + " (" + string(Handle(iw_master)) + ")" // we add the handle, to distinguish same window opened more than once (other sheets)
gnv_app.iole_wordSpellCheck.Application.Caption = ls_caption // so we can find the window to bring it to front
ls_caption = gnv_app.iole_wordSpellCheck.Application.Caption
 
// bring to front of powerbuilder window:
n_ole ln_ole
ln_ole = create n_ole
ln_ole.of_activateByWinTitle( ls_caption ) 
destroy ln_ole
 
//&& in pb2017 doesn't cause a FLASH but on 12.6 seems to flash a screen
gnv_app.iole_wordSpellCheck.Application.Visible = False
gnv_app.iole_wordSpellCheck.Application.WindowState = 2
 
gnv_app.iole_wordSpellCheck.Application.Documents.Open("")
gnv_app.iole_wordSpellCheck.Application.Documents.Add.Content.Paste()
gnv_app.iole_wordSpellCheck.Application.ActiveDocument.CheckSpelling()
 
gnv_app.iole_wordSpellCheck.Application.Visible = False
gnv_app.iole_wordSpellCheck.Application.WindowState = 2
 
gnv_app.iole_wordSpellCheck.Application.ActiveDocument.Content.Copy()
this.SetText(::clipboard())
 
// restore initial contents of clipboard()
if len(ls_restoreClipBoard) > 0 then
::clipboard(ls_restoreClipBoard)
end if
 
gnv_app.iole_wordSpellCheck.ActiveDocument.Close(0)
Comment
  1. Miguel Leeuwe
  2. Thursday, 16 July 2020 22:37 PM UTC
Hi Daniel,

I'm trying to find it ... If I can't find it, I'll make another one. Give me like 24 h, though.

regards.
  1. Helpful
  1. Miguel Leeuwe
  2. Thursday, 16 July 2020 22:53 PM UTC
Ok, I think I found it. See the attached file in my latest answer. This is pb 12.6, so you might be prompted to migrate when opening the workspace.
  1. Helpful
  1. Miguel Leeuwe
  2. Thursday, 16 July 2020 23:07 PM UTC
BTW: meanwhile, we no longer use a global instance to the oleobject. There's this little problem that when you start your application and you instance the OLEObject:

If a user opens up Word (just from windows, not your application), office happiliy occupies your instance. When the user then closes Word, your instance is gone and you'll get a system error / ole runtimeerror.

(now that I think of it, we still SHOULD use the global, but before using it, simply check if still valid and then reconnect if not).

Cheers
  1. Helpful
There are no comments made yet.
Daryl Foster Accepted Answer Pending Moderation
  1. Saturday, 17 March 2018 07:05 AM UTC
  2. PowerBuilder
  3. # 5

I think it's a method rather than a property, so do you need to add brackets after the method name?

lole_Range.WholeStory()

 

Comment
There are no comments made yet.
Jean-Paul Legault Accepted Answer Pending Moderation
  1. Friday, 16 March 2018 21:41 PM UTC
  2. PowerBuilder
  3. # 6

Word is probably timing out. Try using SetAutomationTimeout

Comment
  1. Miguel Leeuwe
  2. Wednesday, 21 March 2018 12:24 PM UTC
One last thing to add:



When you have had several Oleruntime exceptions, it's a good idea to check in your tasmanager to kill all "lost" word.exe (microsoft word) tasks and sometimes even "reboot you PC" before doing any further testing. Stuff seems to get cached and your changes might not be effective.

  1. Helpful
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.