excel 在文件夹和子文件夹中搜索字符串,并将其信息提取到同一工作表中

2jcobegt  于 2023-02-17  发布在  其他
关注(0)|答案(1)|浏览(123)

每天,我都需要检查序列号,看看它是否开过发票。我们有一个系统,它生成发票并在C:\Serial_Numbers位置路径中导出,发票号总是固定在B列中序列号的A列侧。
我试着谷歌一个VBA代码来帮助我,并尝试了这个,这是做得很好,如第一张图片所示:call-tab-and-then-enter-keys-in-an-excel-vba-modulehttps://www.get-digital-help.com/search-all-workbooks-in-a-folder-and-sub-folders/
这个VBA的主要问题是需要手动选择一个序列(字符串)并在新的工作表中获得结果。
编辑:我用我有限的知识调整了代码,使搜索结果在同一张工作表上,并修复了搜索目录文件夹(第一个答案),但每次我试图在所有A列序列号中循环代码时,我都以许多错误告终。

'Dimensioning public variable and declaring the data type
'A Public variable can be accessed from any module, Sub Procedure, Function, or Class within a specific workbook.
Public WS As Worksheet
 
'Name macro and parameters
Sub SearchWKBooksSubFolders(Optional Folderpath As Variant, Optional Str As Variant)
 
'Dimension variables and declare data types
Dim myfolder As String
Dim a As Single
Dim sht As Worksheet
Dim Lrow As Single
Dim Folders() As String
Dim Folder As Variant
 
'Redimension array variable
ReDim Folders(0)
 
'IsMissing returns a Boolean value indicating if an optional Variant parameter has been sent to a procedure.
'Check if FolderPath has not been sent
If IsMissing(Folderpath) Then
 
    'Add a worksheet
    Set WS = Sheets.Add
 
    'Ask for a folder to search.
    With Application.FileDialog(msoFileDialogFolderPicker)
        .Show
        myfolder = .SelectedItems(1) & "\"
    End With
     
    'Ask for a search string.
    Str = Application.InputBox(prompt:="Search string:", Title:="Search all workbooks in a folder", Type:=2)
     
    'Stop macro if no search string is entered.
    If Str = "" Then Exit Sub
     
    'Save "Search string:" to cell "A1".
    WS.Range("A1") = "Search string:"
 
     'Save variable Str to cell "B1".
    WS.Range("B1") = Str
 
    'Save "Path:" to cell "A2".
    WS.Range("A2") = "Path:"
 
    'Save variable myfolder to cell "B2".
    WS.Range("B2") = myfolder
 
    'Save "Folderpath" to cell "A3".
    WS.Range("A3") = "Folderpath"
 
    'Save "Workbook" to cell "B3".
    WS.Range("B3") = "Workbook"
 
    'Save "Worksheet" to cell "C3".
    WS.Range("C3") = "Worksheet"
 
    'Save "Cell Address" to cell "D3".
    WS.Range("D3") = "Cell Address"
 
    'Save "Link" to cell "E3".
    WS.Range("E3") = "Link"
     
    'Save variable myfolder to variable Folderpath
    Folderpath = myfolder
     
    'Dir returns a String representing the name of a file, directory, or folder that matches a specified pattern or file attribute, or the volume label of a drive.
    Value = Dir(myfolder, &H1F)
 
'Continue here if FolderPath has been sent
Else
 
    'Check if the two last characters in Folderpath is "//".
    If Right(Folderpath, 2) = "\\" Then
 
        'Stop macro
        Exit Sub
    End If
 
    'Dir returns a String representing the name of a file, directory, or folder that matches a specified pattern or file attribute, or the volume label of a drive.
    Value = Dir(Folderpath, &H1F)
End If
 
'Keep iterating until Value is nothing
Do Until Value = ""
 
    'Check if Value is . or ..
    If Value = "." Or Value = ".." Then
 
    'Continue here if Value is not . or ..
    Else
 
        'Check if Folderpath & Value is a folder
        If GetAttr(Folderpath & Value) = 16 Then
 
            'Add folder name to array variable Folders
            Folders(UBound(Folders)) = Value
 
            'Add another container to array variable Folders
            ReDim Preserve Folders(UBound(Folders) + 1)
         
        'Continue here if Value is not a folder
        'Check if the file ends with xls, xlsx, or xlsm
        ElseIf Right(Value, 3) = "xls" Or Right(Value, 4) = "xlsx" Or Right(Value, 4) = "xlsm" Then
 
            'Enable error handling
            On Error Resume Next
 
            'Check if the workbook is password protected.
            Workbooks.Open fileName:=Folderpath & Value, Password:="zzzzzzzzzzzz"
 
            'Check if an error has occurred
            If Err.Number <> 0 Then
 
                'Write the workbook name and the phrase "Password protected."
                WS.Range("A4").Offset(a, 0).Value = Value
                WS.Range("B4").Offset(a, 0).Value = "Password protected"
 
                'Add 1 to variable 1
                a = a + 1
 
                'Disable error handling
                On Error GoTo 0
 
            'Continue here if an error has not occurred
            Else
 
                'Iterate through all worksheets in the active workbook
                For Each sht In ActiveWorkbook.Worksheets
                        'Expand all groups in a sheet
                    sht.Outline.ShowLevels RowLevels:=8, ColumnLevels:=8
 
                        'Search for cells containing search string and save to variable c
                        Set c = sht.Cells.Find(Str, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext)
 
                        'Check if variable c is not empty
                        If Not c Is Nothing Then
 
                            'Save cell address to variable firstAddress
                            firstAddress = c.Address
 
                            'Do ... Loop While c is not nothing
                            Do
 
                                'Save the row of the last non-empty cell in column A
                                Lrow = WS.Range("A" & Rows.Count).End(xlUp).Row
 
                                'Save folderpath to the first empty cell in column A in worksheet WS
                                WS.Range("A1").Offset(Lrow, 0).Value = Folderpath
 
                                'Save value to the first empty cell in column B in worksheet WS
                                WS.Range("B1").Offset(Lrow, 0).Value = Value
 
                                'Save the worksheet name to  the first empty cell in column C in worksheet WS
                                WS.Range("C1").Offset(Lrow, 0).Value = sht.Name
 
                                'Save cell address to the first empty cell in column D in worksheet WS
                                WS.Range("D1").Offset(Lrow, 0).Value = c.Address
                                'Insert hyperlink
                                WS.Hyperlinks.Add Anchor:=WS.Range("E1").Offset(Lrow, 0), Address:=Folderpath & Value, SubAddress:= _
                                "'" & sht.Name & "'" & "!" & c.Address, TextToDisplay:="Link"
 
                                'Find next cell containing search string and save to variable c
                                Set c = sht.Cells.FindNext(c)
 
                            'Continue iterate while c is not empty and the cell address is not equal to the first cell address.
                            Loop While Not c Is Nothing And c.Address <> firstAddress
                        End If
 
                'Continue with the next worksheet
                Next sht
            End If
 
            'Close workbook
            Workbooks(Value).Close False
 
            'Disable error handling
            On Error GoTo 0
        End If
    End If
    Value = Dir
Loop
 
'Go through all folder names and
For Each Folder In Folders
 
    'start another instance of macro SearchWKBooksSubFolders (recursive)
    SearchWKBooksSubFolders (Folderpath & Folder & "\")
Next Folder
 
'Resize column widths
Cells.EntireColumn.AutoFit
End Sub

当前结果

预期成果

js81xvg6

js81xvg61#

我尝试尽可能多地调整代码以使输出与需求相匹配,但是我无法在列A的所有序列号中进行循环并获取每行的结果。

Public WS As Worksheet

'Name macro and parameters
Sub SearchWKBooksSubFolders1(Optional Folderpath As Variant, Optional Str As Variant)
 
'Dimension variables and declare data types
Dim myfolder As String
Dim a As Single
Dim sht As Worksheet
Dim Lrow As Single
Dim Folders() As String
Dim Folder As Variant
 
'Redimension array variable
ReDim Folders(0)
 
'IsMissing returns a Boolean value indicating if an optional Variant parameter has been sent to a procedure.
'Check if FolderPath has not been sent
If IsMissing(Folderpath) Then
 
    'Add a worksheet
    'Set WS = Sheets.Add
     Set WS = ActiveSheet
 
    'Ask for a folder to search
    'With Application.FileDialog(msoFileDialogFolderPicker)
    '    .Show
    '    myfolder = .SelectedItems(1) & "\"
         myfolder = "C:\Serial_Numbers" & "\"     'Fixing the search folder
    'End With
     
    'Ask for a search string
    Str = Application.InputBox(prompt:="Search string:", Title:="Search all workbooks in a folder", Type:=2)
     
    'Stop macro if no search string is entered.
    If Str = "" Then Exit Sub
     
    
    WS.Range("A1") = "Serial Numbers"       'Serial Numbers List on Column A
    WS.Range("B1") = "Invoice Number"       'Save Invoice Number on Column B
    WS.Range("C1") = "Folderpath"           'Save "Folderpath" on Column C
    WS.Range("D1") = "Workbook"             'Save "Workbook" on Column D
    WS.Range("E1") = "Worksheet"            'Save "Worksheet" on Column E
    WS.Range("F1") = "Cell Address"         'Save "Cell Address" on Column F
    WS.Range("G1") = "Link"                 'Save "Link" on Column G
     
    'Save variable myfolder to variable Folderpath
    Folderpath = myfolder
     
    'Dir returns a String representing the name of a file, directory, or folder that matches a specified pattern or file attribute or the volume label of a drive.
    Value = Dir(myfolder, &H1F)
 
'Continue here if FolderPath has been sent
Else
 
    'Check if the two last characters in Folderpath is "//"
    If Right(Folderpath, 2) = "\\" Then
        'Stop macro
        Exit Sub
    End If
 
    'Dir returns a String representing the name of a file, directory, or folder that matches a specified pattern or file attribute or the volume label of a drive.
    Value = Dir(Folderpath, &H1F)
End If
 
'Keep iterating until Value is nothing
Do Until Value = ""
 
    'Check if Value is . or ..
    If Value = "." Or Value = ".." Then
 
    'Continue here if Value is not . or ..
    Else
 
        'Check if Folderpath & Value is a folder
        If GetAttr(Folderpath & Value) = 16 Then
 
            'Add folder name to array variable Folders
            Folders(UBound(Folders)) = Value
 
            'Add another container to array variable Folders
            ReDim Preserve Folders(UBound(Folders) + 1)
         
        'Continue here if Value is not a folder
        'Check if file ends with xls, xlsx, or xlsm
        ElseIf Right(Value, 3) = "xls" Or Right(Value, 4) = "xlsx" Or Right(Value, 4) = "xlsm" Then
 
            'Enable error handling
            On Error Resume Next
 
            'Check if the workbook is password protected.
            Workbooks.Open Filename:=Folderpath & Value, Password:="zzzzzzzzzzzz"
 
            'Check if an error has occurred
            If Err.Number <> 0 Then
 
                'Write the workbook name and the phrase "Password protected."
                WS.Range("D2").Offset(a, 0).Value = Value
                WS.Range("E2").Offset(a, 0).Value = "Password protected"
 
                'Add 1 to variable 1
                a = a + 1
 
                'Disable error handling
                On Error GoTo 0
 
            'Continue here if an error has not occurred
            Else
 
                'Iterate through all worksheets in the active workbook
                For Each sht In ActiveWorkbook.Worksheets
                        'Expand all groups in sheet
                    sht.Outline.ShowLevels RowLevels:=8, ColumnLevels:=8
 
                        'Search for cells containing search string and save to variable c
                        Set c = sht.Cells.Find(Str, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext)
 
                        'Check if variable c is not empty
                        If Not c Is Nothing Then
 
                            'Save cell address to variable firstAddress
                            firstAddress = c.Address
 
                            'Do ... Loop While c is not nothing
                            Do
                                'Save row of last non empty cell in column B
                            Lrow = WS.Range("B" & Rows.Count).End(xlUp).Row
                            
                                'Invoice number using offset to Column A - Note:Search string is always in Column B
                                WS.Range("B1").Offset(Lrow, 0).Formula = "='[" & Value & "]" & sht.Name & "'!" & c.Offset(0, -1).Address & ""
 
                                'Save folderpath to the first empty cell in column C in worksheet WS
                                WS.Range("C1").Offset(Lrow, 0).Value = Folderpath
 
                                'Save value to the first empty cell in column D in worksheet WS
                                WS.Range("D1").Offset(Lrow, 0).Value = Value
 
                                'Save worksheet name to  the first empty cell in column C in worksheet WS
                                WS.Range("E1").Offset(Lrow, 0).Value = sht.Name
 
                                'Save cell address to the first empty cell in column D in worksheet WS
                                WS.Range("F1").Offset(Lrow, 0).Value = c.Address
                                
                                'Insert hyperlink
                                WS.Hyperlinks.Add Anchor:=WS.Range("G1").Offset(Lrow, 0), Address:=Folderpath & Value, SubAddress:= _
                                "'" & sht.Name & "'" & "!" & c.Address, TextToDisplay:="Link"
 
                                'Find next cewll containing search string and save to variable c
                                Set c = sht.Cells.FindNext(c)
 
                            'Continue iterate while c is not empty and cell address is not equal to first cell address
                            Loop While Not c Is Nothing And c.Address <> firstAddress
                        End If
 
                'Continue with next worksheet
                Next sht
            End If
 
            'Close workbook
            Workbooks(Value).Close False
 
            'Disable error handling
            On Error GoTo 0
        End If
    End If
    Value = Dir
Loop
 
'Go through all folder names and
For Each Folder In Folders
 
    'start another instance of macro SearchWKBooksSubFolders (recursive)
    SearchWKBooksSubFolders1 (Folderpath & Folder & "\")
Next Folder
 
'Resize column widths
Cells.EntireColumn.AutoFit
End Sub

相关问题