繁体   English   中英

在 Excel 中使用 VBA 循环复选框非常慢

[英]Looping over checkboxes with VBA in Excel very slow

我有一个包含大约 4500 个复选框的 Excel 表(我知道,这听起来很愚蠢,但它是给客户的,请不要问......)。 刚刚在下面写了 VBA Sub 来取消选中所有框。 到目前为止它可以工作,但它非常慢,需要超过 5 分钟,直到所有 boce 都被取消检查,并且在 Sub 运行时,整个 Excel Applikation 变灰冻结。 我知道,4500 Checkboxes 安静了很多,但我想知道它是否真的足以让 Excel 陷入这样的麻烦......有没有人有想法?

最佳迈克尔

Sub DeselectAll()
   Application.EnableCancelKey = False
   Application.Calculation = xlCalculationManual
   Application.ScreenUpdating = False
   Application.EnableEvents = False
   Dim wksA As Worksheet
   Dim intRow As Integer

   Set wksA = Worksheets("Companies")
   For intRow = 1 To 4513
      wksA.CheckBoxes("Checkbox_" & intRow).Value = False
   Next
 End Sub

无选择:

Sub DeselectAll()
  With Worksheets("Companies").CheckBoxes
   .Value = xlOff
  End With
End Sub

只是不要循环。

这是选择何时可以提供帮助的一个很好的例子:

设置所有复选框:

Sub dural()
    ActiveSheet.CheckBoxes.Select
    Selection.Value = xlOn
End Sub

取消选中所有复选框:

Sub dural2()
    ActiveSheet.CheckBoxes.Select
    Selection.Value = xlOf
End Sub

(在表单类型复选框上测试)

我赞成的最佳答案是@EvR 解决方案。 我不是要回答,而是提供一个解决方法的想法。

我通过在带有简单 3 行循环的空白工作簿中的空白工作表中添加 4000 ComboBox 来检查时间(我忘了关闭屏幕更新和计算等)。 在我的旧笔记本电脑上花了大约 10 分钟。 我没有勇气再次重蹈覆辙。

当我尝试使用您的代码进行循环时,它只需要 3-4 秒,而@EvR 的解决方案没有循环和选择需要 1-2 秒。 这些时间是使用Debug.Print或写入某些单元格所花费的实际时间。 实际的戏剧在屏幕更新、计算、事件在工作表处于活动状态的情况下展开。 它变得非常不稳定,任何粗心的点击等都会导致 excel 在 2-5 分钟内处于“无响应”状态。

虽然客户和老板总是对的。 在我的一生中,有一次我成功地用工作表上数百个按钮的类似方法说服了某人使用虚拟的东西。 我的想法是在工作表中创建虚拟复选框。 适当的单元格大小和边界与单元格验证为`=ChrW(&H2714)' 并忽略空白和下面的简单代码可以使其成为一种传递类型的解决方法。

Public Prvsel As Range
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim isect, Cl As Range
Set isect = Application.Intersect(Target, Range("C1:C4000"))

    If isect Is Nothing Then
    Set Prvsel = Nothing  'Release multiple selection
    Exit Sub
    End If

    If isect.Cells.Count > 1 Then
    Set Prvsel = isect        'storing multiple selection for next click event
    Else
        If Target.Value = ChrW(&H2714) Then
        Target.Value = ""
        Else
        Target.Value = ChrW(&H2714)
        End If
        If Not Prvsel Is Nothing Then
            For Each Cl In Prvsel.Cells
            Cl.Value = Target.Value
            Next Cl
        End If
    End If
End Sub

截屏

详细说明@Ahmed AU 解决方案。

选择/取消选择信号/多个虚拟复选框

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

Dim isect As Range
Dim Cl As Range
Dim Prvsel As Range
Set isect = Application.Intersect(Target, Range("C1:C4000"))
If isect Is Nothing Then
Set Prvsel = Nothing  'Release multiple selection
Exit Sub
End If

' Use WINGDING font Chr (254) for checked
' Use WINGDING font Chr (111) for uncheck

If isect.Cells.Count >= 1 Then
Set Prvsel = isect        
    For Each Cl In Prvsel.Cells
            If Cl.Value = Chr(111) Then
                Cl.Value = Chr(254)
                Else
                Cl.Value = Chr(111)
            End If
    Next Cl
End If
'Go to offset cell selection
       Selection.Offset(0, 1).Select
    End Sub

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM