excel VBA代码,用于根据最后一行(以前未复制)将数据从四个源工作簿复制到主工作簿

fzsnzjdm  于 2023-01-21  发布在  其他
关注(0)|答案(1)|浏览(133)

我有一个挑战,实现以下项目,敬请协助:

  • 我有四个源工作簿,名称为(GK、SK、RJ和TB)。
  • 每个工作簿(GK、SK、RJ和TB)都有三个名称相同的工作表(产品、渠道和销售)。
  • 我有一个名为合并工作簿的**目标工作簿,它与四个源工作簿的工作表名称相同(产品、渠道和销售额)。
  • 所有工作簿(源+目标)都在同一文件夹中。
  • 我请求VBA代码,该代码将从所有四个源工作簿的每个工作表中复制数据,并根据上次复制事件中先前未复制的行将数据传输/粘贴到合并工作簿中的工作表。
  • 目前,我有下面的代码,但每当我运行它复制一切从工作表上的源工作簿和粘贴到工作表中的合并工作簿这导致重复的数据。
  • 所有源工作簿的工作表都将“DATE”作为每个工作表表列的第一列。
  • 目标工作簿也具有相同的工作表名称,并且每个工作表上的相同列结构与源工作表相同。
  • 请告知我应进行哪些修改,以便代码能够从所有四个源工作簿的每个工作表复制数据,并根据上次复制事件中未复制的行将数据传输/粘贴到合并工作簿中的工作表
Sub Copy_From_All_Workbooks()
    Dim wb As String, i As Long, sh As Worksheet
    Application.ScreenUpdating = False
    wb = Dir(ThisWorkbook.Path & "\*")
    Do Until wb = ""
        If wb <> ThisWorkbook.Name Then
            Workbooks.Open ThisWorkbook.Path & "\" & wb
                For Each sh In Workbooks(wb).Worksheets
                        sh.UsedRange.Offset(1).Copy   '<---- Assumes 1 header row
                            ThisWorkbook.Sheets(sh.Name).Cells(Rows.Count, 1).End(xlUp).Offset(1).PasteSpecial xlPasteValues
                        Application.CutCopyMode = False
                Next sh
            Workbooks(wb).Close False
        End If
        wb = Dir
    Loop
    Application.ScreenUpdating = True
End Sub

*请参见修改后的代码:

Sub Copy_From_All_Workbooks()
    Dim wb As String, i As Long, sh As Worksheet, fndRng As Range, 
    start_of_copy_row As Long, end_of_copy_row As Long, range_to_copy As 
    Range
    Application.ScreenUpdating = False
    wb = Dir(ThisWorkbook.Path & "\*")
    Do Until wb = ""
    If wb <> ThisWorkbook.Name Then
         Workbooks.Open ThisWorkbook.Path & "\" & wb
            For Each sh In Workbooks(wb).Worksheets
            On Error Resume Next
            sh.UsedRange.Offset(1).Copy   '<---- Assumes 1 header row
            Set fndRng = sh.Range("A:A").Find(date_to_find,LookIn:=xlValues, 
        searchdirection:=xlPrevious)
                
                If Not fndRng Is Nothing Then
                    start_of_copy_row = fndRng.Row + 1
                   Else
                   start_of_copy_row = 2 ' assuming row 1 has a header you want to ignore
                 End If

                   end_of_copy_row = sh.Cells(sh.Rows.Count, "A").End(xlUp).Row

                   Set range_to_copy = Range(start_of_copy_row & ":" & end_of_copy_row)
                        
                        latest_date_loaded = Application.WorksheetFunction.Max(ThisWorkbook.Sheets(sh.Name).Range("A:A"))
                
                       ThisWorkbook.Sheets(sh.Name).Cells(Rows.Count, 1).End(xlUp).Offset(1).PasteSpecial xlPasteValues
        
                   On Error GoTo 0
                   
                   Application.CutCopyMode = False
                   
                Next sh
            Workbooks(wb).Close False
        End If
        wb = Dir
    Loop
    Application.ScreenUpdating = True
   End Sub

请查看合并工作簿的外观(工作表名称和列格式与源工作簿完全相同)。
CONSOLIDATED WORKBOOK

b1payxdu

b1payxdu1#

以下行可用于查找合并工作表上加载的最新日期:

latest_date_loaded = Application.WorksheetFunction.Max(ThisWorkbook.Sheets(sh.Name).Range("A:A"))

下列行可用于工作表(sh)中,以创建一个从latest_date_loaded之后开始到表底部的区域(用于复制)。因此,您需要确保该区域按日期顺序排列。

Dim fndRng As Range, start_of_copy_row As Long, end_of_copy_row As Long, range_to_copy As Range

date_to_find = latest_date_loaded

Set fndRng = sh.Range("A:A").Find(date_to_find, LookIn:=xlValues, searchdirection:=xlPrevious)

If Not fndRng Is Nothing Then
    start_of_copy_row = fndRng.Row + 1
Else
    start_of_copy_row = 2 ' assuming row 1 has a header you want to ignore
End If

end_of_copy_row = sh.Cells(sh.Rows.Count, "A").End(xlUp).Row

Set range_to_copy = Range(start_of_copy_row & ":" & end_of_copy_row)
    • 编辑**

下面是使用我上面提到的一些代码行/想法对您的代码进行的修改。

Sub Copy_From_All_Workbooks()
    
    'declarations 
    Dim wb As String, i As Long, sh As Worksheet, fndRng As Range, _
    start_of_copy_row As Long, end_of_copy_row As Long, range_to_copy As _
    Range, latest_date_loaded As Date, consolidated_wb As Workbook
    
    'turn off screen updating for user experience
    'Application.ScreenUpdating = False
    
    'set a reference to the consolidated workbook
    Set consolidated_wb = ThisWorkbook
    
    'read parent folder of consolidated workbook
    wb = Dir(consolidated_wb.Path & "\*")
    
    'perform this loop until no more files
    Do Until wb = ""
    
        'make sure it doesn't try to open consolidated workbook (again)
        If wb <> consolidated_wb.Name Then
        
            'open found source workbook
            Workbooks.Open consolidated_wb.Path & "\" & wb
            
            'cycle through each sheet (sh)
            For Each sh In Workbooks(wb).Worksheets
                
                'on that sheet, find the latest date already existing
                latest_date_loaded = Application.WorksheetFunction.Max(consolidated_wb.Sheets(sh.Name).Range("A:A"))

                'find the last occurence of that date in column A
                Set fndRng = sh.Range("A:A").Find(latest_date_loaded, LookIn:=xlValues, _
                searchdirection:=xlPrevious)
                
                'if you find that date already then..
                If Not fndRng Is Nothing Then
                    'set the top row to where you found it, plus one
                    start_of_copy_row = fndRng.Row + 1
                Else
                    'otherwise, it's a new sheet, start on row two
                    start_of_copy_row = 2 ' assuming row 1 has a header you want to ignore
                End If
                
                'find the end of the table, using column A's contents
                end_of_copy_row = sh.Cells(sh.Rows.Count, "A").End(xlUp).Row
                
                'make sure there's something to copy
                If end_of_copy_row >= start_of_copy_row Then
                
                    'create a reference to the block of cells to copy
                    Set range_to_copy = sh.Range(start_of_copy_row & ":" & end_of_copy_row)
                    
                    'copy that range
                    range_to_copy.Copy
                    
                    'paste them, values only
                    consolidated_wb.Sheets(sh.Name).Cells(Rows.Count, 1).End(xlUp).Offset(1).PasteSpecial xlPasteValues
                    
                    'clear copy markings from screen
                    Application.CutCopyMode = False
                Else
                
                    'otherwise, do nothing here
                    
                End If
                
            Next sh
            
            'close the source workbook
            Workbooks(wb).Close False
        End If
        
        'get next potential filename
        wb = Dir
        
    Loop

    'turn back on screen updating
    Application.ScreenUpdating = True
    
End Sub

相关问题