VBA for VBA

E

Ed

Is is possible to write a VBA program that can do a search for terms in a
VBA program. (I need it to report back the term (a variable) and the value
assigned to the variable. so the Find function will not work.)
 
J

Jonathan West

Ed said:
Is is possible to write a VBA program that can do a search for terms in a
VBA program. (I need it to report back the term (a variable) and the value
assigned to the variable. so the Find function will not work.)

Yes, look up the VBProject object and its various properties in the VBA
Help. There are limitations - the project you are working on has to be
unlocked - i.e. either not password-protected or open with you having typed
in the password.
 
E

Ed

Jonathan,

If I want a list of the various controls while I am in the MyProject.dot
that contains the VBA project, I type this in the VBA code within MyProject:

For Each oObj In FormName.Controls
. . .do this
Next

But how can I access the same controls in MyProject.dot if I am using
another project (MySuperProject) as the starting point. I have studied
everything, and made sure that the target project (MyProject) is open and
unlocked.

This code in MySuperProject should work, but there is no "Controls" property
or method that is parallel to what I wrote above (and works fine.) (I have
tried Collections and many other combinations, but I cannot find an
appropriate command to access the controls in "FormName")

Documents.Open "C\myprojects\MyProject.dot"
For Each oObj in ActiveDocument.VBProject.VBComponents("FormName").Controls

What am I missing?

--Ed (in Virginia)
 
R

Russ

A variable by definition varies after an initial value, otherwise it is a
constant. So are you talking about while a program is running?

While running you can use watch, locals, call stack, debug.print, .TypeText
"myvarname = " & myvarname ... into another document, etc.
 
R

Russ

For Each aVar In ActiveDocument.Variables
Jonathan,

If I want a list of the various controls while I am in the MyProject.dot
that contains the VBA project, I type this in the VBA code within MyProject:

For Each oObj In FormName.Controls
 
R

Roy

Russ,

That gives me the document variables that have been embedded in the
active document. However, it doesn't give me access to the Controls (esp.
the various UserForms and Modules) in the VBA project that is contained
within the active document.
Do you know how to get to those controls?
I have got to be close with "ActiveDocument.VBProject.VBComponents." but
I just cannot figure out what goes next to allow me access to UserForms (and
the Controls within those UserForms). Thanks.
 
O

old man

Hi,

You can try this code to list all the controls in a form (put the code in
the form):
Private Sub UserForm_Click()
Dim str1 As String
Dim myControl As Control

On Error Resume Next
For Each myControl In Controls

str1 = str1 & "Name: " & myControl.Name & vbCrLf
str1 = str1 & "Height: " & myControl.Height & vbCrLf
str1 = str1 & "Width: " & myControl.Width & vbCrLf
str1 = str1 & "Left: " & myControl.Left & vbCrLf
str1 = str1 & "Right " & myControl.Right & vbCrLf
str1 = str1 & "Default: " & myControl.Default & vbCrLf
str1 = str1 & "Tabindex: " & myControl.TabIndex & vbCrLf
str1 = str1 & "Top: " & myControl.Top & vbCrLf & vbCrLf

Next

MsgBox str1

End Sub

old man
 
E

Ed

I think I need to restate the premise (which I failed to clearly do at the
outset).

I want to create a new VBA project. I want this new project to open up an
existing project (called "MyOldProject") which has a collection of
userforms. I want the new project to read the controls found n each userform
in MyOldProject.

I open 'MyOldProject' in the new project thus:

Documents.Open "C:\projects\MyOldProject"

From there I should be able to write a code that accesses the VBProject and
the components within MyOldProject. This is where I am hung up. (I am not
worrying about looping through every userform just yet. I cannot even get to
the controls in a single form.). Something similar to this should be
possible, but it is not. I have spent hours playing with this:

"ActiveDocument.VBProject.VBComponents.("MyForm1").Controls"

but there is no 'Controls' element available, or reasonable substitute. What
goes next in the above formula that will allow me access to UserForms (and
the Controls within those UserForms) in the external project?

-Ed (in Virginia)

==================
 
R

Russ

You might be talking about references. I think that is how one project can
access the objects in another project.
 
R

Russ

Ed,
Here's Tony talking about using references in a previous message:Hi Richard,

Your app does seem complex, but that is not to say it needs to be.
For comparison (without bragging), my main addin is 5Mb. It has 19
userforms (mostly not overly complex), 27 modules (most a total of
over 280 procedures) and 3 class modules. It too gets data from
external databases using both ADO and DAO -if it's not broken I
(mostly) don't fiddle with it. It has references to other object
libraries such as OLE automation, scripting runtime, Jet, and control
libraries -it uses ListView and TreeView controls that are not native
to word VBA forms.

It also has references to other templates which provide other
functionality created by other developers within the organisation.
More on how this is done later.


I don't know how to measure the size of each module to see if it
exceeds the 64K limit you mention, but I have never had a problem with
that as far as I know. Where did you hear about that? Are you
automating word from Word templates or is that a problem when
automating from other apps?

This addin provides all of the functionality that is common to my
other individual templates. My main approach is that I have a
separate template for each discrete type of document I need to
produce. These templates contain the "words" that are to be produced
as well as the code that gets the data (both from the user and
databases) that the template needs.

My main approach is as follows.

SmartDoc(tm) Addin - this is a Word template that is automatically
loaded by Word (its in the Startup folder). This addin provides a menu
system from which the user selects the template they want (or even a
template or document from another app eg. spreadsheet, pdf, email).
Once the template is selected the menu then runs a specific procedure/
macro specified for that template. That procedure is in the selected
template. From here on, control is passed to the selected template.

The selected template calls a procedure in a third template which
contains code used to select the job/details for the job we are
working on eg names addresses, responsible partners etc. A job
selection screen is displayed and then the job data is retrieved from
a database and displayed on a form for checking. This common data
then populates the relevant places on the new document.

After this common data phase is complete the selected template macro
displays another form (remember all this code and the form is stored
in the selected template) allowing the user to enter information
specific to that template. The data is validated and then transferred
to the document.

So I have
One template with common procedures always accessible by other
templates (because it is always loaded at Word Startup). This
references external dll and OCX libraries as well as other templates
which make code available (through referencing).

One template that is only referenced by the selected template (through
referencing).

One selected template that accesses procedures from both of the above
templates.


So how does this work?
I hope this helps a little.

To access procedures between templates, the best way is to declare a
reference at design time.

For example Template A provides procedures to all other templates
Template A's procedures are accessible when it is opened/loaded by
word. This can be done in one of four ways.
1. The template is opened directly by word (using File|Open)
2. The template is loaded automatically by Word by being in Word's
Startup folder
3. The template is opened automatically by Word by being specified in
the "Global Templates and Addins". Tools|Templates and Addins"
Templates tab and click the Add button.
4. The template is loaded automatically by being referenced in the VBA
IDE. To do this Open the IDE and select Tools|References.

My SmartDoc(tm) is loaded using the first method. It referenced the
other templates using the fourth method.
The selected template accesses procedures in the common template also
using the fourth method.

The trick to simplifying this is to assign a meaningful project name
to the template to be referenced. This is done from the VBA IDE. Open
the template, and then switch to the IDE. In the IDE select the
template from the Projects window. It will be listed as
"TemplateProject (x)" or "Project (x)", where x is the name of the
document. Right click on the project and select the Project
Properties. You can now assign a project name to the template. If
you keep this short and meaningful it will help immensely). For
example my SmartDoc addin template project name is ... drum roll
please..... "SmartDoc".

Now whenever the template is loaded (via any of the above four
methods) it will appear in the Reference list as "SmartDoc".

If you need to use any procedures from an external template you simple
add a reference to the template project name at design time.

So in the above example the selected template has a reference to the
SmartDoc Addin as well as to the template providing the common job
type related procedures (in my case I have two called "CRGcommon" and
"Admincommon").

Any public procedures in either template can now be accessed simply by
using its name.

Eg here are two procedures.
One in SmartDoc
If SmartDoc.ProgrammerTemplateTestExit Then Exit Sub

This one in AdminCommon
Call AdminCommon.modAdmin_DoitCommon.CalledFromDoc


As you probably know already, these can be simplified as;
If ProgrammerTemplateTestExit Then Exit Sub

AdminCommon.modAdmin_DoitCommon.CalledFromDoc
modAdmin_DoitCommon.CalledFromDoc
CalledFromDoc


I have just realised how much time I have spent on this reply so have
to cut it short. Sorry.

As for the rest of your response, I will just make some simple
comments which can maybe act as pointers to further discussion.

the combinations of letters which one might encounter under certain conditions
for a particular category of client letter. That
category just had lots of combinations and elements at the time. I was
primarily using 2 comboboxes on that page of the form, and

I usually use individual templates for each type of letter. I do try
to simplify/reduce numbers by combining text into a single template
and adding/removing as necessary under program control but if the
conditions when a certain text is retained or removed get too
complicated (nested conditions) I usually find it is simpler to code
and for the client to specify if there are separate templates.

generate letters. The file is a .dot so that everything which it creates is in
the image of the template settings, plus it takes all
of these instructions from my code. Then there is template #2 which holds the
letterhead. I need to use the letterhead with the
different 1st page setup. Somebody suggested after I explained in more detail
that I can't have user intervention and the whole
thing must be done automatically, that I look into reading about auto-text in
the Word VBA help and move my letterhead into the main

Sounds like you are substantially "constructing" the document content
on the fly. See above point on this.
I agree if you don't need the letterhead on every document then it may
not be appropriate to have it "hard-coded" in the template. On the
other hand how are you inserting it?
If it isn't in the document are you copying it from another source and
inserting it on the fly? If that is the case you could insert it from
autotext stored in one of the already loaded templates. If you are not
doing any of these then are you constructing it?

3. There is a good bit of header and footer info in the "main" file's code

So you are constructing it?
things seemed to go awry when introducing this letterhead which is in the header/footer
layer already. That is, in the template file for the letterhead, you don't see the letterhead
with full color and contrast until you view headers and footers.

That is as it should be. It will still print and output correctly.
It's like that more as a visual clue to the user as to where that
stuff is coming from (and by putting it there and not say, at the
start of the document first page, it reduces the possibility of the
user inadvertently moving/deleting it).

Cheers
TonyS.
 
O

old man

Hi Ed,

Why don't you export the forms files from the old project and import them
into the new project? When you export you can make a copy of the files so you
are not losing anying in the old project. You can then access whatever
controls (in the new project) you want in a much cleaner way.

Old Man
 
Top