COM Addin/Template Issue in Word 2003

M

MikeBTP

I'm having an issue trying to get a COM Addin created with VB 6 to work
properly.

I have a COM DLL Referenced in a Word 2003 template. I open Word and go to
File...New to open this template then look at the VBE code windows and the
TemplateProject (ThisDocument) contains the Sub procedures and the Reference
to the DLL as expected. Yet when I try to run any of the DLL functions in the
document, I get "Object Variable or With block variable not set" error.

I can open Word then open my template as if to edit it and it works fine. It
also works if I change the .DOT extension to .DOC and double-click to open it.

I've tried attaching the template and setting it is an addin and that
doesn't work either.

Any help with this would be greatly appreciated.

Thanks,
Mike
 
S

Shauna Kelly

Hi Mike

I think we need to get some terminology clear first.

You created a project in VB6. Was it an ActiveX DLL? Did you add a Designer
to the project? And you told it the Addin was for Word? If so, is it set to
Load on demand? And you compiled it to a DLL, and registered the DLL? Unless
all of those things are true, you don't have a COM add-in.

If you did do those things then Word will load the COM Addin when it starts.
You can determine what COM addins are loaded (if you used the default
settings for the designer and it loads for the current user only). To do
that, in Word, Tools > Customize. On the Commands tab, in the Categories
list, choose Tools. From the Commands list, drag COM Add-ins to a toolbar.
Then close the Customize dialog and click the COM Addins button. Your addin
should be listed there.

The most common way to access code in a COM Addin is without any VBA code at
all. You create a Word template file (.dot) with a toolbar and controls. The
..dot file does not run any code or call the COM addin, so it does not need a
reference to the DLL. You get your COM Addin to hook the controls on the
toolbar when the addin loads. And it responds to _Click events when the user
clicks one of the controls.

Maybe what you have is a DLL, but not a COM addin. If that's the case, and
you want to call the methods or properties it exposes, then you need the
following:
1. The DLL has to expose at least one public class.
2. You create a reference in your VBA code (Tools > References) to the DLL.
3. You use code that looks something like this:

Dim mDLLClass as Object

On error resume next
Set mDLLClass = CreateObject("MyDLLName.MyPublicClassName")
on error goto 0

if not mDLLClass is nothing then
msgbox mDLLClass.MyFunctionName (MyParameter:="foobar")
else
msgbox "Could not establish a connection to MyDLLName"
endif

This code is using late binding. You can also use early binding, which makes
it easier to code, but you can't avoid errors if the DLL isn't available.
For more info on that see
Early vs. Late Binding
http://www.word.mvps.org/FAQs/InterDev/EarlyvsLateBinding.htm

File...New to open this template
File > New doesn't open a template. It creates a new document based on a
template. If you want to open the template you have to do File > Open.
when I try to run any of the DLL functions
You'll need to work out whether you have a COM addin or not. If you do, then
it's unusual to use VBA code alongside it. If you have an ordinary DLL, and
the example above doesn't help, then post back and give us a sample of the
code.
I've tried attaching the template
attaching it to what?
and setting it is an addin
How are you doing that? With Tools > Templates and Add-ins? Where is the
add-in stored?

Hope this helps.

Shauna Kelly. Microsoft MVP.
http://www.shaunakelly.com/word
 
M

MikeBTP

Hi Shauna,

Thanks for the detailed reply. I'm sure my terminology is incorrect but let
me try to explain what I've got.

I've created an ActiveX DLL with three classes, two of which have at least
one Public function and one of these classes also "exposes" Word events using
Public WithEvents WordApp As Word.Application (early binding). I also have a
few Forms in this project. The project started out as a stand-alone EXE then
we wanted to open some of the project's functionality within Word. Therefore,
I did not initially create this as an Addin with Designers. I took the
Standard EXE and "converted" it to an ActiveX DLL.

I want to use this ActiveX DLL in two manners: one as a stand-alone program
that is opened from a Standard EXE that References the DLL and one whose
public functions can be called within Word via custom buttons and menu items.
The Word template that I have created has a Reference to the DLL and in the
ThisDocument object of the VBE I have declared my DLL object and added
Private Subs for the button click events that will each call my Object's
functions.

I did a lot of this a couple of years ago with Visio but it doesn't seem to
work exactly the same way with Word. As you correctly pointed out, when I go
to File\New and point to the template (Visio or Word) I open a new document
based on that template. In Visio, all of my ActiveX DLL functionlity is
available in the new document. In Word it is only available when I Open the
template file or change its extension to DOC (and double-click that DOC).

I may need to go back to the "drawing board" to make this work both ways
unless you have any suggestions.

Thanks again for your help,

Mike
 
S

Shauna Kelly

Hi Mike

If this were me, these are the things I'd check and/or the trouble-shooting
steps I'd follow:

1. Ensure that the class that holds your Public functions in the DLL has
Instancing as MultiUse or Global Multiuse.

2. For the Word events in the DLL to fire, you'll need to give the DLL a
reference to the Word Application, and the variable in which you save that
reference needs to have scope that will persist. To test whether it's
working, create a WordApp_NewDocument event and put a message box in there
just to be sure it fires every time you create a new document.

3. For the buttons' Click events to fire, you will need to hook the buttons
using a unique Tag/ID combination. Have you checked that you're actually
capturing the controls?

4. Check that the code to call the DLL is actually firing. If it only works
when you open the template, it sounds like you have the code in the wrong
place. If you need to to run every time you open a document, then it needs
to be in the Document_Open event in ThisDocument, or in a macro named
AutoOpen. If you want it to fire when you create a new document, use
Document_New or AutoNew.

5. Don't forget that you can step through the code. Close Word, open your VB
project in VB6, put in appropriate break points (eg at the point that you
pass the reference to the Word application to the DLL, at all the _Click
events and so on). Now, do ctrl-F5, then open Word and create a new
document, or open an existing document. When VB6 hits a break point, you can
then examine variables and step through the code and see what's going on.

By the way, I thoroughly recommend Professional Excel Development by Stephen
Bullen et al published by Addison Wesley. The early chapters are all about
Excel. But there's one whole chapter on doing just what you want to do, and
one on creating COM addins. They explain things very clearly and give good
examples. It's worth buying the book for those chapters alone.

Hope this helps.

Shauna Kelly. Microsoft MVP.
http://www.shaunakelly.com/word
 
M

MikeBTP

Hi Shauna,

Your steps 1, 2, 4, and 5 are working as expected. But step 3, about the
button tag/ID I'm unfamiliar with and this seems to be where my problem is.
The DLL loads and several init functions work but the button clicks generate
the "Object variable ... not set" error.

The way I've setup the button events (as I did in Visio a while back) is
create several Sub procedures in the ThisDocument object that are named as
the OnAction property for the button object in the VB DLL. Therefore, if the
button's OnAction property is "OpenSheet" there's a Sub in ThisDocument
called OpenSheet and in here a call to my DLL method is made:
"DllObject.OpenSheet".

In Document_New is where the object is instantiated and an Init method is
then called with a reference to ThisDocument instance. I place message boxes
in all of this and they all show up. The buttons are even created and the
Tooltips work but when I click any I get the error.

I'm thinking I have some sort of instance issue. One thing I noticed is that
when I open Word then click to create a new doc with my template, a second
window opens and all of my buttons and the VBE entries and references are
there. But if I close the original window only, all of this is gone from the
2nd window (based on my template). This I'm not familiar with.

I do appreciate your help and will check out the book you mentioned as I
obviously need help.

Thanks,
Mike
 

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