Reload Ribbon

R

Ron

I have quite few custom ribbons created and the way to be able to invalidate
ribbons or controls on the ribbon is to set the ribbon object to a variable
like this.

Sub CallbackOnLoad(ribbon As IRibbonUI)

' Callback onLoad.
Set gobjRibbon = ribbon

End Sub

The CallBackonLoad of course is in the source xml file of the ribbon.
Anyway, whenever my access app encounters an error, the gobjRibbon object get
wiped out. Is there any way to call this function again? It's only called
when the ribbon is first activated so the only I can do is close the
application and re-open it again. I need to know how to call this function
again so that the gobjRibbon is reloaded.
 
A

Albert D. Kallal

This is pet peeve of mine.

This problem extends to all of office, not just ms-access. On the other
hand, excel, or word applications are likely to have one custom ribbon.

In ms-access, we could potentially have LOTS of ribbons.

There are two solutions

1). Don't use any call backs, and then your never have to worry about having
a reference to the ribbon available. This is not as crappy as an answer as
one would think (I open to being bonked on the head with a frying pan is you
disagrees however!!). In many cases, you really don't need call backs. in
place of disabling a button, simply have the button give the user a message
as to why the button is not available, or even better tell the user WHAT
they must do before the button is enabled. I can try to make a case that
this is user friendly.

2) use a global collection of ribbons, and add to that collection for each
on-load.

eg:

Public Sub MyRibbonLoad(ByRef nribbonUI As Office.IRibbonUI)

Dim colNewRib As New clsRibbon

colNewRib.name = f.name
Set colNewRib.m_ribbon = nribbonUI
colRibbons.Add colNewRib, f.name

Set f.MyRibbon = colNewRib

Set f = Nothing

End Sub

f is global from variable that I set in the forms on-load event. so, i go:

Call SetMyRib(Me)

And, my SetMyRib code is:

Public Sub SetMyRib(frm As Form, Optional strRibbonName As String = "")

Dim i As Integer

Set f = frm ' needed global from ref for MyRibbonLoad Call back

If strRibbonName = "" Then
strRibbonName = frm.name
End If

For i = 1 To colRibbons.Count
If colRibbons(i).name = frm.name Then
Set frm.MyRibbon = colRibbons(i)
Exit For
End If
Next i

frm.RibbonName = strRibbonName

End Sub

So, the only solution is to keep a global collection. There is no way to
force a re-load. I do think that like we have forms(), reprots(), there
should be a global ribbon collection exposed, and this problem would be done
with.....

I certainly am voting..and pushing for this feature in the next version of
office....
 
R

Ron

K, I'm kind of with you. I don't have much experience w/ classes but here is
what I have. I have created a new class module called clsRibbon. Inside it
I have the following:

Option Compare Database
Option Explicit

Public m_ribbon As IRibbonUI
Public Name As String

Next I have modified my RibbonOnLoad procedure like the following per your
sample


Sub CallBackLeaseView(ribbon As IRibbonUI)
'Set gLeaseViewRibbon = ribbon

Dim colNewRib As New clsRibbon
Dim colRibbons As New Collection

colNewRib.Name = f.Name
Set colNewRib.m_ribbon = ribbon
colRibbons.Add colNewRib, f.Name
Set f.MyRibbon = colNewRib
Set f = Nothing
End Sub

My question is where does the MyRibbon object come into play? Where is it
set? As well as the m_ribbon? And where is f set?

Moving on I have inserted SetMyRib procedure (again where does the MyRibbon
come from?)

Finally I'm calling SetMyRib from the form's OnLoad event.

One more thing, your sample looks like it will re-load a ribbon based off of
the name of the form. I have a ribbon that is used throughout multiple
forms. How would that work?

Thanks for your help again. I hope this is clear.
 
A

Albert D. Kallal

been too busy to post my example:, but here is my class object the bibbon

-->this is a class moddule called clsRibbon

Option Compare Database
Option Explicit

Public colControls As New Collection
Public m_ribbon As IRibbonUI
Private m_name As String

Public Property Get Controls(strC As String, Optional strRib As String = "")
As clsRibContorl

Dim i As Integer
Dim intGotOne As Integer
Dim NewControl As New clsRibContorl
' look for contorl in colleciton, if not in, then add...
For i = 1 To colControls.Count
If strC = colControls(i).name Then
intGotOne = i
Exit For
End If
Next i

If intGotOne = 0 Then
' add contorl, set defaults
NewControl.enabled = True
NewControl.visible = True
NewControl.Label = ""
NewControl.name = strC
colControls.Add NewControl, strC

Set Controls = NewControl
Else

Set Controls = colControls(intGotOne)
End If

Me.m_ribbon.InvalidateControl (strC)


End Property


Public Property Get MyControls(strC As String) As clsRibContorl

Dim i As Integer
Dim intGotOne As Integer
Dim NewControl As New clsRibContorl
' look for contorl in colleciton, if not in, then add...
For i = 1 To colControls.Count
If strC = colControls(i).name Then
intGotOne = i
Exit For
End If
Next i

If intGotOne = 0 Then
' add contorl, set defaults
NewControl.enabled = True
NewControl.visible = True
NewControl.Label = ""
NewControl.name = strC
colControls.Add NewControl, strC

Set MyControls = NewControl
Else

Set MyControls = colControls(intGotOne)

' If bolLoad = False Then
' Me.m_ribbon.InvalidateControl (strC)
' Me.m_ribbon.Invalidate
' End If
End If


End Property


Public Property Get name() As String

name = m_name

End Property

Public Property Let name(str As String)

m_name = str

End Property

--------------------

And, I also have a class for the contorl, it is called clsRibContorl

Option Compare Database
Option Explicit

Dim m_enabled As Boolean
Dim m_visible As Boolean
Dim m_Label As String
Dim m_name As String



Public Property Let enabled(bol As Boolean)

m_enabled = bol

End Property

Public Property Get enabled() As Boolean

enabled = m_enabled

End Property

'-----------

Public Property Let visible(bol As Boolean)

m_visible = bol

End Property

Public Property Get visible() As Boolean

visible = m_visible

End Property

Public Property Let Label(str As String)

m_Label = str

End Property

Public Property Get Label() As String

m_Label = m_Label

End Property

Public Property Get name() As String

name = m_name

End Property

Public Property Let name(str As String)

m_name = str

End Property

------

And, our standard code in a regular module (basRibbon) is:

Option Compare Database
Option Explicit

Public colRibbons As New Collection

Private f As Form

Public Sub SetMyRib(frm As Form, Optional strRibbonName As String = "")

Dim i As Integer

Set f = frm ' needed global from ref for MyRibbonLoad Call back

If strRibbonName = "" Then
strRibbonName = frm.name
End If

For i = 1 To colRibbons.Count
If colRibbons(i).name = frm.name Then
Set frm.MyRibbon = colRibbons(i)
Exit For
End If
Next i

frm.RibbonName = strRibbonName

End Sub


Public Sub MyRibbonLoad(ByRef nribbonUI As Office.IRibbonUI)

Dim colNewRib As New clsRibbon

colNewRib.name = f.name
Set colNewRib.m_ribbon = nribbonUI
colRibbons.Add colNewRib, f.name

Set f.MyRibbon = colNewRib

Set f = Nothing

End Sub

Public Sub MyVisible(control As IRibbonControl, _
ByRef visible As Variant)
Dim f As Form

If Forms.Count > 0 Then
Set f = Screen.ActiveForm
visible = colRibbons(f.name).MyControls(control.ID).visible
End If

End Sub


Public Sub MyEnable(control As IRibbonControl, _
ByRef visible As Variant)
Dim f As Form

Set f = Screen.ActiveForm

visible = colRibbons(f.name).MyControls(control.ID).enabled


End Sub


Now, for any form, do NOT use the "other tab" to set the ribbion, but in the
forms on-load go:

Call SetMyRib(Me)

Now, to enable, or make vistiatl any contorl inthe menu bar, you simply go:

MyRibbon.Controls("button1").enabled = True

or

MyRibbon.Controls("button1").enabled = false

So, you can now enable, disable any control in the ribbon you please. Note
that the above also allows you to specify a ribbon name

MyRibbon.Controls("button1", "name of ribbon").enabled = false

If you leave it blank, it assumes the current form name for the ribbon.

For ANY control that you need enable/disable, you add to the xml:

<button id="button1" label="Buttion1"
getVisible="MyVisible"
getEnabled="MyEnable"
onAction="=MyTest1()" />

the beauty of this whole system is that you don't need to write any
additional code for each new ribbon control that you want to enable, or
disable, or visible.

I just simply too busy to write up this code, document it, and post an
example. I will do so ASAP....

However, the above should get you going if you want a "general" solution for
all ribbons and not have to write additional code for each control....
 
R

RD

Hi Albert,

I have to say, sometimes your replies border on poetry.

;-)
RD
"I open to being bonked on the head with a frying pan is you disagrees
however!!"
 

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