【问题标题】:How do I count the number of times a value is repeated across different files?如何计算一个值在不同文件中重复的次数?
【发布时间】:2017-11-18 23:06:28
【问题描述】:

我想知道一个值被重复的次数,例如 288,以及在许多具有相同格式的文件中总共有多少个值(每个数字)。

对于一个工作表,我只会使用 =COUNTIF(F:F;288)=COUNTA(F:F)

但现在我必须在一个文件夹中处理超过 30000 个 xlsx 文件。

我的第一个意图是将它们合并到一个文件 like this 然后用 this solution 计数,但它在 5279 个标签后停止,我猜是某种限制。

我的所有文件都在同一个文件夹 (H:\Macro\positions) 中,并且这些值只在 F 列中。

每个文件有 100-600 个值,大约 30000 个文件。

操作只需完成一次,我不介意等待几个小时才能完成。

你会怎么做?

【问题讨论】:

  • 所有 xlsx 是否都在同一个文件夹中,并且该文件夹中每个文件的每个工作表中的 F 列中的值是否预期?
  • 是的,H:\Macro\positions 并且就在 F 列中。
  • 需要计算多少个值?我的意思是 30000 个文件很多。打开excel文件需要很多时间,这就是为什么你应该以某种方式合并它们。然后你可以循环浏览合并的文件并将计数器存储在一个数组中。
  • 每个文件有 100-600 个值,大约 30000 个文件。操作只需完成一次,我不介意等待几个小时才能完成。

标签: vba excel count


【解决方案1】:

尝试下面的代码并遵循 cmets - 基本上,该代码会打开给定文件夹中的每个电子表格,循环浏览该工作簿中的工作表,为每个工作表运行 COUNTIF 公式并记录总数。

Option Explicit

Sub CheckForValue()

    Dim objFso As FileSystemObject '<-- add Microsoft Scripting Runtime as a reference
    Dim objFile As File
    Dim wbToCheck As Workbook
    Dim wsToCheck As Worksheet
    Dim strPath As String
    Dim varValue As Variant
    Dim lngValueCount As Long
    Dim lngTotal As Long
    Dim wsf As WorksheetFunction

    On Error Goto CleanUp

    strPath = "H:\Macro\positions"
    Set objFso = New FileSystemObject '<-- access to file system
    varValue = 288 '<-- value you are looking for
    lngTotal = 0 '<-- total count of value you are looking for
    Set wsf = Application.WorksheetFunction '<-- shortcut to WorksheetFunction

    ' iterate files in folder
    For Each objFile In objFso.GetFolder(strPath).Files
        ' only check spreadsheets
        If objFile.Type = "Microsoft Excel Worksheet" Then
            ' get reference to workbook
            Set wbToCheck = Workbooks.Open(objFile.Path)
            ' iterate worksheets
            For Each wsToCheck In wbToCheck.Worksheets
                ' your original formula
                lngValueCount = wsf.CountIf(wsToCheck.Range("F:F"), varValue)
                ' add to total
                lngTotal = lngTotal + lngValueCount
            Next wsToCheck
            ' close without saving changes
            wbToCheck.Close SaveChanges:=False
        End If
    Next objFile

    ' final count of value you are looking for
    Debug.Print "Total is: " & lngTotal

CleanUp:
    ' error handling
    If Err.Number <> 0 Then
        Debug.Print Err.Description
    End If

    Set objFile = Nothing
    Set objFso = Nothing

End Sub

根据您的评论,该操作必须只执行一次,我不介意等待几个小时才能完成然后上面的代码会做到这一点,只需仔细检查工作表价值。如果你想提高速度,可以在For循环之前使用以下代码来帮助:

Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.EnableEvents = False

然后将设置转回(在CleanUp: 语句之后):

Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.EnableEvents = True

【讨论】:

  • 我尝试了它并为一个小样本工作。我现在将它与我的 30000 个文件一起使用,并让您知道它是否可以很好地扩展。非常感谢。
  • 现在正在阅读编辑,完美,我会使用加速。
  • 我更正了编辑 - 重新打开设置的代码应该在 CleanUp 块中,以防出现错误。我还添加了一个On Error Goto CleanUp 命令。
  • 现在已经完成了!完美的。我将修改代码以计算其他值、总数等,但现在我知道该怎么做了。非常感谢。
  • 没问题 - 很高兴它有帮助。
猜你喜欢
  • 1970-01-01
  • 2022-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-24
相关资源
最近更新 更多