2017-06-16 6 views
1

値が繰り返される回数、たとえば288を知りたいとします。同じ形式の多くのファイルで、合計(いくつでも)の値がいくつあるかを知りたいと思います。異なるファイル間で値が繰り返される回数はどのように数えますか?

1つのワークシートのために私はちょうど=COUNTIF(F:F;288)=COUNTA(F:F)

を使用するであろう。しかし、今、私は、フォルダ内の複数の30000個のxlsxファイルでそれをしなければなりません。

最初の目的は、ファイルlike thisを1つにマージしてthis solutionとカウントしていましたが、5279個のタブの後に停止しました。何らかの制限があると思います。

すべてのファイルは同じフォルダ(H:\Macro\positions)にあり、値は列Fにのみ含まれています。

ファイルごとに100〜600個の値があり、約30000個のファイルがあります。

操作は一度だけ行う必要があります。終了するまでに数時間待つのは気になりません。

どうすればよいですか?

+1

が全てですxlsxは同じフォルダ内にあり、そのフォルダ内の各ファイルの各シートのF列でのみ期待される値ですか? –

+0

はい、H:\ Macro \ positionsおよびちょうど列F –

+0

いくつの値を数える必要がありますか?私は30000ファイルがたくさんあることを意味します。ファイルを開くには多くの時間がかかります。なぜなら、それらを何らかの方法でマージする必要があるからです。マージされたファイルを循環して、カウンタを配列に格納することができます。 – UGP

答えて

2

以下のコードを試してコメントに従ってください - 基本的に、コードは特定のフォルダ内の各スプレッドシートを開き、そのブックのシートをループし、各シートに対して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 

その後、上記のコードはそれを行うだろう、ただのチェックシートによる研削値。

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

をそしてその後(CleanUp:文の後に)戻って設定を有効に:あなたはスピードを改善したい場合は、助けるためにForループの前に次のコードを使用することができます

Application.ScreenUpdating = True 
Application.DisplayAlerts = True 
Application.EnableEvents = True 
+0

私はそれを試み、小さなサンプルのために働いた。今では30000個のファイルでそれを使用し、それがうまくスケールされているかどうかをお知らせします。どうもありがとうございました。 –

+0

今編集を読んで、完璧な、私はスピードアップを使用します。 –

+1

私は編集を訂正しました - エラーがある場合のために、クリーンアップブロック内の設定を元に戻すコード。また、On Error Goto CleanUpコマンドを追加しました。 –

関連する問題