Wait till intialization complete...

L

Lüko Willms

Is there a "wait" or "pause" function in VBA?

I have written a VBA-program for MS-Word which is started by the
"New" event, i.e. when a new document is created based on a given
template, in which my VBA program resides.

The new document is created by a database application (which is
written in Delphi, by the way), which writes several hundred
DocVariables into the Word document, which are then used in Fields,
and in my VBA program.

The problem is now, that the "New" event is the moment when the
document is created by that other application, and when my VBA program
is triggered by that event, nearly all those DocVariables which my VBA
program is to process are simply not yet in existence. They are still
being Added. Takes its time.

How can I, resp. my VBA program, wait for the completion of this
process? Is there a "wait" or "pause" function in VBA, by which my VBA
program can be laid to rest for a specified span of time? Can I detect
another application or task working on the "ActiveDocument" which my
VBA program is associated with?

Any suggestion for me?


Yours,
L.W.
Germany
 
H

Helmut Weber

Hi Lüko,

kind of a stab in the dark:
Google here for gettickcount, sleep, ontime.

I'd check whether the number of docvariables
is increasing between two points in time.

By the way, adding 300 docvariables to a doc,
here and now, takes 10 Milliseconds:

Sub autonew()
Dim lCnt As Long
Dim lTm1 As Long
lTm1 = GetTickCount
For lCnt = 1 To 300
ActiveDocument.Variables.Add _
Name:=Format(lCnt, "000"), Value:=lCnt
Next
MsgBox GetTickCount - lTm1 ' 10
End Sub


--
Greetings from Bavaria, Germany

Helmut Weber, MVP WordVBA

Win XP, Office 2003
"red.sys" & Chr$(64) & "t-online.de"
 
L

Lüko Willms

Am Sat, 7 Oct 2006 08:21:34 UTC, schrieb Helmut Weber
I'd check whether the number of docvariables
is increasing between two points in time.

I had that idea, too.

Currently, I think that the proper way would be to use the Task
object, resp. the Tasks collection of the Application MS-Word. MAybe
also the Parent property of the Document object. Don't know yet, but
that is the direction which I am currently researching.

Maybe some real expert is able to help me...


Yours,
L.W.
 
T

Tony Jollans

Helmut was trying to help; the suggestion that he is no expert is (a) untrue
and (b) rude.

Before you go down a blind alley can I ask a basic question?

You create a document
You write some docvars to it.
You then want to run a macro.

Why don't you simply do that, all under control from the same place (your
delphi app)?

Trying to run one element of your process asynchronously when it is
dependent on another element introduces an unnecessary complexity -
especially, as you have found out, when there aren't any easy-to-use
facilities to help you control the process.
 
L

Lüko Willms

Am Sun, 8 Oct 2006 15:14:48 UTC, schrieb "Tony Jollans" <my forename
at my surname dot com> auf microsoft.public.word.vba.general :
You create a document
You write some docvars to it.

No, that is a foreign application which does it.
You then want to run a macro.

Which is fired by the "Document New" event.
Why don't you simply do that, all under control from the same place (your
delphi app)?

I write the VBA program, but I have no control over the data base.

The database application exports data to a newly created MS-Word
document in form of Document Variables, and then leaves it alone.
Until now this information has been used only in Fields, but I now
started to add some VBA programming.

My VBA program is fired by the Document_New event, but at that
moment in time, the database is not yet done with its work on the
document. My VBA program is to use information from these Document
Variables, which are not yet present.

I am just looking for ways to wait without waisting processor time,
i.e. yielding time to the OS instead of stealing CPU cycles from the
database application, which makes the actual waiting time longer. But
until now I can't find a way to do that with VBA (I am using Office
2000 for development here, and Office 2003 at the actual production
site). I also do rather not want to bother the users with MsgBoxes
which they might have to acknowledge repeatedly.

Yours,
L.W.
 
T

Tony Jollans

Well, first thing is that I don't think you can do it in Document_New at
all. The document is not considered open, or available for the Delphi app to
add variables to, until the event code has finished. This means you will
have to start a separate macro using Application.OnTime. In that macro you
will have to check whether the variables have been added or not and, not
continue until they have, perhaps with a DoEvents loop ...

Document_New ...

' Do whatever you have to do
Application.Ontime Now + TimeValue("00:00:01"), "NextMacro"

NextMacro ...

While <Document>.Variables.Count < 300
DoEvents
Wend
' Now you can do your stuff

Instead of DoEvents you could use another OnTime and exit. You may need to
experiment with the timings to get the best result.

Of course, if the delphi app is changed to add 400 variables you will start
failing so it would be better having a more definite trigger.
 
L

Lüko Willms

Am Sun, 8 Oct 2006 18:26:20 UTC, schrieb "Tony Jollans" <my forename
at my surname dot com> auf microsoft.public.word.vba.general :

thanks for your thoughts
Well, first thing is that I don't think you can do it in Document_New at
all. The document is not considered open, or available for the Delphi app to
add variables to, until the event code has finished. This means you will
have to start a separate macro using Application.OnTime.

I had a look at this in the online help, but had and have my doubts,
one reason being the time granularity which seemed to be somewhat to
coarse, but I may have been in error on that matter.

If really the "document_new" event is not yet over in that moment,
the document will not yet have the name which is being assigned to it
by the database application, and do I not have to specify that name in
the OnTime call? Will the target macro really catch the new document
which had just been created, or some other? I am not sure.

Otherwise, your suggestion may hit the mark. Anyway, I will have to
consult with the developers of the database application, what they
have to say about my project.
Of course, if the delphi app is changed to add 400 variables you will start
failing so it would be better having a more definite trigger.

I had a look at various documents, and found that the number of
DocVariables can easily reach 850 or more...

But the very first one is named "DATA_DONE", and it always had the
value of "1". I guess that it has initially the value "0", and is
changed to "1" when the data is actually done. I have a procedure
which loops thru the document variable collection, checks for the
existence of this variable and its value (when available -- I hope
that the second condition after a AND operator is not checked by
VBA...). But, as I said, I would like to simply yield the time to the
OS and other applications by some kind of WAIT function.


Yours,
L.W.
 
T

Tony Jollans

the document will not yet have the name which is being assigned to it
by the database application, and do I not have to specify that name in
the OnTime call?

Your macro is not in the document - by definition; it is in the template on
which the document is based. You shouldn't, however, need to explicitly name
it in the OnTome anyway.
But the very first one is named "DATA_DONE", and it always had the
value of "1". I guess that it has initially the value "0", and is
changed to "1" when the data is actually done. I have a procedure
which loops thru the document variable collection, checks for the
existence of this variable and its value (when available -- I hope
that the second condition after a AND operator is not checked by
VBA...).

The actual data are for you and the delphi app to agree; I can't help on
that score, but you don't want to be checking up to 800 variables just to
find the one you want. Address it by name and trap the error if it doesn't
exist.
But, as I said, I would like to simply yield the time to the
OS and other applications by some kind of WAIT function.

That (yielding to the OS for all queued activity to run) is what DoEvents
does. There is no VBA Wait - although it can be done with API calls or
mimiced using OnTime.
 
L

Lüko Willms

Am Sun, 8 Oct 2006 21:36:34 UTC, schrieb "Tony Jollans" <my forename
at my surname dot com> auf microsoft.public.word.vba.general :
but you don't want to be checking up to 800 variables just to
find the one you want. Address it by name and trap the error if it doesn't
exist.

maybe. I have some reticence to use this Basic-ish "on error resume
next" thing. And I'm not sure about the scope of that statement.
That (yielding to the OS for all queued activity to run) is what DoEvents
does. There is no VBA Wait - although it can be done with API calls or
mimiced using OnTime.

Thanks. I think I now understand better the "DoEvents". Better than
a "wait" with a fixed time. I have put that in the loops and will test
it out this afternoon (if not other, more urgent tasks keep me away).

I still wonder what I can do with the "tasks" collection,
"ActiveDocument.Creator" and so on.


MfG,
L.W.
 
T

Tony Jollans

I have some reticence to use this Basic-ish "on error resume
next" thing. And I'm not sure about the scope of that statement.

I'm not wonderfully impressed with it myself but it's what we've got so we
have to work with it. You control the scope yourself - but do read up on it
to make sure it doesn't bite you. In this case a fairly basic ...

myvar = 0
On error resume next
myvar = activedocument.variables("whatever")
On error goto 0
If myvar = 1 then
etc

... is probably along the lines of what you want
I still wonder what I can do with the "tasks" collection,
"ActiveDocument.Creator" and so on.

I wonder many things but sometimes I just have to get on with the job at
hand :)
 
L

Lüko Willms

Am Sun, 8 Oct 2006 15:14:48 UTC, schrieb "Tony Jollans" <my forename
at my surname dot com> auf microsoft.public.word.vba.general :
Before you go down a blind alley can I ask a basic question?

You create a document
You write some docvars to it.
You then want to run a macro.

Why don't you simply do that, all under control from the same place (your
delphi app)?

As I said in my previous anwer to this question, it is not my Delphi
application.

But, having explored all the other possibilities, and now looked
into how the developers of this application do it (Delphi 5 with
OLE-Automation), I came to the conclusion, that the above would be the
best way to go.

Because:
Trying to run one element of your process asynchronously when it is
dependent on another element introduces an unnecessary complexity -
especially, as you have found out, when there aren't any easy-to-use
facilities to help you control the process.

That is the bitter truth. I even looked into the Application events,
like Application.WindowActivate, but that would, if successfully
implemented (VBA unter Office 2000 rejected an unknown user object
type), do that event for _any_ window activated in MS-Word, not only
those based on my template - right?

So I will contact the developers of that Delphi5 application, and
suggest to them to implement as a configuration option for the Word
interface (one can configure which group of DocVariables is created)
to run a user-written macro, which then should have a fixed name, e.g.
"ThisDelphiApp_UserStartMacro" or something similar.

In the mean time I will rewrite my VBA program to be activated by
some user input...


Yours,
 
K

Karl E. Peterson

Lüko Willms said:
But the very first one is named "DATA_DONE", and it always had the
value of "1". I guess that it has initially the value "0", and is
changed to "1" when the data is actually done. I have a procedure
which loops thru the document variable collection, checks for the
existence of this variable and its value (when available -- I hope
that the second condition after a AND operator is not checked by
VBA...). But, as I said, I would like to simply yield the time to the
OS and other applications by some kind of WAIT function.

DoEvents does indeed yield to the system, but it can give the appearance of
100% cpu utilization as the system will continue to feed timeslices to the
yielding app just as before. I have re-read this thread, and wonder whether
you actually considered a timer-based polling for the other app's
completion? That would seem to avoid the need for your user to tell you
when it's finished. Checking every 100ms or so wouldn't put any strain on
the cpu, but would appear "instantaneous" to the user.
 
L

Lüko Willms

Am Wed, 11 Oct 2006 17:52:43 UTC, schrieb "Karl E. Peterson"
I have re-read this thread, and wonder whether
you actually considered a timer-based polling for the other app's
completion?

How would I find that out? The application will run all day, as the
main database application for that site. I would have to find out when
they have finished working on my document. What would I have to look
at?


Yours,
L.W.
 
K

Karl E. Peterson

Lüko Willms said:
How would I find that out? The application will run all day, as the
main database application for that site. I would have to find out when
they have finished working on my document. What would I have to look
at?

This is what I *specifically* replied to:

I chose that passage carefully, as it sounded as if this was the answer to
the question you now ask. Did I misunderstand? I would test that
"DATA_DONE" variable on each timer tick, until it's flagged.

Also, with regard to this:

It is. VB(A) doesn't short-circuit logical expressions.
 
L

Lüko Willms

Am Thu, 12 Oct 2006 18:59:27 UTC, schrieb "Karl E. Peterson"
I would test that
"DATA_DONE" variable on each timer tick, until it's flagged.

I tried; the problem is that the Delphi-Application and my
"Document_New" event-procedure apparently block each other.

I'm currently changing it to a MACROBUTTON filed on the top of the
letter which the user should click to do the initialization work from
my VBA program. Unfortunately, it doesn't work yet...

I also have suggested to the developers of that Delphi application
that they make an configurable option available to RUN a macro
supplied in the document template.


Yours,
L.W.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top