首页 > 解决方案 > Count和CountIf混淆VBA

问题描述

我有一个 for 循环遍历工作簿中的每个工作表。对于大多数用途,每张纸都是相同的。我正在我的工作簿中制作一个概览表,以表达其他表中数据的结果(相同的表)。

有 11 辆车,每辆车都有自己的表格,其中包含每天的测试数据。在任何一天都可能没有测试,或者一直到 30,000 次测试。第 47 行中每一列的标题以“06/01/2021 ... 06/30/2021”格式说明日期。每次测试迭代的数据将粘贴到从第 49 行开始的正确日期列中。

所以我的概览页面需要显示的是前一天的数据。在我的概述的一个单元格中,有一个公式用于获取一个月中的天数,如 20 或 1 等。使用这个数字,天数与前一天数据的列索引相同在方便。因此,在我的 for 循环中,我希望在 B 列中有一个表,其中包含 B 列中每个工作表的名称,在 CI 列中希望在 DI 列中显示当天完成的测试总数(而不是所有数据的总和)需要结果为 0 的测试数,在 EI 列中需要结果高于上限公差的测试数,在 FI 列中需要结果低于下限的测试数减去列中的结果D.

我一直在玩 Application.WorksheetFunction.Count 和 CountIf 函数,但每个单元格都得到 0。我为上公差值和下公差值制作了两个数组,它们是 Longs 类型,分别称为 UTol 和 LTol。TabList 是一个公共数组,将车辆的每个工作表名称存储为字符串。finddate 是一个整数,它读取今天的日期数,即昨天的列索引。我已经包含了一张有问题的表格的图片和我的 for 循环代码: 有问题的表

    
    finddate = Worksheets("Overview").Range("A18").Value
    
    For TabNRow = 1 To 11
        startcol = 3
        Worksheets(TabList(TabNRow)).Activate
        Debug.Print (TabList(TabNRow))
        
        'Total number of tests done that day
        Worksheets("Overview").Cells(startrow, startcol).Value = Application.WorksheetFunction.Count(Range(Cells(49, finddate), Cells(30000, finddate)))
        startcol = 4
        
        'Total number of 0 results, this used to get the number of 0's from each sheet but that row has since been deleted
        Worksheets("Overview").Cells(startrow, startcol).Value = Worksheets(TabList(TabNRow)).Cells(48, finddate).Value
        startcol = 5
        
        'Total number of results above tolerance
        Worksheets("Overview").Cells(startrow, startcol).Value = Application.WorksheetFunction.CountIf(Range(Cells(49, finddate), Cells(30000, finddate)), ">" & UTol(TabNRow))
        startcol = 6
        
        'Total number of results below tolerance
        Worksheets("Overview").Cells(startrow, startcol).Value = Application.WorksheetFunction.CountIf(Range(Cells(49, finddate), Cells(30000, finddate)), "<" & LTol(TabNRow))
        startrow = startrow + 1
    Next TabNRow
    ```

标签: excelvbaexcel-2016

解决方案


引用它们时无需选择/激活工作表。请参阅:如何避免在 Excel VBA 中使用 Select

像这样的东西应该工作:

Dim wsOv As Worksheet, wsData As Worksheet, rngData As Range

Set wsOv = ThisWorkbook.Worksheets("Overview")
finddate = wsOv.Range("A18").Value

For TabNRow = 1 To 11
    
    Set wsData = ThisWorkbook.Worksheets(TabList(TabNRow))
    Set rngData = wsData.Range(wsData.Cells(49, finddate), _
                               wsData.Cells(Rows.Count, finddate).End(xlUp))
    
    Debug.Print wsData.Name, rngData.Address 'edited
    
    With wsOv.Rows(2 + TabNRow)
        .Columns("C").Value = Application.Count(rngData)
        .Columns("D").Value = Application.CountIf(rngData, 0)
        .Columns("E").Value = Application.CountIf(rngData, ">" & UTol(TabNRow))
        .Columns("F").Value = Application.CountIf(rngData, "<" & LTol(TabNRow)) _
                               - .Columns("D").Value
    End With
    
Next TabNRow

推荐阅读