UtterAccess.com
X   Site Message
(Message will auto close in 2 seconds)

Welcome to UtterAccess! Please ( Login   or   Register )

Custom Search
 
   Reply to this topicStart new topic
> Hide A Button On A Custom Ribbon, Access 2016    
 
   
Raas
post Jun 27 2019, 02:26 PM
Post#1



Posts: 639
Joined: 27-January 07
From: Northern Arizona


I have read all of the posts that seemed to pertain to this subject, but none of them (at least I couldn't find any) address the hiding of a button in a custom ribbon that doesn't use the global callbacks. I have followed Albert's suggestions that the ribbon should be and could be placed directly in the form rather than using callbacks all the time. So, I need to hide a button from a ribbon that is loaded from a form, based on administrative permissions settings. Hopefully that is explanatory enough to get me some help on this issue.

I have, in the past, and could do so again, created global callbacks and used the invalidate in order to hide a button and groups. Wanted to learn how to do it this other way.

Thanks,


Using Access 2019, by-the-way.
Go to the top of the page
 
pere_de_chipstic...
post Jun 27 2019, 03:18 PM
Post#2


UtterAccess Editor
Posts: 10,514
Joined: 8-November 07
From: South coast, England


Hi Raas

>> the ribbon should be and could be placed directly in the form <<
I am not sure what you mean by this, the ribbon is the ribbon and is separate from the form (well at least to 2016!) Could you explain / post the link to Albert's suggestion as I am curious!

The only way I'm aware of to hide (or disable) a ribbon control is through the getVisible / getEnabled callbacks.

--------------------
Warm regards
Bernie
Go to the top of the page
 
Raas
post Jun 27 2019, 06:14 PM
Post#3



Posts: 639
Joined: 27-January 07
From: Northern Arizona


I create the XML ribbon file as usual, but instead of doing callbacks, I place the ribbon in the form under the 'other' tab and the Ribbon Name. When the form is loaded, the ribbon fires. I can have a new ribbon for each form, as I want, or not. The ribbon referred to does have all the xml code in it, but I don't call a callback function. I'll get Albert's article when I get home, and I'll post as much as I think I can without violating his copyright to his work.
Go to the top of the page
 
Raas
post Jun 27 2019, 06:21 PM
Post#4



Posts: 639
Joined: 27-January 07
From: Northern Arizona


Found it. Since it was in answer to a question I had about ribbons some time ago, and he posted his reply to the forum, then there should be no problems with posting again:


Answer

Albert D. Kallal replied on
• MVP

This is actually a great question!

And the answer is you can actually choose to use a function() and when you do so you are not actually using a call back, but the Access expression service.
And if you use a function (and not a call back), then you can in fact place the code (function) in the forms code module. Often if you had a few buttons on a form this suggests that such code belongs in the form. If you want to now move those buttons out of the form up to a custom ribbon, then again by using functions, then you can keep/leave that code in the form's code module where it belongs.
However, if you use a call back, then you MUST place the code in a standard code module and this is often where you don't want the code. However, for "global" code routines then of course you would (and want) to place the code in a standard code module and not in a form's code module.
Ok, so now let's point out the difference between a call back and that of a function.
In general, if you use a function, you also find it tends to be less work. And you also can use the ribbon to pass values.
Here is some ribbon XML that uses a function:
XML:
<button id="OpenSP1" imageMso="ViewsReportView" label="SP1"
screentip="Open a standard reporting panel" size="large"
onAction="=MyTest()"
/>

If you look close, note how I place the = and () under the quotes. (this is important).
The above is thus a function call. This means the code can be placed in a form. All you write is thus this:
VBA:
Public Function MyTest()
DoCmd.OpenForm "Sales Reports Dialog"
End Function

Note how in the above the public function does not have parameters. This approach is really nice for a form, since the public function in question can be placed in the form where it belongs, and not in some public code module as the ribbon call back has to be.
And note in above. You do not use "sub", but a function. And note how you don't have to pass anything like IRibbon or ANY parameters.

In fact, you can pass you own custom params like this if you want:

XML:
<button id="OpenSP1" imageMso="ViewsReportView" label="Sales Report"
screentip="Open Report for sales" size="large"
onAction="=MyOpenReport('rptSales')"
/>

Note the single quotes, and the value I pass. Then your function is this:
VBA:
Public Function MyOpenReport(strReport as string)
DoCmd.OpenReport strReport,acViewPreview
End Function

The above means that many ribbons can open reports and you only written ONE public report function. So keep in mind this is NOT a callback, but you using public functions. Also note how I had to use single quotes in the above xml as to not mess up the double quotes.
If you drop the = and the () in the above on Action, then you using a call back and you must use a Sub in VBA and you must place the code in a standard code module.
Note that if you have one ribbon, and 5 forms, each with a public function, then the public function in the form that has the current focus means that code will be called (so each form can have a function that is custom, but one ribbon will call the correct sub based on what form has the focus.
Also, the above syntax is also the same syntax you would have used with custom menu bars. So if you migration from menu bars to ribbon, then the above means your existing form code etc. will work with the ribbon now.

So a great question on your part. And the answer is you have a choice, and I recommend that you use functions, since they can be in the form, and as above shows, you can easy pass values.

Albert D. Kallal (Access MVP)
Edmonton, Alberta Canada

Go to the top of the page
 
Raas
post Jun 27 2019, 06:22 PM
Post#5



Posts: 639
Joined: 27-January 07
From: Northern Arizona


Reading his information again, I may have decided on a strategy that might work. I'll try in out and if it works I'll post the answer. In the meantime, my original question still stands. Hopefully that helps.

Go to the top of the page
 
PhilS
post Jun 28 2019, 07:30 AM
Post#6



Posts: 650
Joined: 26-May 15
From: The middle of Germany


QUOTE
I have, in the past, and could do so again, created global callbacks and used the invalidate in order to hide a button and groups. Wanted to learn how to do it this other way.

Have you tried to use a function for the getVisible callback-event of your ribbon button?

--------------------
Go to the top of the page
 
pere_de_chipstic...
post Jul 1 2019, 11:02 AM
Post#7


UtterAccess Editor
Posts: 10,514
Joined: 8-November 07
From: South coast, England


Hi Raas

Have you found a solution?

Albert's suggestion I believe only applies to the OnAction part of an XML ribbon control and is particularly useful where many forms have a common ribbon but the actual function is dependent on the form that is open when the function is called.

With the ribbon getVisible / getEnabled commands (or any command that passes the xml ID identifier) then I think you will have to use callbacks as the value (e.g. Visible = true / false) needs to be returned to, and interpreted by) the ribbon - which a function call doesn't do.

In my ribbon I use the same callback sub for all ribbon getVisible commands (and similarly for getEnabled commands)

Then use a case statement to differentiate the calling control in the callback sub e.g.

CODE
Sub RbnGetVis(ctrl As IRibbonControl, ByRef Visible)
On Error GoTo err_proc
    
Select Case ctrl.ID
Case "Command1ID", "Command2ID", "Command3ID"
     Visible = TempVars!AccessLevel > 3

Case "Command4ID", "Command5ID"
     Visible = TempVars!AccessLevel > 4

Case "Command7ID", "Command8ID", "Command9ID"
     Visible = TempVars!AccessLevel > 5

Case "Command10ID"
     Visible =xxx    'Some other criteria

End Select

exit_proc:
    Exit Sub

err_proc:
    MsgBox err.Description
    Resume exit_proc
End Sub



hth

--------------------
Warm regards
Bernie
Go to the top of the page
 
Raas
post Jul 1 2019, 12:58 PM
Post#8



Posts: 639
Joined: 27-January 07
From: Northern Arizona


I did. I worked on it this weekend and it works. What I did was to create two custom ribbons. One has all of the XML buttons in it that administration uses. The other has only the buttons that non-administrative users can use. Then I simply enter the VBA to change the ribbons on-the-fly in the form by executing the command in the on load event for the form. I change the Ribbon Name property to the ribbon I want based on the login credentials of the user. Not the way I wanted to accomplish the task (always looking for new or better ways to do something), but it works seamlessly. Of course, I still have to use callbacks for some of the functions in the XML. Don't know how to not, and maybe there is no way.

me.ribbonName = "AdminRibbon"

or

me.ribbonName = "UserRibbon"

Anyway, that's my solution at the moment. I still would like to do an invalidate on a tab so that I only use the one ribbon. I'll still work with that for a while, so if anyone has any more insight, let me know please.

I'm going to try to incorporate your example given above. That actually looks pretty simple as a solution. THANKS
This post has been edited by Raas: Jul 1 2019, 12:59 PM
Go to the top of the page
 
pere_de_chipstic...
post Jul 1 2019, 01:03 PM
Post#9


UtterAccess Editor
Posts: 10,514
Joined: 8-November 07
From: South coast, England


Hi Raas

Having user access level dependent ribbons is certainly a way of limiting access to ribbon commands to different access levels. I did use this method, but eventually decided against it as it implied maintaining as many different custom ribbons as there were access levels!

--------------------
Warm regards
Bernie
Go to the top of the page
 
pere_de_chipstic...
post Jul 1 2019, 01:25 PM
Post#10


UtterAccess Editor
Posts: 10,514
Joined: 8-November 07
From: South coast, England


Hi Raas

>>I'm going to try to incorporate your example given above. That actually looks pretty simple as a solution. THANKS<<
You're very welcome thumbup.gif

There is a mistake in the (air) code I posted though blush.gif

TempVars are strings rather than numeric so code would be better as (e.g.)
CODE
Sub RbnGetVis(ctrl As IRibbonControl, ByRef Visible)
On Error GoTo err_proc
Dim intAccLevel as Byte    

intAccLevel = CByte(TempVars!AccessLevel)

Select Case ctrl.ID
Case "Command1ID", "Command2ID", "Command3ID"
     Visible = intAccLevel > 3

Case "Command4ID", "Command5ID"
     Visible = intAccLevel > 4

Case "Command7ID", "Command8ID", "Command9ID"
     Visible = intAccLevel > 5

Case "Command10ID"
     Visible =xxx    'Some other criteria

End Select

exit_proc:
    Exit Sub

err_proc:
    MsgBox err.Description
    Resume exit_proc
End Sub


Cheers

--------------------
Warm regards
Bernie
Go to the top of the page
 


Custom Search


RSSSearch   Top   Lo-Fi    7th December 2019 - 01:07 AM