使用自定义功能区时,是否可以阻止MS Access自动更改选定的功能区选项卡?

时间:2012-06-18 21:04:44

标签: ms-access access-vba ribbon office-2010

使用自定义UI XML文件在Access中添加多个自定义功能区选项卡时,只要表单关闭,选定功能区选项卡就会更改回第一个自定义选项卡。

我们以编程方式从VBA加载自定义功能区。我创建了an accdb that reproduces the problem。该文件夹还包含一个包含功能区定义的XML文件。它必须与.accdb文件位于同一目录中。

问题很容易证明:

  1. 打开数据库RibbonTest.accdb,
  2. 使用功能区上的按钮切换到Tab2并打开Form2,然后
  3. 关闭Form2。
  4. 请注意,Tab1现在处于活动状态。

    当然,在这个小例子中db这个问题似乎很小。但是,我们有一个非常大的项目,包含许多自定义选项卡,每个选项卡包含许多组和按钮。我们的用户发现非常令人沮丧的是,他们每次关闭表格时都会在彩带上丢失位置。

    我们调查了一种解决方法,我们以编程方式存储选定的标签,并在我们认为需要时将其恢复。然而,证明难以可靠地做到这一点。 (没有像这样自动化功能区的Office API,但是this article helped。)

    还有其他人遇到过这个问题吗?您是否找到了阻止标签自动更改的方法?

    修改:似乎此问题是在Office 2010 SP1 中实施的修复程序中引入的。 (对不起,没有链接:不要认为我可以有两个以上。)RTM版本中没有问题。 SP1的修复列表包括:“当用户返回到该对象时,Access不会激活或将用户返回到先前打开的数据库对象的正确功能区选项卡。”看起来他们已经尝试修复Form.RibbonName属性(它支持上下文功能区)的使用,但是在此过程中打破了默认功能区。

6 个答案:

答案 0 :(得分:6)

这一行解决了这个问题:

<tab id="tabBogus" label="Bogus" visible="false"></tab>

只需将其设为<tabs>中的第一个标签即可。非常感谢Scott的潜在解决方案答案!! (尝试投票和/或评论,但刚刚注册,因此没有足够的声誉。)这节省了工作时间(或几天)与其他复杂的解决方法!谢谢!

答案 1 :(得分:4)

潜在的解决方法

我偶然发现的一件事就是使用可见标签隐藏XML中的第一个标签。我没有对它进行过多次测试,但我有一个隐藏的标准Home选项卡的副本(不知道它是否需要是一个填充的选项卡)。在我看来,由于Access在关闭表单时无法实际激活隐藏选项卡,因此它仍保留在当前选定的表单上。

我不知道这是否已在Access 2013中修复,但希望这些信息对于某人来说还不算太晚。

答案 2 :(得分:2)

这是一个错误!

MS支持已接受此错误提交,并对Office 2010 SP1发表评论,“实施的更改允许我们使用选项卡的TCID跟踪每个数据库对象(表单,报表等)的活动选项卡,以便当您在对象之间移动时,活动选项卡将被恢复。但是,自定义选项卡都使用相同的TCID值,因此通过此更改自定义选项卡的活动选项卡将始终移至第一个自定义选项卡。

我们希望他们将来会发布一个修补程序来解决这个问题。

的变通方法

以下信息对我们在创建变通方法时非常有用。

  1. 请参阅上述Johanness关于IRibbonUI.ActivateTab方法的答案。这是在Office 2010中引入的。
  2. 没有用于获取当前所选选项卡的Office API(AFAIK)。因此,我们使用来自this article的代码很有帮助。我们
    • 在生成包含每个功能区选项卡的id值的功能区时创建一个数组
    • 句柄Form_Deactivate并使用它以另一种隐藏形式启动计时器,并存储所选标签的索引,
    • 在隐藏表单的Timer_Tick处理程序中,我们禁用了计时器并查找我们存储在id中的索引的选项卡的Form_Deactivate值,并且
    • 使用IRibbonUI.ActivateTab激活标签。
  3. This article显示了IRibbonUI.InvalidategetVisible回调的有趣用法,用于选择特定标签。

答案 3 :(得分:1)

似乎有办法获取所选标签(正如您所提到的,可能已经有代码,并且您可以找到here

在RibbonCode模块中:  将ribbonObject保存到模块变量:   在xml中更改第一行:

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onload="OnRibbonLoad" >

并添加:

Private MyRibbon as IRibbonUI
Private ActiveRibbonTab as string

Sub OnRibbonLoad(ribbon As IRibbonUI)
  Set MyRibbon = ribbon
End Sub

Sub RememberRibbonTab
  ActiveRibbonTab=<Do the IAccessibleMagic here>   
End

Sub RecallActiveTab
  If ActiveRibbonTab<>"" then MyRibbon.ActivateTab(ActiveRibbonTab)
  ActiveRibbonTab=""
End

现在以各种形式添加

Private Sub Form_Close()
  Remember_RibbonTab
End Sub

Private Sub Form_GotFocus()
  RecallActiveTab
End Sub

答案 4 :(得分:1)

在与功能区选项卡编号(ALT + Y)对应的通用代码模块中创建枚举器变量

' Used By Send Keys to Select Correct Ribbon Tab.
Enum eRibTabs
    DataEntry = 1
    Reporting = 2
    StockAndParts = 3
    AdminFinance = 4
    DataImport = 5
    OtherAdmin = 6
    Admin = 7
    LocalSystem = 8
End Enum

在ms访问中创建一个名为&#34; zFrmRibbonSelect&#34;并放入一个名为txtTabValue的未绑定文本框,然后将以下代码放入新表单中。 (建议将表单模式设置为隐藏。

Private Sub Form_Current()
' Select Correct Tab Menu Item
Me.txtTabValue = Me.OpenArgs

End Sub

Private Sub Form_Close()
'Select Correct Tab Menu Item
Dim varTab As Variant

varTab = Me.txtTabValue

SendKeys "%Y" & varTab
SendKeys "{ESC}"
SendKeys "{ESC}"

End Sub

Private Sub Form_Timer()
DoCmd.Close acForm, Me.Name, acSaveNo
End Sub

将表单计时器间隔设置为500,并检查属性框中的计时器显示事件等。

在您的报告中输入以下代码:(使用您想要的枚举值。)

Private Sub Report_Close()
'Select Correct Tab Menu Item
 DoCmd.OpenForm "zFrmRibbonSelect", , , , , acHidden, eRibTabs.StockAndParts
End Sub

对于关闭的表单,在表单

中使用以下代码
Private Sub Form_Close()
'Select Correct Tab Menu Item
    SendKeys "%Y" & eRibTabs.StockAndParts
    SendKeys "{ESC}"
    SendKeys "{ESC}"
End Sub

答案 5 :(得分:0)

实际上,一种效果很好的方法是减少或消除您打开的表单中的选项卡。如果指定功能区(属性表中的其他选项卡),则在表单之间切换时,显示的功能区会自动切换,无需代码。

现在虽然这不是你的问题的真正解决方案,但这里的想法和概念是,如果你必须开始编写一堆代码来参与并切换到什么标签,那么当你指出这真的变得困难时。

如Access / office 2010所述,您可以使用代码设置活动标签(此功能在Access / Office 2007中不可用)。

所以关于我在这里的唯一建议是尝试并尽可能将大多数表单限制为一个选项卡。另一个提示是,虽然在菜单中可能会按“任务类型”进行分组,因此您可能会有一个级联到一大堆报告的菜单。现在使用功能区处理发票时,您可以:

Create invoice
Balance invoice
Post invoice
Print invoice (a report).

因此,所有上述选项都是不同的选项,但是在一个功能区中分组,以便您完成一项工作。

因此,这里的想法是将功能区选项分组,而不是按所有报告的选项类型进行分组,但是组+基于执行一项任务创建功能区,该任务包括用户在给定时间对给定任务所需的选项。 / p>

如上所述,上述内容可能不是您的问题的解决方案,但避免使用其他标签通常会解决很多这些问题。