简体   繁体   中英

How to append data to existing workbook's sheet and don't create a new workbook

I am trying to work out what I need to change in the following VBA code to append the data at the bottom of data that already exists in a workbook named " Main " and a worksheet named " summary ":

Sub MergeAllWorkbooks()
Dim MyPath As String, FilesInPath As String
Dim MyFiles() As String
Dim SourceRcount As Long, FNum As Long
Dim mybook As Workbook, BaseWks As Worksheet
Dim sourceRange As Range, destrange As Range
Dim rnum As Long, CalcMode As Long

' Change this to the path\folder location of your files.
MyPath = "C:\test\"

' Add a slash at the end of the path if needed.
If Right(MyPath, 1) <> "\" Then
    MyPath = MyPath & "\"
End If

' If there are no Excel files in the folder, exit.
FilesInPath = Dir(MyPath & "*.xl*")
If FilesInPath = "" Then
    MsgBox "No files found"
    Exit Sub
End If

' Fill the myFiles array with the list of Excel files
' in the search folder.
FNum = 0
Do While FilesInPath <> ""
    FNum = FNum + 1
    ReDim Preserve MyFiles(1 To FNum)
    MyFiles(FNum) = FilesInPath
    FilesInPath = Dir()
Loop
FNum = FNum - 1

' Set various application properties.
With Application
    CalcMode = .Calculation
    .Calculation = xlCalculationManual
    .ScreenUpdating = False
    .EnableEvents = False
End With

' Add a new workbook with one sheet.
Set BaseWks = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
rnum = 1

' Loop through all files in the myFiles array.
If FNum > 0 Then
    For FNum = LBound(MyFiles) To UBound(MyFiles)
        Set mybook = Nothing
        On Error Resume Next
        Set mybook = Workbooks.Open(MyPath & MyFiles(FNum))
        On Error GoTo 0

        If Not mybook Is Nothing Then
            On Error Resume Next

            ' Change this range to fit your own needs.
          With mybook.Worksheets(1)
                Set sourceRange = .Range("A2:T" & CStr(mybook.Worksheets(1).Range("A2").CurrentRegion.Rows.Count))
            End With

            If Err.Number > 0 Then
                Err.Clear
                Set sourceRange = Nothing
            Else
                ' If source range uses all columns then
                ' skip this file.
                If sourceRange.Columns.Count >= BaseWks.Columns.Count Then
                    Set sourceRange = Nothing
                End If
            End If
            On Error GoTo 0

            If Not sourceRange Is Nothing Then

                SourceRcount = sourceRange.Rows.Count

                If rnum + SourceRcount >= BaseWks.Rows.Count Then
                    MsgBox "There are not enough rows in the target worksheet."
                    BaseWks.Columns.AutoFit
                    mybook.Close savechanges:=False
                    GoTo ExitTheSub
                Else

                    ' Copy the file name in column A.
                    With sourceRange
                        BaseWks.Cells(rnum, "A"). _
                                Resize(.Rows.Count).Value = MyFiles(FNum)
                    End With

                    ' Set the destination range.
                    Set destrange = BaseWks.Range("B" & rnum)

                    ' Copy the values from the source range
                    ' to the destination range.
                    With sourceRange
                        Set destrange = destrange. _
                                        Resize(.Rows.Count, .Columns.Count)
                    End With
                    destrange.Value = sourceRange.Value

                    rnum = rnum + SourceRcount
                End If
            End If
            mybook.Close savechanges:=False
        End If

    Next FNum
    BaseWks.Columns.AutoFit
End If

ExitTheSub:
' Restore the application properties.
With Application
    .ScreenUpdating = True
    .EnableEvents = True
    .Calculation = CalcMode
End With
End Sub

Thank you

I do not like this code. There is lots I object to but I am most unhappy about the use of error handling:

  • The error handling functionality is there to allow your routine to fail gracefully when something goes wrong. It is not there to allow you to ignore errors and carry on as though they did not happen.

  • The error handling failed to handle a problem with one of my workbooks. I have not investigated but I suspect the problem is either the length of a single cell or the total length of the data being transferred by destrange.Value = sourceRange.Value .

However, you ask how to make a single change so I will limit myself to that.

I suggest the easiest approach would be to create workbook "Main" with worksheet "Summary" and to include your macro in it.

Add new statements under the Dim statements:

  Dim rnum As Long, CalcMode As Long

  '### Start of new code    
  If Workbooks.Count > 1 Then
    ' It is easy to get into a muddle if there are multiple workbooks
    ' open at the start of a macro like this.  Avoid the problem until
    ' you understand it.
    Call MsgBox("Please close all other workbooks", vbOKOnly)
    Exit Sub
  End If

  Set BaseWks = ActiveWorkBook.Worksheets("Summary")
  With BaseWks
    rnum = .Cells(Rows.Count, "A").End(xlUp).Row + 1
  End With
 '### End of new code  

 ' Change this to the path\folder location of your files.

The first block of the above code ensures there are no other workbooks open.

The second block (1) sets BaseWks to worksheet "Summary" and (2) sets rnum to the first unused row in "Summary". End(xlUp) is the VBA equivalent of clicking Ctrl + Up . So I have gone to the bottom of column A, gone up until I hit a row with a value and then down 1 row.

Replace the loop that locates the filenames with:

  Do While FilesInPath <> ""

    If FilesInPath <> ActiveWorkbook.Name Then
      FNum = FNum + 1
      ReDim Preserve MyFiles(1 To FNum)
      MyFiles(FNum) = FilesInPath
    End If
    FilesInPath = Dir()

  Loop

I assume that workbook "Main" will be in the same folder as the other workbooks. This change ensures that "Main" is not used as a source.

Discard these statements:

Set BaseWks = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
rnum = 1

because I have already set BaseWks and rnum to the values I require.

If you want to save the updated workbook "Main" automatically, add the following statement above ExitTheSub: :

ActiveWorkbook.Save

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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