简体   繁体   English

Excel VBA 将工作表名称添加到从整行创建的数组中

[英]Excel VBA add worksheet name to array created from entire row

I have a search function, which loops through Excel workbooks and worksheets and by using Cells.Find returning an array with all rows matching search pattern.我有一个搜索 function,它循环通过 Excel 工作簿和工作表,并使用 Cells.Find 返回一个所有行匹配搜索模式的数组。 The issue is that as files in directory grow I am losing track of which workbook/worksheet the records were found in. I can't figure out how to modify the temp range to inject worksheet/workbook name without breaking entire array.问题是,随着目录中文件的增长,我无法跟踪在哪个工作簿/工作表中找到了记录。我无法弄清楚如何修改临时范围以在不破坏整个数组的情况下注入工作表/工作簿名称。 I tried to add worksheet name as array element but transpose do not like that idea.我尝试将工作表名称添加为数组元素,但转置不喜欢这个想法。

This is current code:这是当前代码:

   Dim myDir As String, fn As String, ws As Worksheet, r As Range
Dim a(), n As Long, x As Long, myTask As String, ff As String, temp
myDir = Range("P2").Value
Debug.Print Range("P2").Value
If Dir(myDir, 16) = "" Then
    MsgBox "No such folder path", 64, myDir
    Exit Sub
End If
myTask = InputBox("Enter Search String * accepted")
If myTask = "" Then Exit Sub
x = Columns.Count ' <---- Active worksheet count of all columns
fn = Dir(myDir & "*.xls*")
With Application
    .ScreenUpdating = False
    .EnableEvents = False
End With
Do While fn <> ""
    With Workbooks.Open(myDir & fn, 0)
        For Each ws In .Worksheets ' <- ws is worksheet object ws.Name to return current search worksheet
            Set r = ws.Cells.Find(myTask, , , 1) ' <- Actual find return cells address or Nothing object if not found
            If Not r Is Nothing Then
                ff = r.Address '<- Address of cell where the search was matched
                Do
                    n = n + 1
                    temp = r.EntireRow.Value ' <- take entire row if the cell was found
                    ReDim Preserve temp(1 To 1, 1 To x) ' <- preserve temp data i dynamic array basically one dimensional array of cells, which will become a item in array a
                    ReDim Preserve a(1 To n)
                    a(n) = temp '<- insert temp array as item in array a
                    Set r = ws.Cells.FindNext(r) '<- after finding first mach in the worksheet check if later there is something to matching
                Loop While ff <> r.Address '<- loop through worksheet until we come back to the cell address we initially found
            End If
        Next
        .Close False
    End With
    fn = Dir
Loop
With ThisWorkbook.Sheets("IP_Info").Rows(1)
    .CurrentRegion.ClearContents
    If n > 0 Then
        .Resize(n).Value = _
        Application.Transpose(Application.Transpose(a))
    Else
        MsgBox "Not found", , myTask
    End If
End With

With this design you cannot.有了这个设计,你不能。 Your temp array has as much entries as there are columns in Excel (therefore ReDim Preserve temp(1 To 1, 1 To x) is not necessary) so there is no room for additional information that can be written to a row using transpose.您的临时数组具有与 Excel 中的列一样多的条目(因此不需要 ReDim Preserve temp(1 To 1, 1 To x)),因此没有空间可以使用转置将其他信息写入行。

One thing you can do is to use a second array to store the workbook and sheetname.您可以做的一件事是使用第二个数组来存储工作簿和工作表名称。 Use n as the index that corresponds to the row in array a and the array containing the workbook and sheet in the other array.使用 n 作为与数组 a 中的行以及包含另一个数组中的工作簿和工作表的数组相对应的索引。

You can also store the row and column in the additional array so you will know the workbook, sheetname, row and column for your match.您还可以将行和列存储在附加数组中,以便了解匹配的工作簿、工作表名称、行和列。

if you do not need the complete row but only the value of the cell found you can do the following如果您不需要完整的行,而只需要找到的单元格的值,您可以执行以下操作

::
a(n) = Array(r.Parent.Parent.Name, r.Parent.Name, r.Row, r.Column, r.Value)
:: 

writing to sheet写到工作表

With ThisWorkbook.Sheets("IP_Info")
    .UsedRange.ClearContents
    if n > 0 then
        .Cells(1, 1).Resize(n, 5).Value = Application.Transpose(Application.Transpose(a))
    end if
end with

Thank you for all the answers, I have solved it by putting search results in new sheet (1 file = one sheet).感谢您提供所有答案,我已通过将搜索结果放入新工作表(1 个文件 = 一个工作表)来解决它。

Here is the code which works (depends on the file name you can hit and error as it might have illegal characters in file name thus sheet cannot be created)这是有效的代码(取决于您可以点击的文件名和错误,因为文件名中可能包含非法字符,因此无法创建工作表)

    Dim myDir As String, fn, fn_temp As String, ws As Worksheet, r As Range
Dim a(), n As Long, x As Long, myTask As String, ff As String, temp
Dim sheet As Worksheet
myDir = Range("P2").Value
Debug.Print Range("P2").Value
If Dir(myDir, 16) = "" Then
    MsgBox "No such folder path", 64, myDir
    Exit Sub
End If
myTask = InputBox("Enter Search String * accepted")
If myTask = "" Then Exit Sub
x = Columns.Count ' <---- Active worksheet count of all columns
fn = Dir(myDir & "*.xls*")
With Application
    .ScreenUpdating = False
    .EnableEvents = False
End With
Do While fn <> ""
Debug.Print fn

Set sheet = ThisWorkbook.Sheets.Add(After:=ActiveWorkbook.Worksheets(ActiveWorkbook.Worksheets.Count))
sheet.Name = fn

    With Workbooks.Open(myDir & fn, 0)
        For Each ws In .Worksheets ' <- ws is worksheet object ws.Name to return current search worksheet
            Set r = ws.Cells.Find(myTask, , , 1) ' <- Actual find return cells address or Nothing object if not found
            If Not r Is Nothing Then
                ff = r.Address '<- Address of cell where the search was matched
                Do
                    n = n + 1
                    temp = r.EntireRow.Value ' <- take entire row if the cell was found
                    ReDim Preserve temp(1 To 1, 1 To x) ' <- preserve temp data i dynamic array basically one dimensional array of cells, which will become a item in array a
                    ReDim Preserve a(1 To n)
                    a(n) = temp '<- insert temp array as item in array a
                    Set r = ws.Cells.FindNext(r) '<- after finding first mach in the worksheet check if later there is something to matching
                Loop While ff <> r.Address '<- loop through worksheet until we come back to the cell address we initially found
            End If
        Next
        .Close False
    End With
    fn = Dir
     With ThisWorkbook.Sheets(sheet.Name).Rows(1)
    .CurrentRegion.ClearContents
    If n > 0 Then
        .Resize(n).Value = _
        Application.Transpose(Application.Transpose(a))
        Erase a
        n = 0
    Else
        sheet.Range("A1").Value = "Not found" & myTask & " in " & sheet.Name
        Erase a
        n = 0
    End If
End With
Loop

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM