Group: microsoft.public.word.vba.general
From: "Greg Maxey"
Date: Friday, February 29, 2008 7:33 PM
Subject: Re: Ribbon Customizatin AddIn

JGM,

Thanks for your interest and your comments.

I share your dislike for allowing the end user direct access to the
template. Your suggestion gave me and idea but even your suggestion and my
idea ultimately allows the user to edit the template. I suppose that I
could have the table of data in a separate document but since this whole
exercise was to try to gain a little mastery over Ribbon customization vice
building a robust template Add-In, I think I am going to go with a variation
of your idea.

I decided to add a toggle button control to the Ribbon. The initial state
is "Edit Proofreader Marks List" and the toggled state is "Save changes."

BTW I hope that by the time you get around to playing with this stuff that
you don't experience the same hair pulling frustrations that I have.
Getting the correct images, labels, and states set on a Toggle Button was
gruelling exerience ;-)

Clicking the TB opens the template as document allowing the user to make
their desired changes. I put plenty of Warnings, Cautions, and Notes in the
template so hopefully no one should break it unless they want to. When the
user is finished with the changes then they click the "Save changes" toggle.
The arrays are are rebuilt, the Ribbon revalidates and the changes appear in
the dropdown. Seems to work.

I am going to tinker with this a few more days and then perhaps post it as a
working example of Ribbon Customization on my website. I am including the
current code for you and anyone else that is interested. I might have your
e-mail address lying around or if you want send me a message and I will
attach the template as a reply.

Thanks again.

Option Explicit
Public myRibbon As IRibbonUI
Private myArrayPri() As String
Private myArraySec() As String
Private myArrayTri() As String
Private oDocTemp As Word.Document
Private pImage As String
Private bLabelState As Boolean

Sub Onload(ribbon As IRibbonUI)
Set myRibbon = ribbon
End Sub

Sub GetImage(control As IRibbonControl, ByRef image)
Select Case control.id
Case "TB1"
If pImage = "" Then pImage = "FileOpen"
image = pImage
Case Else
'Do Nothing
End Select
End Sub

Sub GetPressed(control As IRibbonControl, ByRef returnValue)
Select Case control.id
Case "TB1"
If pImage = "" Then pImage = "FileOpen"
If pImage = "FileOpen" Then
returnValue = False
Else
returnValue = True
End If
Case Else
'Do nothing
End Select
End Sub

Sub ToggleOnActionMacro(ByVal control As IRibbonControl, bToggled As
Boolean)
If bToggled Then
pImage = "FileClose"
EditPRMarks
LoadArrays
bLabelState = False
Else
pImage = "FileOpen"
SavePRMarksChanges
bLabelState = True
End If
myRibbon.InvalidateControl control.id
myRibbon.Invalidate
End Sub

Sub MyDDMacro(ByVal control As IRibbonControl, selectedId As String,
selectedIndex As Integer)
Dim oFrm As UserForm1
Dim pUserInt As String
Select Case control.id
Case "DD1"
If Documents.count < 1 Then
myRibbon.InvalidateControl control.id
Exit Sub
End If
If Selection.Type = wdSelectionIP Or wdNoSelection Then
MsgBox "Please select the proofreading error in the text before
inserting comments."
myRibbon.InvalidateControl control.id
Exit Sub
End If
Select Case selectedIndex
Case Is = 0
'Do Nothing
Case Else
pUserInt = Application.UserInitials
Set oFrm = New UserForm1
oFrm.TextBox1 = myArraySec(selectedIndex)
With oFrm.TextBox1
.SetFocus
.SelStart = 0
.SelLength = Len(.Text)
End With
oFrm.Show
If oFrm.Tag = 1 Then
Application.UserInitials = myArrayPri(selectedIndex)
Selection.Comments.Add Selection.Range, oFrm.TextBox1.Text
End If
Unload oFrm
Set oFrm = Nothing
Application.UserInitials = pUserInt
myRibbon.InvalidateControl control.id
End Select
Case Else
'Do Nothing
End Select
End Sub

Sub GetLabel(ByVal control As IRibbonControl, ByRef label)
Select Case control.id
Case "TB1"
If bLabelState Then
label = "Edit Proofreading Marks List"
Else
label = "Save changes"
End If
Case Else
'Do Nothing
End Select
End Sub

Sub GetSelectedItemIndex(ByVal control As IRibbonControl, ByRef Index)
Select Case control.id
Case "DD1"
Index = 0
Case Else
'Do nothing
End Select
End Sub

Sub GetItemLabel(ByVal control As IRibbonControl, Index As Integer, ByRef
label)
Select Case control.id
Case "DD1"
label = myArrayPri(Index)
Case Else
'Do nothing
End Select
End Sub

Sub GetItemScreenTip(ByVal control As IRibbonControl, Index As Integer,
ByRef screentip)
Select Case control.id
Case "DD1"
screentip = myArrayTri(Index)
Case Else
'Do nothing
End Select
End Sub

Sub GetItemCount(ByVal control As IRibbonControl, ByRef count)
On Error Resume Next
If IsNull(myArrayPri(0)) Then
LoadArrays
End If
On Error GoTo 0
Select Case control.id
Case "DD1"
count = UBound(myArrayPri)
Case Else
'Do Nothing
End Select
End Sub

Function GetErrorArray(ByVal oTbl As Table) As String()
Dim i As Long
Dim tempArray() As String
ReDim tempArray(oTbl.Rows.count)
For i = 1 To oTbl.Rows.count
tempArray(i - 1) = Left(oTbl.Cell(i, 1).Range.Text, Len(oTbl.Cell(i,
1).Range.Text) - 2)
Next i
GetErrorArray = tempArray
End Function

Function GetDescriptiveArray(ByVal oTbl As Table) As String()
Dim i As Long
Dim tempArray() As String
ReDim tempArray(oTbl.Rows.count)
For i = 1 To oTbl.Rows.count
tempArray(i - 1) = Left(oTbl.Cell(i, 2).Range.Text, Len(oTbl.Cell(i,
2).Range.Text) - 2)
Next i
GetDescriptiveArray = tempArray
End Function

Function GetScreenTipArray(ByVal oTbl As Table) As String()
Dim i As Long
Dim tempArray() As String
ReDim tempArray(oTbl.Rows.count)
For i = 1 To oTbl.Rows.count
tempArray(i - 1) = Left(oTbl.Cell(i, 3).Range.Text, Len(oTbl.Cell(i,
3).Range.Text) - 2)
Next i
GetScreenTipArray = tempArray
End Function

Sub AutoOpen()
LoadArrays
End Sub

Sub LoadArrays()
Dim aTemplate As Template
Dim oDoc As Word.Document
Dim oTbl As Table
bLabelState = True
For Each aTemplate In Templates
If aTemplate.Name = "Proofreading Marks AddIn.dotm" Then
Set oDoc = Documents.Add(aTemplate.FullName, , , False)
Set oTbl = oDoc.Tables(1)
myArrayPri() = GetErrorArray(oTbl)
myArraySec() = GetDescriptiveArray(oTbl)
myArrayTri() = GetScreenTipArray(oTbl)
oDoc.Close wdDoNotSaveChanges
Exit For
End If
Next
End Sub

Sub EditPRMarks()
Dim aTemplate As Template
Dim oTbl As Table
For Each aTemplate In Templates
If aTemplate.Name = "Proofreading Marks AddIn.dotm" Then
Set oDocTemp = aTemplate.OpenAsDocument
End If
Exit For
Next
End Sub

Sub SavePRMarksChanges()
Dim oTbl As Table
If Not oDocTemp Is Nothing Then
With oDocTemp
Set oTbl = .Tables(1)
myArrayPri() = GetErrorArray(oTbl)
myArraySec() = GetDescriptiveArray(oTbl)
myArrayTri() = GetScreenTipArray(oTbl)
.Save
.Close
End With
End If
End Sub

The UserForm code:

Option Explicit
'OK Btn
Private Sub CommandButton1_Click()
Me.Tag = 1
Me.Hide
End Sub
'Cancel Btn
Private Sub CommandButton2_Click()
Me.Tag = 0
Me.Hide
End Sub





--
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org
Word MVP web site http://word.mvps.org
~~~~~~~~~~~~~~~~~~~~~~~~~~~~



Jean-Guy Marcil wrote:
> "Greg Maxey" wrote:
>
>> This is a long post with multiple questions. Please don't be
>> discouraged and feel free to answer all or part. Thank you.
>>
>
> I have not really worked with 2007 VBA or XML yet... In fact, I have
> looked into 2007 because I was curious, but my working environment
> has not yet allowed me to really take the plunge yet...
> As I read your post, something did occur to me, and I tought that it
> might be of interest to you, so here we go!
>
>>
>> 1. I am not very confident of my process for populating the two
>> arrays with the data needed for the callbacks. My goals is to find
>> the simplest way to make the data customizable to the user and
>> accessible to the the callback. By putting the data in a table
>> contained in the template. All the user needs to do is open the
>> template and edit the table. Once that is done, then when the
>> template loads the the compiler has to get to it. AutoExec is the
>> only event that I know of that fires when a template is loaded. Is
>> this correct and is this the best way?
>>
>
> I do not like the idea of telling users to open a template... Too many
> things could go wrong...
>
> If I were developping such a customizable tool. I would include a
> Ribbon button called "Customize Entries" (or whatever is
> appropriate). The button would get the information from the template,
> display it in a table in a new unsaved document, then the user would
> edit that document. this document, when active, would have something
> like a MACROBUTTON labelled "Done" or some such label (I guess it
> could be an ActiveX button instead). The user would click on that to
> save the changes back to the template. (Or the button could be on the
> Ribbon instead, excepts that this is more difficult becasue if the
> user decides to give up and not close the document properly or in an
> unexcepted way, you may be stuck with a useless Ribbon button).
> Finally, since you already have the code to populate the dropdowns on
> the ribbon, I guess you would need to execute that code to update the
> ribbon as soon as the user has finished updating the data.
>
> Just my 2 cents!