Excel 在关联菜单中添加/删除许多命令的速度非常慢,尤其是在大型工作表上
最近我注意到我的上下文菜单创建(根据电子表格添加了很多宏按钮)非常慢 出于测试目的,工作簿对象的VBA中有以下宏:Excel 在关联菜单中添加/删除许多命令的速度非常慢,尤其是在大型工作表上,excel,vba,contextmenu,Excel,Vba,Contextmenu,最近我注意到我的上下文菜单创建(根据电子表格添加了很多宏按钮)非常慢 出于测试目的,工作簿对象的VBA中有以下宏: Private Sub App_SheetBeforeRightClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean) Dim OnActionString As String Dim cmdNew As CommandBarButton For Each icbc In A
Private Sub App_SheetBeforeRightClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
Dim OnActionString As String
Dim cmdNew As CommandBarButton
For Each icbc In Application.CommandBars("cell").Controls
If icbc.Tag = "brccm" Then icbc.Delete
Next icbc
For i = 1 To 70
Set cmdNew = Application.CommandBars("cell").Controls.Add
With cmdNew
.Caption = "RecordedOrNot"
.OnAction = "UTILITY_RecordedOrNot"
.BeginGroup = False
.Tag = "brccm"
End With
Next
End Sub
即使在空白工作表上,右键单击上下文菜单也需要大约两秒钟的时间才能显示。我有一个大约80000行的大工作表,它需要7秒钟才能显示出来
为什么慢?有没有办法加快速度?是否有一种方法可以禁用应用程序中的某些内容。*这样做会有所帮助?一个选项可能是在打开工作簿时预加载所有控件。。。然后根据显示逻辑使控件可见(或不可见)。我在一张随机数据范围(“A1:Z80000”)的工作表上进行的测试表明,与实时添加和删除控件相比,此操作的执行时间约为三分之一(显示/隐藏的时间约为1.4s,删除/添加的时间约为4.5s)
上下文菜单上有70个项目?听起来像是一个糟糕的UX!您可能需要重新考虑设计。也就是说,您真的需要在每次右键单击时删除并重新添加它们吗?您可以对菜单的当前状态进行dif,只删除/添加所需的更改或设置一次。可能会调用编组子来处理任何上下文要求。70只是一个示例,说明这样的代码有多慢。不同的列、工作簿和工作表会改变其中显示的内容,而不是跟踪我每次在菜单中创建的这些内容的所有组合。这就是我看到的Excel这个特性的用例。我主要关心的是为什么这段代码很慢,尤其是在大型工作表上。一般来说,从excel对象读取要比写入快。因此,在这种情况下,我会先检查菜单中是否有项目,然后根据需要添加/删除。至于在大型工作表上的速度较慢,我无法添加任何内容,其他方法是尝试禁用常用的应用程序对象属性
Option Explicit
Private Sub Workbook_Open()
Dim cmdNew As CommandBarButton
Dim icbc As CommandBarControl
Dim i As Long
For Each icbc In Application.CommandBars("cell").Controls
If icbc.Tag = "brccm" Then icbc.Delete
Next icbc
For i = 1 To 70
Set cmdNew = Application.CommandBars("cell").Controls.Add
With cmdNew
.Caption = "RecordedOrNot"
.OnAction = "UTILITY_RecordedOrNot"
.BeginGroup = False
.Tag = "brccm"
End With
Next
End Sub
Private Sub Workbook_SheetBeforeRightClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
Dim icbc As CommandBarControl
For Each icbc In Application.CommandBars("cell").Controls
If icbc.Tag = "brccm" Then
icbc.Visible = False ' Include visibility logic here True/False
End If
Next icbc
End Sub