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

6
当使用自定义UI XML文件在Access中添加多个自定义功能区选项卡时,每当关闭表单时所选的功能区选项卡会更改回第一个自定义选项卡。
我们从VBA程序中动态加载自定义功能区。我已经创建了一个可以重现此问题的accdb文件。该文件夹还包括一个包含功能区定义的XML文件。它必须与.accdb文件位于同一目录中。
该问题很容易演示:
1. 打开RibbonTest.accdb数据库, 2. 切换到Tab2并使用功能区上的按钮打开Form2 3. 关闭Form2。
注意,现在活动的是Tab1。
当然,在这个小示例数据库中,这个问题似乎非常微不足道。但是,我们有一个非常大的项目,其中包含许多自定义选项卡,每个选项卡都包含许多组和按钮。我们的用户发现每次关闭表单时都失去功能区选项卡上的位置非常令人沮丧。
我们研究了一个解决方法,即在我们认为需要时编程存储所选择的选项卡并恢复它。但是,要可靠地做到这一点似乎很困难。(虽然没有Office API可以像这样自动化功能区选项卡,但此文章对此有帮助)
是否有其他人遇到过这个问题?您是否找到了防止选项卡自动更改的方法?
编辑:似乎这个问题是在Office 2010 SP1中引入的修复程序。SP1的修复列表包括:“当用户返回到该对象时,Access不会激活或将用户返回到先前打开的数据库对象的正确功能区选项卡。”看起来他们试图修复Form.RibbonName属性的使用(它支持上下文功能区选项卡),但在处理过程中破坏了默认功能区选项卡。
6个回答

6
这一行代码解决了问题: <tab id="tabBogus" label="Bogus" visible="false"></tab> 只需要将它作为你的第一个选项卡放在标签中。非常感谢Scott的潜在解决方案!(试图赞同和/或评论,但刚注册所以声望不够。)与其他复杂的解决方法相比,这节省了数小时(或数天)的工作时间! 谢谢!

4

潜在解决方案

我偶然发现的一种方法是使用可见标签隐藏XML中的第一个选项卡。虽然我没有进行太多测试,但我有一个标准主页选项卡的副本是隐藏的(不知道是否需要是填充的选项卡)。据我观察,由于Access无法在关闭表单时激活隐藏选项卡,因此它保留在当前选择的选项卡上。

我不知道这个问题在Access 2013中是否已经修复,但希望这些信息对某人有所帮助。


优秀 - 将此标记为答案而不是我的解决方法。 - Olly

2

出现了一个错误!

微软支持已经接受了这个错误提交,并在 Office 2010 SP1 中发表评论:"实施的更改允许我们跟踪每个数据库对象(表单、报告等)的活动选项卡(TCID),以便在您在对象之间移动时恢复活动选项卡。然而,所有自定义选项卡都使用相同的 TCID 值,因此随着这个更改,自定义选项卡的活动选项卡将始终移动到第一个自定义选项卡。"

我们希望他们会在未来发布热修复来解决这个问题。

解决方法

以下信息对我们创建解决方法非常有用。

  1. 查看上面 Johannes 的答案,关于 IRibbonUI.ActivateTab 方法。这是在 Office 2010 中引入的。
  2. 没有办法(据我所知)获取当前选定的选项卡的 Office API。因此,我们使用这篇文章中的代码。我们
    • 生成我们的选项卡时创建一个包含每个选项卡的 id 值的数组,
    • 处理 Form_Deactivate 并使用它来启动另一个隐藏表单中的计时器,并存储所选选项卡的索引,
    • 在隐藏表单中的 Timer_Tick 处理程序中禁用计时器并查找我们在 Form_Deactivate 中存储的索引的选项卡的 id 值,并
    • 使用IRibbonUI.ActivateTab激活选项卡。
  3. 这篇文章展示了使用IRibbonUI.InvalidategetVisible回调选择特定选项卡的有趣方法。

感谢您花时间添加有用的信息以寻找可能的解决方案。 - Renaud Bompuis

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

在Microsoft Access中创建一个名为“zFrmRibbonSelect”的表单,并放置一个称为“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

1

似乎有一种方法可以获取所选选项卡(正如您提到并且可能已经拥有代码,以及您可以在这里找到)

在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

谢谢!目前我们正在使用类似的东西,但是(通常情况下)它并不完美。例如,当功能区被最小化时,我们的解决方法会导致一些奇怪的行为。我很想知道是否有一种方法让Access不要管功能区! - Olly

0

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

虽然这并不是您问题的解决方案,但这里的想法和概念是,如果您必须开始编写大量代码来进行切换,那么这确实会变得很困难,就像您所指出的一样。

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

因此,我在此唯一的建议就是尽可能限制大多数表单只有一个选项卡。另一个提示是,虽然菜单可能按“任务类型”分组,从而可以使菜单向下级联到一堆报告上。但现在,通过功能区,在处理发票时,您只需:

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

所以以上所有选项都是不同的东西,但它们被分组在一个功能区中,以便您完成一个任务。

因此,这里的想法是根据执行一个任务所需的选项来分组功能区选项,而不是按选项类型(如所有报告)进行分组+创建功能区。

正如所述,以上可能不是解决您问题的方法,但避免使用额外的选项卡通常会解决许多这些问题。


感谢您的建议。我们尚未研究过您所描述的Form.RibbonName属性,但遗憾的是它对我们来说不是一个解决方案。我们不使用上下文功能区;我们只是有一个包含许多选项卡的大型功能区,用于提供对项目中表单的访问。有趣的是,我们遇到的问题是在SP1中引入的,显然是因为添加了一个“修复程序”以使Form.RibbonName属性正常工作。 - Olly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接