ActiveX open word document

Xbase++ 2.0 Build 554 or later
Post Reply
Message
Author
Victorio
Posts: 621
Joined: Sun Jan 18, 2015 11:43 am
Location: Slovakia

ActiveX open word document

#1 Post by Victorio »

Hi,
I work on automatic generate word documents .
I have one document as "template" where are bookmarks.
And then change this bookmarks to my own values and save document to outdocument.

But I want after it open this document also with ActiveX, because with DC_Spawnurl this is some tome to open it.

How can realize waiting to close document, when I show it in word ?

here sample :
lWordFinished := .f.
oWord := CreateObject("Word.Application")
oWord := oWord:dynamicCast(ActiveXObject())
oWord:Quit := {||lWordFinished := .T.}
oWord:visible := .T. // zobrazuje word dokument počas spracovania
lWordFinished := .f.
oWord:documents:open( outdocument )

???

oDoc:close()
oWord:Quit()
oWord:destroy()

when I try to ??? place put for example this :
do while lWordFinished=.T.
sleep(100)
enddo

application frozen, that I mean, this is not good way.

without anything document open, but in a monent close.

many thanks for any advice

User avatar
rdonnay
Site Admin
Posts: 4728
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: ActiveX open word document

#2 Post by rdonnay »

I think you need this:

DO WHILE .NOT. lWordFinished
Sleep(100)
ENDDO
The eXpress train is coming - and it has more cars.

User avatar
Auge_Ohr
Posts: 1405
Joined: Wed Feb 24, 2010 3:44 pm

Re: ActiveX open word document

#3 Post by Auge_Ohr »

Victorio wrote:Hi,
But I want after it open this document also with ActiveX, because with DC_Spawnurl this is some tome to open it.

How can realize waiting to close document, when I show it in word ?
guess you have 2 Xbase++ Apps and you wait that 2nd App "close" ... what do you need :?:
you need to "communicate" between both Apps ... that is what ActiveX can do :!:

now your Code use only "one Way" : from Xbase++ sending to ActiveX
but you need to receive Events from ActiveX if you want to react on it when User :!: "close" Document.



next are Threads ... :whistle:
ActiveX use its own (GUI) Thread -> not Xbase++ "Event" Loop.
i use PostAppEvent() with UserDef Events to "transfer" it into Xbase++ "Event" Loop.


so Code like this will NEVER work ...

Code: Select all

lWordFinished := .f.
DO WHILE
you have no Control, while you did not receive Events from ActiveX.

remember : Windows does not force any Action ... it react on User and send Events

---

here a Sample how i use Outlook Editor with Xbase++

Code: Select all

//
// activeX Event
//
#define EvClose                 "Close"
#define EvWrite                 "Write"
#define EvPropertyChange        "PropertyChange"
#define EvItemChange            "ItemChange"
#define EvDeactivate            "Deactivate"
#define EvQuit                  "Quit"

      ::oOutlook := ::oOutlook:dynamicCast( ActiveXObject() )
      xVar := ::oOutlook:isEventPublished( EvQuit )
      IF xVar <> NIL
         lSuccess := ::oOutlook:SubscribeEvent( xVar, { | a, b, c, d | IF( NIL = ::oMainApp, NIL, PostAppEvent( xbeE_TerminRefresh, dDate,, ::oMainApp ) ), PostAppEvent( xbeP_Activate,,, ::ButtonOK ) } )
         IF .NOT. lSuccess
            * LOGME("::oOutlook EvQuit FAIL")
         ENDIF
      ENDIF

      ::oItem := ::oItem:dynamicCast( ActiveXObject() )
      xVar := ::oItem:isEventPublished( EvWrite )
      IF xVar <> NIL
         lSuccess := ::oItem:SubscribeEvent( xVar, { | a, b, c, d | PostAppEvent( xbeE_TerminWrite,,, Self ) } )
         IF .NOT. lSuccess
            * LOGME("::oItem EvWrite FAIL")
         ENDIF
      ENDIF

      xVar := ::oItem:isEventPublished( EvClose )
      IF xVar <> NIL
         lSuccess := ::oItem:SubscribeEvent( xVar, { | a, b, c, d | IF( NIL = ::oMainApp, NIL, PostAppEvent( xbeE_TerminRefresh, dDate,, ::oMainApp ) ), PostAppEvent( xbeP_Activate,,, ::ButtonOK ) } )
         IF .NOT. lSuccess
            * LOGME("::oItem EvClose FAIL")
         ENDIF
      ENDIF

      // this show Editor using its own Thread        
      ::oItem:Display()

      // more Xbase++ Code   
---
Word2003_Events.jpg
Word2003_Events.jpg (385.01 KiB) Viewed 14673 times
greetings by OHR
Jimmy

Victorio
Posts: 621
Joined: Sun Jan 18, 2015 11:43 am
Location: Slovakia

Re: ActiveX open word document

#4 Post by Victorio »

Jimmy: thansk for information, I must study it, because it is a little complicated for me :oops:

I do not have two Xbase apps ,this is all in one , only word is called from it.

I do not understand, but now this works as I want also without any wait loop :

* Open template document and replace bookmarks with my values
**************************************************************
oWord := oWord:dynamicCast(ActiveXObject())
oWord:Quit := {||lWordFinished := .T.}
* oWord:visible := .T. // zobrazuje word dokument počas spracovania
oWord:visible := .F. // nezobrazuje word dokument počas spracovania
lWordFinished := .f.

oWord:documents:open( cFile )
oDoc := oWord:ActiveDocument
oBM := oDoc:Bookmarks

// Replace the Bookmark with a new value
ReplaceBookmark(oBM , "CISLO_ZMLUVY" , aData[1] )
ReplaceBookmark(oBM , "NAJOMCA" , aData[2] )
ReplaceBookmark(oBM , "PRENAJIMATEL" , aData[3] )

IF(ValType(cSaveAs)=="C")
oDoc:saveas(cSaveAs)
ENDIF

// Close the document and destroy the ActiveX
// object
if nBearb # 1
//oDoc:sendfax()
oDoc:close()
oWord:Quit()
endif

sleep(50) // tu časové oneskorenie asi aby stihol zatvoriť dokument

oWord:destroy()

* And now open saved document with new values
**********************************************
lWordFinished := .f.
oWord := CreateObject("Word.Application")
oWord := oWord:dynamicCast(ActiveXObject())
oWord:Quit := {||lWordFinished := .T.}
oWord:visible := .T. // zobrazuje word dokument počas spracovania
lWordFinished := .f.
oWord:documents:open( docsuborout )

*oDoc:close()
*oWord:Quit()

oWord:destroy()


So I am not sure, what is :dynamicCast , and other things but now after changes document this saved, and open new document and word stay open with it. This is what I want.
Only time to open document need some time, about 10 seconds

Victorio
Posts: 621
Joined: Sun Jan 18, 2015 11:43 am
Location: Slovakia

Re: ActiveX open word document

#5 Post by Victorio »

Now this works as I want,
open teplate document,
change bookmarks to my values,
save to new document as DOC and PDF
open new document and wait to close it in word by user.

here this is modal, that's what I need to prevent for some unsuported situations.

Here source ispired by some posts from alaska newsgroup...:
*****************************************************************************
static FUNCTION WordFillDocument(cFile,aData,cSaveAs,cSaveAsPdf,nBearb,acnz1) // funkcia, ktorá vymení bookmarks/záložky za zvolený text
*****************************************************************************
LOCAL oWord,oBM,oDoc,lWordFinished := .f.,x
LOCAL cCakaj

oWord := CreateObject("Word.Application")
IF Empty( oWord )
MsgBox( "Microsoft Word nie je nainštalovaný, dokument sa nedá vytvoriť !" )
return .f.
ENDIF

oWord := oWord:dynamicCast(ActiveXObject())
oWord:Quit := {||lWordFinished := .T.}
*oWord:visible := .T. // zobrazuje word dokument počas spracovania
oWord:visible := .F. // nezobrazuje word dokument počas spracovania
lWordFinished := .f.

oWord:documents:open( cFile, .F., .T. ) // toto som upravil podľa fóra news alaska
oDoc := oWord:ActiveDocument
oBM := oDoc:Bookmarks

* nahradenie bookmarkov hodnotami z poľa aData, resp. priamo zvolenými hodnotami
// Replace the Bookmark with a new value
ReplaceBookmark(oBM , "CISLO_ZMLUVY" , aData[1] )
ReplaceBookmark(oBM , "NAJOMCA" , aData[2] )
ReplaceBookmark(oBM , "PRENAJIMATEL" , aData[3] )

IF(ValType(cSaveAs)=="C")
oDoc:saveas(cSaveAs)
ENDIF

lulozitajpdf:=.T.
if lulozitajpdf==.T.
oDoc:ExportAsFixedFormat( cSaveasPdf, 17 )
cRet := cSaveasPdf
endif

oWord:visible := .T. // nezobrazuje word dokument počas spracovania
oWord:Activate()

* here wait ... to close word
Do While !lWordFinished
nEvent:=AppEvent( @mp1, @mp2, 1 )
Enddo

oDoc:destroy()
oWord:destroy()

RETURN .t.

***********************************************
static FUNCTION ReplaceBookmark(oBM,cBM,cValue)
***********************************************
LOCAL lRet := oBM:Exists(cBM) // zistí, či bookmark existuje
LOCAL oF

IF(lRet)
oF := oBM:Item(cBM) // načíta do premennej objekt pôvodnú hodnotu
oF:Range:Text := cValue // nahradí novým textom
oF:Destroy() // zatvorí objekt
ENDIF

RETURN(lRet)

User avatar
Auge_Ohr
Posts: 1405
Joined: Wed Feb 24, 2010 3:44 pm

Re: ActiveX open word document

#6 Post by Auge_Ohr »

Victorio wrote:Now this works as I want,
open teplate document,
change bookmarks to my values,
save to new document as DOC and PDF
open new document and wait to close it in word by user.
ok ... you open a new Session ...
Victorio wrote:

Code: Select all

* here wait ... to close word
Do While !lWordFinished
	nEvent:=AppEvent( @mp1, @mp2, 1 )
Enddo
hm ... :eusa-think:
3th Parameter of AppEvent() is a Object (@oXbp) not a Number :naughty:
greetings by OHR
Jimmy

Victorio
Posts: 621
Joined: Sun Jan 18, 2015 11:43 am
Location: Slovakia

Re: ActiveX open word document

#7 Post by Victorio »

... nEvent:=AppEvent( @mp1, @mp2, 1 ) ...

yes, I saw this in some example here and it was weird, but for examine I put it also to my program :

https://www.xbaseforum.de/viewtopic.php ... C+1#p92536

but rather I use AppEvent( @mp1, @mp2, @oXbp )

User avatar
Auge_Ohr
Posts: 1405
Joined: Wed Feb 24, 2010 3:44 pm

Re: ActiveX open word document

#8 Post by Auge_Ohr »

Victorio wrote:... nEvent:=AppEvent( @mp1, @mp2, 1 ) ...
yes, I saw this in some example here and it was weird, but for examine I put it also to my program :
https://www.xbaseforum.de/viewtopic.php ... C+1#p92536
have a look again

Code: Select all

// Just wait
nEvent := AppEvent( @mp1, @mp2, , 1)
also Koverhage use Event "BeforeClose"

Code: Select all

oBook:BeforeClose := {||lExcelFinished := .T.}
lExcelFinished := .F.
greetings by OHR
Jimmy

Post Reply