excel 用VBA快速计数有色细胞

yftpprvb  于 2023-06-30  发布在  其他
关注(0)|答案(1)|浏览(123)

我有一个电子表格选项卡,其中的活动范围是A4:DD 2500,因此有270,000个单元格。我有一段代码(感谢@EvilBlueMonkey),它根据用户在A列中的下拉选择(见下文),将B列到DD列中的单元格填充为蓝色、灰色或黄色。当用户在其中一个蓝色单元格中输入数据时,它会变成绿色,表示使用条件格式完成。我想实现一个代码,在每次用户执行一个条目后动态运行,该条目计数四种不同的情况-蓝色单元格,绿色单元格,没有文本的黄色单元格和有文本的黄色单元格。我构建了以下代码,它将运行,但每次都会冻结Excel。有没有什么方法可以更有效地遍历27万个单元格?如果没有,那么循环遍历那些只填充了列A的行怎么办?

Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    
    'Declarations.
    Dim CountRange As Range
    Dim CountRangeCell As Range
    Dim BColorCounter As Long
    Dim GColorCounter As Long
    Dim YColorCounter As Long
    Dim YColorTextCounter As Long
        
    'SETTINGS:
    
    'Set Cells to be counted Range
    Set CountRange = Worksheets("ADIS").Range("B3:DD2500")
      
        'Loop through each cell in the range
        For Each CountRangeCell In CountRange
         'Checking Blue Color
        If Cells(CountRangeCell.Row, CountRangeCell.Column).DisplayFormat.Interior.Color = RGB(155, 194, 230) Then
        BColorCounter = BColorCounter + 1
        Else
               
        'Checking Yellow Color
        If Cells(CountRangeCell.Row, CountRangeCell.Column).DisplayFormat.Interior.Color = RGB(255, 255, 0) And CountRangeCell.Text = "" Then
        YColorCounter = YColorCounter + 1
        Else
       
        'Checking Green Color
        If Cells(CountRangeCell.Row, CountRangeCell.Column).DisplayFormat.Interior.Color = RGB(169, 208, 142) Then
        GColorCounter = GColorCounter + 1
        Else
        
        'Checking Yellow With Text
        If Cells(CountRangeCell.Row, CountRangeCell.Column).DisplayFormat.Interior.Color = RGB(255, 255, 0) And CountRangeCell.Value <> "" Then
        YColorTextCounter = YColorTextCounter + 1
           
        End If
        End If
        End If
        End If
        
        Next
        Range("C2504") = YColorCounter
        Range("D2504") = BColorCounter
        Range("E2504") = GColorCounter
        Range("F2504") = YColorTextCounter

End Sub

谢谢!x1c 0d1x

watbbzwu

watbbzwu1#

工作表变更:计数突出显示的单元格

  • 请注意,这是一个很大的范围,如果删除条件 “如果范围第一列的值为空,则不应计算该行”,代码将花费大约5秒(在A列中的每个更改上)。如果列A中的所有单元格都被填充。
  • 我认为这一切都是XY problem。要走的路将是实现逻辑,你已经使用了条件格式摆在首位,到VBA。但这需要更多的信息。
Option Explicit

' The worksheet name ("ADIS") is irrelevant. Use the 'Me' keyword instead.
' Whenever you change a value in the 1st column of the range,
' this code runs automatically counting the colors in the remaining columns.
' It is assumed that blank cells in the first column will have no highlights
' in the remaining columns.
Private Sub Worksheet_Change(ByVal Target As Range)
     
    Const SHOW_MESSAGE_BOX As Boolean = True
    Dim Success As Boolean
    On Error GoTo ClearError

    Const SOURCE_RANGE As String = "A3:DD2500"

    Dim Blue As Long: Blue = RGB(155, 194, 230)
    Dim Green As Long: Green = RGB(169, 208, 142)
    Dim Yellow As Long: Yellow = RGB(255, 255, 0)
    
    Dim trg As Range, CountRange As Range

    With Me.Range(SOURCE_RANGE)
        Set trg = .Columns(1)
        ' If a change didn't happen in the first column, do nothing.
        If Intersect(trg, Target) Is Nothing Then Exit Sub
        Set CountRange = .Resize(, .Columns.Count - 1).Offset(, 1)
    End With
    
    Dim CountRangeRow As Range, CountRangeCell As Range, r As Long
    Dim BlueCount As Long, GreenCount As Long
    Dim YellowCount As Long, YellowTextCount As Long
    
    For Each CountRangeRow In CountRange.Rows
        r = r + 1
        If Len(trg.Cells(r)) > 0 Then
            For Each CountRangeCell In CountRangeRow.Cells
                Select Case CountRangeCell.DisplayFormat.Interior.Color
                    Case Blue
                        BlueCount = BlueCount + 1
                    Case Green
                        GreenCount = GreenCount + 1
                    Case Yellow
                        If Len(CStr(CountRangeCell.Value)) = 0 Then ' is blank
                            YellowCount = YellowCount + 1
                        Else ' is not blank
                            YellowTextCount = YellowTextCount + 1
                        End If
                    'Case Else ' neither; do nothing
                End Select
            Next CountRangeCell
        End If
    Next CountRangeRow
    
    ' Before writing to the worksheet, disable events or the code
    ' gets triggered again and again until Excel crashes!
    Application.EnableEvents = False
    
    With Me
        .Range("C2504").Value = YellowCount
        .Range("D2504").Value = BlueCount
        .Range("E2504").Value = GreenCount
        .Range("F2504").Value = YellowTextCount
    End With

    Success = True

ProcExit:
    On Error Resume Next
        ' Don't forget to enable events again!
        If Not Application.EnableEvents Then Application.EnableEvents = True
        If SHOW_MESSAGE_BOX Then
            If Success Then MsgBox "Highlighted cells counted.", vbInformation
        End If
    On Error GoTo 0
    Exit Sub
ClearError:
    MsgBox "Run-time error '" & Err.Number & "':" & vbLf & vbLf _
         & Err.Description, vbCritical
    Resume ProcExit
End Sub

相关问题