Placing Individual Building Blocks on Ribbon

D

Dogwoodnc

I've created a customized tab for our workgroup, and would like to make
separate buttons for a few of our custom building blocks. The building
blocks are visible in the Quick Parts listing. I've recorded macros that
retrieve each building block -- the macros work fine via the Developer>Macro
method.

I then tried to insert lines in the RibbonX XML that place icons on the
Ribbon and allow the user to call each macro. Here's a sample line of code,
using the same syntax that I had successfully used for other macros that
don't deal with building blocks:

<button id="TagNote" label=" " onAction="TagNoteTag"
image="TagNoteGraphic"/>

However, when I click the icon on the Ribbon (to invoke the macro), the
following error message appears:
Wrong number of arguments or invalid property assignment.

Might you have any suggestions re what to do in the XML to retrieve the
macro with the building block?

Thanks in advance!
Diana
 
G

Greg Maxey

That is the error that is generated if you don't have the parameter "control
as IRibbonControl" set in your onAction callback:

Sub TagNotTag(control As IRibbonControl)
 
D

Dogwoodnc

Thank you! I'm just now learning Word 2007 (and customizing the Ribbon with
VBA macros), and hadn't run across that parameter yet. I've added the
"control as IRibbonControl" parameter to the macros, and that has helped
tremendously. Clicking on the icons on the ribbon now correctly invokes the
macros based on the building block text!

Two followup questions:
1. I've noticed that when I add that parameter, the macro is no longer
visible in the list of available macros (Developer>Macro). Is there a way to
make it visible on that list AND on the Ribbon itself?

2. My ultimate goal is to deploy these macros to our entire workgroup.
Historically (in previous versions of Word), we've done this via placing the
template that contains the macros in the Startup folder -- which has the same
path name for everyone, so we haven't had to create unque sets of macros to
compensate for differences in path names associated with names/corporate ID
numbers/etc. However, when I tested the template in the Startup folder, and
then tried invoking the macros described below, the error message "The
requested member of the collection does not exist" appears. Any suggestions
re fixing this?

THANKS!
I really appreciate your help in journeying along this learning curve!
 
J

Jay Freedman

To answer your first question, the Macros dialog never displays any
procedure that (a) takes parameters, (b) is a Function instead of a Sub,
and/or (c) is declared as Private instead of the default of Public. If you
want to be able to run the same macro from both the ribbon and the Macro
dialog, you need to create another macro without a parameter and have it
call the first one. For the example Greg gave you, try this:

Sub TagNoteTagRun()
Dim control As IRibbonControl
TagNoteTag control
End Sub

I can't give an absolute answer to the second question without seeing the
code of one of the macros, but I suspect it's trying to insert a building
block that's stored in the same template with the macros by using a
statement like

ActiveDocument.AttachedTemplate.BuildingBlockEntries("BB"). _
Insert Where:=Selection.Range, RichText:=True

That works as long as the template is in the Templates folder and you base a
new document on it. When you move the template to the Startup folder,
though, the template is NOT the AttachedTemplate of the ActiveDocument. So
the building block you're trying to insert isn't in the AttachedTemplate of
the ActiveDocument, and the error message is accurate.

To fix this, you need to select the template that does contain the building
block, like this:

Sub TagNoteTag(control As IRibbonControl)
Templates(ThisDocument.FullName).BuildingBlockEntries("BB") _
.Insert Where:=Selection.Range, RichText:=True
End Sub


--
Regards,
Jay Freedman
Microsoft Word MVP
Email cannot be acknowledged; please post all follow-ups to the newsgroup so
all may benefit.
 
D

Dogwoodnc

Thank you so much for your insight! #1 works great now!

You're right, the building blocks were in the same template as the macros.
I've moved them to a separate template, and have placed that template in the
Document Building Blocks folder. (As far as I can tell, if I place them
anywhere else, they are not visible on the Quick Parts list!) However, I
still don't quite understand the code needed for question #2 below. [Note,
I'm not a trained programmer! :) ]


My current two macros are:

Sub TagNoteTagClick(control As IRibbonControl)
ActiveDocument.AttachedTemplate.BuildingBlockEntries("TagNoteTag1") _
..Insert Where:=Selection.Range, RichText:=True
End Sub

and

Sub TagNoteTag()
Dim control As IRibbonControl
TagNoteTagClick control
End Sub

I understand that I need to change ActiveDocument.AttachedTemplate to
Templates(ThisDocument.FullName) -- but I'm not sure where I need to specify
the path/doc name that contains the customized building blocks. (I'd like
them to be in a path that can be easily deployed -- perhaps
"%appdata%\Microsoft\Document Building Blocks\ ? They don't seem to appear
in the building block list if I place them anywhere else! The file name is
customBB.dotx.)

I've searched my reference books and online, but cannot locate an example
where the path/file name is specified with the
Templates(ThisDocument.FullName) command. I've experimented with several
possibilities, but have not been successful.

Any suggestions are gratefully appreciated!
Thank you!
Diana
 
J

Jay Freedman

The code I posted was explicitly and exclusively for the case where
the macros and the building blocks are in the same template. The
reason is that the built-in variable ThisDocument refers to the
document or template containing the macro code that's currently
executing. So the expression Templates(ThisDocument.FullName) returns
the member of the Templates collection that contains the macro -- and
therefore the one that contains the building block you want. When you
split the macros and the building blocks over two templates, you broke
that connection.

For your current arrangement -- which is indeed easier to install and
maintain -- the code needs to be modified to point to the correct
template. That code is below the explanation.

The Templates.LoadBuildingBlocks statement causes Word to load the
templates from the Document Building Blocks folder if they aren't
already members of the Templates collection. (For performance reasons,
building-block-only templates aren't loaded until you open the
organizer, use a building block such as a page number from the ribbon,
or run the LoadBuildingBlocks command in a macro.)

The For loop examines each template in the collection until it finds
one whose name matches the quoted string -- which you'll need to
change from "extra building blocks.dotx" to the name you used for your
template. Making the quoted string all lower case and comparing it to
the result of the LCase function makes the comparison
case-insensitive.

When the loop is done, BBtemplate will point to your template (unless
it wasn't found, in which case BBtemplate will be the special value
Nothing). Then you can insert the desired building block, knowing that
it's a member of the BuildingBlockEntries collection of the template
BBtemplate.

Sub TagNoteTagClick(control As IRibbonControl)
Dim BBtemplate As Template
Dim oTmp As Template

Templates.LoadBuildingBlocks

For Each oTmp In Templates
If LCase(oTmp.Name) = "extra building blocks.dotx" Then
Set BBtemplate = oTmp
Exit For
End If
Next

If Not (BBtemplate Is Nothing) Then
BBtemplate.BuildingBlockEntries("TagNoteTag1").Insert _
Where:=Selection.Range, RichText:=True
End If
End Sub

--
Regards,
Jay Freedman
Microsoft Word MVP
Email cannot be acknowledged; please post all follow-ups to the
newsgroup so all may benefit.


Thank you so much for your insight! #1 works great now!

You're right, the building blocks were in the same template as the macros.
I've moved them to a separate template, and have placed that template in the
Document Building Blocks folder. (As far as I can tell, if I place them
anywhere else, they are not visible on the Quick Parts list!) However, I
still don't quite understand the code needed for question #2 below. [Note,
I'm not a trained programmer! :) ]


My current two macros are:

Sub TagNoteTagClick(control As IRibbonControl)
ActiveDocument.AttachedTemplate.BuildingBlockEntries("TagNoteTag1") _
.Insert Where:=Selection.Range, RichText:=True
End Sub

and

Sub TagNoteTag()
Dim control As IRibbonControl
TagNoteTagClick control
End Sub

I understand that I need to change ActiveDocument.AttachedTemplate to
Templates(ThisDocument.FullName) -- but I'm not sure where I need to specify
the path/doc name that contains the customized building blocks. (I'd like
them to be in a path that can be easily deployed -- perhaps
"%appdata%\Microsoft\Document Building Blocks\ ? They don't seem to appear
in the building block list if I place them anywhere else! The file name is
customBB.dotx.)

I've searched my reference books and online, but cannot locate an example
where the path/file name is specified with the
Templates(ThisDocument.FullName) command. I've experimented with several
possibilities, but have not been successful.

Any suggestions are gratefully appreciated!
Thank you!
Diana




Jay Freedman said:
To answer your first question, the Macros dialog never displays any
procedure that (a) takes parameters, (b) is a Function instead of a Sub,
and/or (c) is declared as Private instead of the default of Public. If you
want to be able to run the same macro from both the ribbon and the Macro
dialog, you need to create another macro without a parameter and have it
call the first one. For the example Greg gave you, try this:

Sub TagNoteTagRun()
Dim control As IRibbonControl
TagNoteTag control
End Sub

I can't give an absolute answer to the second question without seeing the
code of one of the macros, but I suspect it's trying to insert a building
block that's stored in the same template with the macros by using a
statement like

ActiveDocument.AttachedTemplate.BuildingBlockEntries("BB"). _
Insert Where:=Selection.Range, RichText:=True

That works as long as the template is in the Templates folder and you base a
new document on it. When you move the template to the Startup folder,
though, the template is NOT the AttachedTemplate of the ActiveDocument. So
the building block you're trying to insert isn't in the AttachedTemplate of
the ActiveDocument, and the error message is accurate.

To fix this, you need to select the template that does contain the building
block, like this:

Sub TagNoteTag(control As IRibbonControl)
Templates(ThisDocument.FullName).BuildingBlockEntries("BB") _
.Insert Where:=Selection.Range, RichText:=True
End Sub




.
 
D

Dogwoodnc

Thank you! I think this is going to work perfectly! :)



Jay Freedman said:
The code I posted was explicitly and exclusively for the case where
the macros and the building blocks are in the same template. The
reason is that the built-in variable ThisDocument refers to the
document or template containing the macro code that's currently
executing. So the expression Templates(ThisDocument.FullName) returns
the member of the Templates collection that contains the macro -- and
therefore the one that contains the building block you want. When you
split the macros and the building blocks over two templates, you broke
that connection.

For your current arrangement -- which is indeed easier to install and
maintain -- the code needs to be modified to point to the correct
template. That code is below the explanation.

The Templates.LoadBuildingBlocks statement causes Word to load the
templates from the Document Building Blocks folder if they aren't
already members of the Templates collection. (For performance reasons,
building-block-only templates aren't loaded until you open the
organizer, use a building block such as a page number from the ribbon,
or run the LoadBuildingBlocks command in a macro.)

The For loop examines each template in the collection until it finds
one whose name matches the quoted string -- which you'll need to
change from "extra building blocks.dotx" to the name you used for your
template. Making the quoted string all lower case and comparing it to
the result of the LCase function makes the comparison
case-insensitive.

When the loop is done, BBtemplate will point to your template (unless
it wasn't found, in which case BBtemplate will be the special value
Nothing). Then you can insert the desired building block, knowing that
it's a member of the BuildingBlockEntries collection of the template
BBtemplate.

Sub TagNoteTagClick(control As IRibbonControl)
Dim BBtemplate As Template
Dim oTmp As Template

Templates.LoadBuildingBlocks

For Each oTmp In Templates
If LCase(oTmp.Name) = "extra building blocks.dotx" Then
Set BBtemplate = oTmp
Exit For
End If
Next

If Not (BBtemplate Is Nothing) Then
BBtemplate.BuildingBlockEntries("TagNoteTag1").Insert _
Where:=Selection.Range, RichText:=True
End If
End Sub

--
Regards,
Jay Freedman
Microsoft Word MVP
Email cannot be acknowledged; please post all follow-ups to the
newsgroup so all may benefit.


Thank you so much for your insight! #1 works great now!

You're right, the building blocks were in the same template as the macros.
I've moved them to a separate template, and have placed that template in the
Document Building Blocks folder. (As far as I can tell, if I place them
anywhere else, they are not visible on the Quick Parts list!) However, I
still don't quite understand the code needed for question #2 below. [Note,
I'm not a trained programmer! :) ]


My current two macros are:

Sub TagNoteTagClick(control As IRibbonControl)
ActiveDocument.AttachedTemplate.BuildingBlockEntries("TagNoteTag1") _
.Insert Where:=Selection.Range, RichText:=True
End Sub

and

Sub TagNoteTag()
Dim control As IRibbonControl
TagNoteTagClick control
End Sub

I understand that I need to change ActiveDocument.AttachedTemplate to
Templates(ThisDocument.FullName) -- but I'm not sure where I need to specify
the path/doc name that contains the customized building blocks. (I'd like
them to be in a path that can be easily deployed -- perhaps
"%appdata%\Microsoft\Document Building Blocks\ ? They don't seem to appear
in the building block list if I place them anywhere else! The file name is
customBB.dotx.)

I've searched my reference books and online, but cannot locate an example
where the path/file name is specified with the
Templates(ThisDocument.FullName) command. I've experimented with several
possibilities, but have not been successful.

Any suggestions are gratefully appreciated!
Thank you!
Diana




Jay Freedman said:
To answer your first question, the Macros dialog never displays any
procedure that (a) takes parameters, (b) is a Function instead of a Sub,
and/or (c) is declared as Private instead of the default of Public. If you
want to be able to run the same macro from both the ribbon and the Macro
dialog, you need to create another macro without a parameter and have it
call the first one. For the example Greg gave you, try this:

Sub TagNoteTagRun()
Dim control As IRibbonControl
TagNoteTag control
End Sub

I can't give an absolute answer to the second question without seeing the
code of one of the macros, but I suspect it's trying to insert a building
block that's stored in the same template with the macros by using a
statement like

ActiveDocument.AttachedTemplate.BuildingBlockEntries("BB"). _
Insert Where:=Selection.Range, RichText:=True

That works as long as the template is in the Templates folder and you base a
new document on it. When you move the template to the Startup folder,
though, the template is NOT the AttachedTemplate of the ActiveDocument. So
the building block you're trying to insert isn't in the AttachedTemplate of
the ActiveDocument, and the error message is accurate.

To fix this, you need to select the template that does contain the building
block, like this:

Sub TagNoteTag(control As IRibbonControl)
Templates(ThisDocument.FullName).BuildingBlockEntries("BB") _
.Insert Where:=Selection.Range, RichText:=True
End Sub


Dogwoodnc wrote:
Thank you! I'm just now learning Word 2007 (and customizing the
Ribbon with VBA macros), and hadn't run across that parameter yet.
I've added the "control as IRibbonControl" parameter to the macros,
and that has helped tremendously. Clicking on the icons on the
ribbon now correctly invokes the macros based on the building block
text!

Two followup questions:
1. I've noticed that when I add that parameter, the macro is no longer
visible in the list of available macros (Developer>Macro). Is there
a way to make it visible on that list AND on the Ribbon itself?

2. My ultimate goal is to deploy these macros to our entire workgroup.
Historically (in previous versions of Word), we've done this via
placing the template that contains the macros in the Startup folder
-- which has the same path name for everyone, so we haven't had to
create unque sets of macros to compensate for differences in path
names associated with names/corporate ID numbers/etc. However, when
I tested the template in the Startup folder, and then tried invoking
the macros described below, the error message "The requested member
of the collection does not exist" appears. Any suggestions re fixing
this?

THANKS!
I really appreciate your help in journeying along this learning curve!



:

That is the error that is generated if you don't have the parameter
"control as IRibbonControl" set in your onAction callback:

Sub TagNotTag(control As IRibbonControl)

Dogwoodnc wrote:
I've created a customized tab for our workgroup, and would like to
make separate buttons for a few of our custom building blocks. The
building blocks are visible in the Quick Parts listing. I've
recorded macros that retrieve each building block -- the macros work
fine via the Developer>Macro method.

I then tried to insert lines in the RibbonX XML that place icons on
the Ribbon and allow the user to call each macro. Here's a sample
line of code, using the same syntax that I had successfully used for
other macros that don't deal with building blocks:

<button id="TagNote" label=" " onAction="TagNoteTag"
image="TagNoteGraphic"/>

However, when I click the icon on the Ribbon (to invoke the macro),
the following error message appears:
Wrong number of arguments or invalid property assignment.

Might you have any suggestions re what to do in the XML to retrieve
the macro with the building block?

Thanks in advance!
Diana


.


.
.
 
G

Graham Mayor

You could introduce extra code to insert a building block entry from
wherever it is stored see
http://www.gmayor.com/word_vba_examples.htm#Autotext which shows examples
for both Word 2003 and 2007

--
<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
Graham Mayor - Word MVP


<>>< ><<> ><<> <>>< ><<> <>>< <>><<>


Dogwoodnc said:
Thank you so much for your insight! #1 works great now!

You're right, the building blocks were in the same template as the macros.
I've moved them to a separate template, and have placed that template in
the
Document Building Blocks folder. (As far as I can tell, if I place them
anywhere else, they are not visible on the Quick Parts list!) However, I
still don't quite understand the code needed for question #2 below.
[Note,
I'm not a trained programmer! :) ]


My current two macros are:

Sub TagNoteTagClick(control As IRibbonControl)
ActiveDocument.AttachedTemplate.BuildingBlockEntries("TagNoteTag1") _
.Insert Where:=Selection.Range, RichText:=True
End Sub

and

Sub TagNoteTag()
Dim control As IRibbonControl
TagNoteTagClick control
End Sub

I understand that I need to change ActiveDocument.AttachedTemplate to
Templates(ThisDocument.FullName) -- but I'm not sure where I need to
specify
the path/doc name that contains the customized building blocks. (I'd like
them to be in a path that can be easily deployed -- perhaps
"%appdata%\Microsoft\Document Building Blocks\ ? They don't seem to
appear
in the building block list if I place them anywhere else! The file name
is
customBB.dotx.)

I've searched my reference books and online, but cannot locate an example
where the path/file name is specified with the
Templates(ThisDocument.FullName) command. I've experimented with several
possibilities, but have not been successful.

Any suggestions are gratefully appreciated!
Thank you!
Diana




Jay Freedman said:
To answer your first question, the Macros dialog never displays any
procedure that (a) takes parameters, (b) is a Function instead of a Sub,
and/or (c) is declared as Private instead of the default of Public. If
you
want to be able to run the same macro from both the ribbon and the Macro
dialog, you need to create another macro without a parameter and have it
call the first one. For the example Greg gave you, try this:

Sub TagNoteTagRun()
Dim control As IRibbonControl
TagNoteTag control
End Sub

I can't give an absolute answer to the second question without seeing the
code of one of the macros, but I suspect it's trying to insert a building
block that's stored in the same template with the macros by using a
statement like

ActiveDocument.AttachedTemplate.BuildingBlockEntries("BB"). _
Insert Where:=Selection.Range, RichText:=True

That works as long as the template is in the Templates folder and you
base a
new document on it. When you move the template to the Startup folder,
though, the template is NOT the AttachedTemplate of the ActiveDocument.
So
the building block you're trying to insert isn't in the AttachedTemplate
of
the ActiveDocument, and the error message is accurate.

To fix this, you need to select the template that does contain the
building
block, like this:

Sub TagNoteTag(control As IRibbonControl)
Templates(ThisDocument.FullName).BuildingBlockEntries("BB") _
.Insert Where:=Selection.Range, RichText:=True
End Sub


--
Regards,
Jay Freedman
Microsoft Word MVP
Email cannot be acknowledged; please post all follow-ups to the newsgroup
so
all may benefit.




.
 

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