【问题标题】:Extracting specific cells from multiple Excel files and compile it into one Excel file从多个 Excel 文件中提取特定单元格并将其编译为一个 Excel 文件
【发布时间】:2018-11-12 01:31:12
【问题描述】:

我是 VBA 新手,我想用它来完成一些困难而艰巨的任务。我有大量包含数千行和数列的 Excel 文件。我需要按行搜索并提取具有特定字符串的某些单元格。我已经拼凑了一些函数和代码,几乎可以让它工作,但我不断得到意外的结果,比如提取不相关的数据或随机错误,因为我不太了解 VBA 语法。作为 Excel 的新手,我正在竭尽全力调试这段代码,但它仍然没有给我需要的结果。到目前为止,我的代码如下:

Option Explicit

Sub ImportDataFromMultipleFiles()
Dim firstAddress As Variant
Dim filenames As Variant
Dim i As Long
Dim rFind As Range
Dim firstFile As String
Dim n As Long
Dim r As Range
Dim myArray() As Integer

ThisWorkbook.Activate
Application.ScreenUpdating = False
Range("a2").Select
filenames = Application.GetOpenFilename _
(FileFilter:="Excel Filter(*xlsx), *.xlsx", MultiSelect:=True)
Application.FindFormat.Clear

For i = 1 To UBound(filenames) 'counter for files
firstFile = filenames(i)
Workbooks.Open firstFile 'Opens individual files in folder
n = 0

With ActiveSheet.UsedRange
      Set rFind = .Find("Test*Results:", Lookat:=xlPart, MatchCase:=True, SearchFormat:=False)
        If Not rFind Is Nothing Then
            firstAddress = rFind.Address
            Do
            n = n + 1
            Set rFind = .FindNext(rFind)
            Selection.Copy
            ThisWorkbook.Activate
            Selection.PasteSpecial
            ActiveCell.Offset(0, 1).Activate
            Loop While Not rFind Is Nothing And rFind.Address <> firstAddress
        End If
    End With

ReDim myArray(0, n)
n = 0
Workbooks.Open firstFile 'Opens individual files in folder

With ActiveSheet.UsedRange
    Set rFind = .Find("Test*Results:", Lookat:=xlPart, MatchCase:=False, SearchFormat:=False)
            If Not rFind Is Nothing Then
            firstAddress = rFind.Address
            Do
            myArray(0, n) = rFind.Row '<<< Error currently here
            n = n + 1
            Set rFind = .FindNext(rFind)
            Selection.Copy
            ThisWorkbook.Activate
            Selection.PasteSpecial
            ActiveCell.Offset(0, 1).Activate
            Loop While Not rFind Is Nothing And rFind.Address <> firstAddress
        End If
    End With

For n = LBound(myArray) To UBound(myArray)
Debug.Print "Rows are: " & myArray(0, n)
Next n

Workbooks.Open filenames(i)
ActiveWorkbook.Close SaveChanges:=False
ActiveCell.Offset(1, 0).Activate

Next i

End Sub

我什至不确定第二个循环是否必要,但使用它已经为我提供了迄今为止我正在寻找的最接近的结果。这段代码将涵盖大量数据,因此任何使我的代码更高效的建议都将不胜感激。 提前致谢!

【问题讨论】:

    标签: vba excel loops syntax-error


    【解决方案1】:

    您绝对不需要所有这些代码。

    试试这个 - 如果您将“查找”部分拆分为单独的方法,则更易于管理。

    Option Explicit
    
    Sub ImportDataFromMultipleFiles()
    
        Dim filenames As Variant, wb As Workbook
        Dim rngDest As Range, colFound As Collection, f, i As Long
    
        Set rngDest = ActiveSheet.Range("A2") '<< results start here
    
        filenames = Application.GetOpenFilename( _
            FileFilter:="Excel Filter(*xlsx), *.xlsx", MultiSelect:=True)
    
        If TypeName(filenames) = "Boolean" Then Exit Sub '<< nothing selected
    
        Application.FindFormat.Clear
    
        For i = 1 To UBound(filenames) 'counter for files
    
            Set wb = Workbooks.Open(filenames(i))
            Set colFound = FindAll(wb.Sheets(1).UsedRange, "Test*Results:") '<< get matches
            Debug.Print "Found " & colFound.Count & " matches in " & wb.Name '<<EDIT
            For Each f In colFound
                f.Copy rngDest
                Set rngDest = rngDest.Offset(1, 0)
                Debug.Print "", f.Value
            Next f
    
            wb.Close False
        Next i
    
    End Sub
    
    Public Function FindAll(rng As Range, val As String) As Collection
        Dim rv As New Collection, f As Range
        Dim addr As String
    
        Set f = rng.Find(what:=val, after:=rng.Cells(rng.Cells.Count), _
            LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, _
            SearchDirection:=xlNext, MatchCase:=True)
        If Not f Is Nothing Then addr = f.Address()
    
        Do Until f Is Nothing
            rv.Add f
            Set f = rng.FindNext(after:=f)
            If f.Address() = addr Then Exit Do
        Loop
    
        Set FindAll = rv
    End Function
    

    【讨论】:

    • 好的,效率更高!我喜欢你的 FindAll 功能,它有助于简化事情。不过我不熟悉公共函数,如果我只是将它与其余的 VBA 代码一起放入它会正常运行吗?或者我需要做一些特别的事情吗?
    • 您应该可以将其添加到您的模块中。在这种情况下,它可能不需要是 Public,因此您可以删除该关键字。
    • 好的,我把它放在我的模块中,我的主 Excel 电子表格中没有任何数据。它允许我像以前一样选择文件并运行代码,但我的电子表格保持空白。这没什么好说的,但是有什么建议吗?
    • 打开的每个工作簿中是否只有一张工作表?您是否在 VB 编辑器的“立即”窗格中看到任何输出?
    • 我误解了你的问题。如果您询问rng.Cells(rng.Cells.Count),它基本上是“开始查看范围中的最后一个单元格”,这意味着开始查看范围的 第一个 单元格,因为 Find 总是在到达时循环要搜索的范围的结尾。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 1970-01-01
    • 1970-01-01
    • 2023-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多