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
ActiveX open word document
Re: ActiveX open word document
I think you need this:
DO WHILE .NOT. lWordFinished
Sleep(100)
ENDDO
DO WHILE .NOT. lWordFinished
Sleep(100)
ENDDO
The eXpress train is coming - and it has more cars.
Re: ActiveX open word document
guess you have 2 Xbase++ Apps and you wait that 2nd App "close" ... what do you needVictorio 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 ?

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

next are Threads ...

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
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
greetings by OHR
Jimmy
Jimmy
Re: ActiveX open word document
Jimmy: thansk for information, I must study it, because it is a little complicated for me
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

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
Re: ActiveX open word document
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)
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)
Re: ActiveX open word document
ok ... you open a new Session ...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.
hm ...Victorio wrote:Code: Select all
* here wait ... to close word Do While !lWordFinished nEvent:=AppEvent( @mp1, @mp2, 1 ) Enddo

3th Parameter of AppEvent() is a Object (@oXbp) not a Number

greetings by OHR
Jimmy
Jimmy
Re: ActiveX open word document
... 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 )
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 )
Re: ActiveX open word document
have a look againVictorio 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
Code: Select all
// Just wait
nEvent := AppEvent( @mp1, @mp2, , 1)
Code: Select all
oBook:BeforeClose := {||lExcelFinished := .T.}
lExcelFinished := .F.
greetings by OHR
Jimmy
Jimmy