Error 91 when code run in Internet Explorer embedded word

B

Beeawwb

Hi all,

Interesting (or not so interesting) connundrum.

I've written some code which I'm very happy with, works very well. I've
implemented it on a number of systems here at work, and everybody is working
fine. The problem is, I've found 1 user trying to run the code from the
"Internet explorer" embedded link of Word (opening a document from our
Intranet, in IE, which then opens the document in IE), and pushing the button
to start my userform etc. When this happens, they get "Error 91: Object
variable or With block variable not set." As mentioned, when running the code
in a "proper" session of Word.

The biggest problem is, because I'm in IE when the error happens, I can't
debug the code. And I've tried adding Error 91 to my error handling (Case 91
'Word may be running in Internet Explorer) but the error still happens. Which
is weird, since I would assume that On Error statements override everything
else. But what do I know, I'm still a fair novice.

Anyway, the question is: How do I trap for this error, seeing as it occurs
in IE? Is there any way I can check how the macro is being called (eg, what
environment it exists in, and then if it's in IE, stop running) and work
around it? Or any way I can get the error checking to say "Hey, Error 91! I
know that one. Do this stuff!" (Wow, I'm paraphrasing today).

Thanks in advance for your knowledge and help,

-Bob
 
R

Russ

Sounds confusing.
"embedded link of Word" = Word application running in IE?
Or just a link to a .doc file?

"pushing the button to start my userform" = where is the button? In Word, or
IE, or macrobutton on document shown through a Word viewer of IE or toolbar
of the application of Word ran inside of IE?
 
B

Beeawwb

Hi Russ,

Sorry I know I'm being confusing, I'm havng difficulty describing what
exactly the problem is because I don't know the actual terms, since I don't
actually use it myself.

There's an option which allows you to open Word documents in Internet
Explorer. I personally disable this, because I prefer to be using an actual
Word application. However not everybody in our office does this. Some like to
just edit in IE.

Pushing the button is refering to a button I've put on a toolbar which runs
the Which_Letterhead_Load() sub. This can be shown on a toolbar in IE or in
Word. The problems I'm describing only occur when the button is pushed in IE.

Hope that clarifies things a bit for everybody, let me know if there's
anything else confusing.

-Bob
 
R

Russ

Bob,
I'm no expert on the interplay between Word and IE, but maybe someone else
will respond.

How does the toolbar button appear in IE, if it is part of a template for
the document in Word? Do you dynamically create it, when the document opens?
Are you using html, javascript, or something similar?

You don't want someone to edit in IE, right?

<http://www.shaunakelly.com/word/sharing/OpenDocInIE.html>

Note reference to registry setting and also check out the reference article
links at the bottom of this webpage.
How to launch Word from Internet
Explorer<http://support.microsoft.com/kb/178222>

Application.BrowseExtraFileTypes Property
<http://msdn2.microsoft.com/en-us/library/bb209622.aspx>

How to configure Internet Explorer to open Office documents in the
appropriate Office program instead of in Internet Explorer
<http://support.microsoft.com/kb/162059>

But going back to your original error message, does the user have you
template that includes the userform code on his computer? If not, maybe that
is why the button can't call it.

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.
 
B

Beeawwb

Hi again Russ,

I too am confused by the interplay between Word and IE. Something tells me
that there must be a way of "telling" what environment the code is running
in, but I may be wrong.

While I would love to force users to edit documents in Word, ala registry
fix, our "Standard Operating Environment" (SOE) as defined by our Tech
department says that it's not possible. I'm friends with our local LAN
administrator, so I've had a few changes to my SOE made, but they're for me
only, because of the work I do programming on the side.

The user is able to see the template, and the code, because the toolbar
changes do show up on their system. It's just some part of the code that IE
is finding incompatable, that I need to trap for so I can make it error out.

For reference, I've added Case 91 to my error handling code, so if Error 91
occurs, it should just display an error message and quit. Since it's not, I'm
assuming that either A) the code isn't able to compile (which wouldn't make
sense to me) or an error is occuring somewhere that is preventing it from
evaluating the error.

Thoughts?

Thanks again,

-Bob
 
T

Tony Jollans

Take a look at the document's Container Property - I forget the details off
the top of my head but it should tell you what, If anything, Word is running
inside.
 
B

Beeawwb

Hi Tony,

This is definately on the right track, unfortunately I'm having difficulty
implementing it. I'm unable to tell how I should access the Container
property and return it correctly. The helpfile and searches of the internet
aren't proving very helpful either. The helpfile rather cryptically states
"The Container property also provides a pathway into the object model of the
container application if a Word document is opened as an ActiveX document —
for example, when a Word document is opened in Microsoft Office Binder or
Internet Explorer." but of course, doesn't tell which Object I need to check,
or how to check it.

I've experimented with a few of the "Smart" tips to see what the
Word.Application and Word objects have, but nothing allows me to return a
name that I can see.

Right on the edge of solving this one, anybody know how to return the
Container for a Word Application to see if Word has been opened as an ActiveX
document (as per the above "helpfile")

Thanks again,

-Bob
 
T

Tony Jollans

You will get an error if not in some sort of container. Try something like
this:

On Error Resume Next
Set Cont = ActiveDocument.Container
Select Case Err.Number
Case 0:
If TypeName(Cont) = "IWebBrowser2" Then
MsgBox "In Browser"
Else
MsgBox "In some other OLE Container"
End If
Case 5722:
MsgBox "Just in Word"
Case Else:
MsgBox "Error - treat as any other error"
End Select
On Error GoTo 0
 

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