使用vba在excel中查找多个工作表和工作簿中的值

dgsult0t  于 2022-12-24  发布在  其他
关注(0)|答案(1)|浏览(328)

我有一个宏,它在多个工作表和工作簿中查找值“a”并替换为值“B”,该宏循环通过文件夹中的文件和子文件夹中的文件,并替换它能找到的所有值。
现在,我希望宏返回工作表E列中的文件名,宏被写入其中,仅当在文件中进行更改时(因此,如果a被替换为B,则返回E列中的文件名)
但是我当前的代码只返回它运行的第一个工作簿的文件名。
我的代码从sub search开始,它将sub()作为输入

Sub FindReplaceAcrossMultipleExcelWorkbooksFreeMacro(Path As String)

    Dim CurrentWorkbookName As String
    Dim ExcelCounter As Integer
    Dim ExcelWorkbook As Object
    Dim FindReplaceCounter As Integer
    Dim FindandReplaceWorkbookName As String
    Dim FindandReplaceWorksheetName As String
    Dim LastRow As Integer
    Dim oFile As Object
    Dim oFolder As Object
    Dim oFSO As Object
    Dim Shape As Shape
    Dim ws As Worksheet
    Dim myrange As Range
    Dim look As String

    FindandReplaceWorkbookName = ActiveWorkbook.Name
    FindandReplaceWorksheetName = ActiveSheet.Name
  
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    Set oFolder = oFSO.GetFolder(Path)

    For Each oFile In oFolder.Files              'Loop through every File in Active Workbook's folder path
    
        If InStr(1, oFile.Type, "Microsoft Excel") <> 0 And InStr(1, oFile.Name, FindandReplaceWorkbookName) = 0 And InStr(1, oFile.Name, "~") = 0 Then 'If the File Type contains the phrase Microsoft Excel isn't the current Excel Workbook and is NOT Lock File
            Set ExcelWorkbook = Application.Workbooks.Open(Path & "\" & oFile.Name) 'Open Excel Workbook
            CurrentWorkbookName = ActiveWorkbook.Name 'Name of Active Excel Workbook that was opened
            Application.Workbooks(CurrentWorkbookName).Activate 'Ensure open Excel Workbook is active for future reference using ActiveWorkbook
            Application.ScreenUpdating = False   'Limit screen flashing when Excel Workbooks opened and when Find & Replace is completed
            FindReplaceCounter = 2
            LastRow = Workbooks(FindandReplaceWorkbookName).Sheets(FindandReplaceWorksheetName).Cells(Rows.Count, 1).End(xlUp).Row 'Identify Last Row in Column A
            Do Until FindReplaceCounter > LastRow 'Complete the Find and Replace for all values in Column A & B
                For Each ws In ActiveWorkbook.Worksheets 'Loop through every Excel Worksheet in Active Excel Workbook

                    Set myrange = ws.UsedRange.Find(what:="ben")
                    If Not myrange Is Nothing Then
                    
                        Workbooks(FindandReplaceWorkbookName).Sheets(FindandReplaceWorksheetName).Range("E" & Rows.Count).End(xlUp).Offset(1, 0) = ExcelWorkbook.Name
                        
                    End If
    
                    ws.Cells.Replace what:=Workbooks(FindandReplaceWorkbookName).Sheets(FindandReplaceWorksheetName).Cells(FindReplaceCounter, 1).Value, Replacement:=Workbooks(FindandReplaceWorkbookName).Sheets(FindandReplaceWorksheetName).Cells(FindReplaceCounter, 2).Value
                
                Next ws
                
                FindReplaceCounter = FindReplaceCounter + 1
                
            Loop
            
            ActiveWorkbook.Save                  'Save Active Excel Workbook
            ActiveWorkbook.Close                 'Close Active Excel Workbook

        End If
        
    Next oFile

    Application.ScreenUpdating = True            'Turn Excel ScreenUpdating back on

    Set ExcelWorkbook = Nothing
    Set oFSO = Nothing
    Set oFolder = Nothing
    Set oFile = Nothing
  
    Exit Sub
  
End Sub

Sub Search()

    FindReplaceAcrossMultipleExcelWorkbooksFreeMacro (Cells(2, 3).Value)

    MsgBox "The Find and Replace has been completed."
 
End Sub
jdzmm42g

jdzmm42g1#

如果我没理解错的话,下面的代码也许可以帮助您将它与您的案例进行比较。

Sub test()
Dim rg As Range: Dim wb As Workbook
Dim oFSO: Dim oFolder: Dim oFile
Dim fn As String: Dim sh As Worksheet: Dim cell As Range

Application.ScreenUpdating = False
Set wb = ActiveWorkbook
With wb.Sheets("Sheet1")
Set rg = .Range("A2", .Range("A" & Rows.Count).End(xlUp))
.Range("E:E").ClearContents
End With

Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.GetFolder("D:\test")
For Each oFile In oFolder.Files
fn = oFile.Name
If InStr(fn, "test") Then GoTo nextfile:
    Workbooks.Open oFile
    With ActiveWorkbook
        For Each sh In .Worksheets
            For Each cell In rg
                If Not sh.Cells.Find(cell.Value) Is Nothing Then
                    sh.UsedRange.Replace what:=cell.Value, Replacement:=cell.Offset(0, 1).Value, LookAt:=xlWhole
                wb.Sheets("Sheet1").Range("E" & Rows.Count).End(xlUp).Offset(1, 0).Value = _
                    fn & " - " & sh.Name & " : value " & cell.Value & " is replaced with " & cell.Offset(0, 1).Value
                End If
            Next
        Next
    .Close SaveChanges:=False
    End With
nextfile:
Next oFile
Application.ScreenUpdating = True
End Sub

要测试代码,请创建3个工作簿:
1.将第一个wb命名为“test.xlsm”,这是代码所在的wb。
在test.xlsm工作表Sheet 1中,在A列和B列中制作两个列标题,并将其命名为:在A1中查找并在B1中替换。在“查找”下,将aaa、bbb、ccc等数据放入A2中。在“替换”下,将XXX、YYY、ZZZ等数据放入B2中。
1.创建另外两个工作簿,随你喜欢命名。在每个工作簿中,把aaa和/或bbb和/或ccc放在任何工作表的任何单元格中。
1.将test.xlsm和其他两个工作簿放在驱动器D:中的一个文件夹中,将该文件夹命名为“test”。
1.运行test. xlsm中的代码,确保其他两个工作簿已关闭。
代码中有三个循环。
第一种方法是循环到test文件夹中的每个文件
第二种方法是循环到该文件的每个工作表
第三种方法是循环到工作表Sheet1test.xlsm中的每个FIND/REPLACE值
在第一个循环中,它打开文件/工作簿(不是test.xlsm)
然后它循环到打开WB的每一页
在循环表中,循环到sheet 1 test.xlsm中FIND/REPLACE下的每个数据,检查循环表中是否找到循环单元格值,然后执行两个过程:(A)将找到的值替换为替换值(B)将信息写入test.xlsm的E列sheet 1
请注意,代码不会在打开的循环工作簿的循环工作表上写入信息。它只是在找到要替换的值时替换为新值。
如果您第二次运行sub,则test. xlsm中工作表Sheet 1的E列中不应该有任何信息。

相关问题