My Assistant
![]()
Custom Search
|
![]() ![]() |
![]() |
![]() 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. |
![]() 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 |
![]() 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. |
![]() 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 |
![]() 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. |
![]() 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? -------------------- |
![]() 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 |
![]() 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 |
![]() 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 |
![]() 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 ![]() There is a mistake in the (air) code I posted though ![]() 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 |
![]()
Custom Search
|
![]() | Search Top Lo-Fi | 7th December 2019 - 01:07 AM |