1
votes

I want to merge a worksheet content named "Task tracking" from 3 different workbooks named Sub WB1, Sub WB2 and Sub WB3 into single Main Workbooks Task tracking worksheet. Please help.

There are 4 workbook in total with 12 worksheets in each.

  • Main Workbook
  • Sub WB1
  • Sub WB2
  • Sub WB3

I want to merge the data from "Task Tracking" (Worksheet name) from Sub WB1, Sub WB2 and Sub WB3 into Main Workbook using a Consolidate button in the main workbook.

I used the below code which I got from some reference but I am getting Runtime Error: 1004. Please help.

Sub MergeSpecificWorkbooks()

    Dim MyPath 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
    Dim SaveDriveDir As String
    Dim FName As Variant


     'Change ScreenUpdating, Calculation and EnableEvents
    With Application
        CalcMode = .Calculation
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
        .EnableEvents = False
    End With

      'SaveDriveDir = CurDir
      'ChDirNet "D:\DD_Task1\"

      path = "D:\DD_Task1\"

      'FName = Application.GetOpenFilename("Sub WB1.xls, Sub WB2.xls, Sub WB3.xls", MultiSelect:=True)

    FName = Application.GetOpenFilename(filefilter:="Sub WB1.xlsm, Sub WB2.xlsm, Sub WB3.xlsm", _
    MultiSelect:=True)

    If IsArray(FName) Then
         'Add a new workbook with one sheet
         'Set BaseWks = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
        Set BaseWks = Worksheets.Add
        BaseWks.Name = "Master"
        rnum = 2

         'Loop through all files in the array(myFiles)
        For FNum = LBound(FName) To UBound(FName)
            Set mybook = Nothing
            On Error Resume Next
            Set mybook = Workbooks.Open(FName(FNum))
            On Error GoTo 0
            If Not mybook Is Nothing Then
                On Error Resume Next
                With mybook.Worksheets("H-POD")
                    .Unprotect
                    LC = .Cells(.Rows.Count, "C").End(xlUp).Row
                    Set sourceRange = .Range("B10:M" & LC)
                End With
                If Err.Number > 0 Then
                    Err.Clear
                    Set sourceRange = Nothing
                Else
                     'if SourceRange use 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 "Sorry there are not enough rows in the sheet"
                        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 = FName(FNum)
                        End With
                         'Set the destrange
                        Set destrange = BaseWks.Range("B" & rnum)
                         'we copy the values from the sourceRange to the destrange
                        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 ScreenUpdating, Calculation and EnableEvents
    With Application
        .ScreenUpdating = True
        .EnableEvents = True
        .Calculation = CalcMode
    End With

     ' ChDirNet SaveDriveDir

End Sub
1

1 Answers

2
votes

GetOpenFilename() method doesn't accept such a FileFilter syntax as "Sub WB1.xlsm, Sub WB2.xlsm, Sub WB3.xlsm"

if you want the user to select files with given names only then you have to use a UserForm

for instance you could act as follows:

  • change:

    FName = Application.GetOpenFilename("Sub WB1.xls, Sub WB2.xls, Sub WB3.xls", MultiSelect:=True)
    

    to:

    FName = GetFName()
    
  • add the following Function (maybe in the same module as your Sub's one)

    Function GetFName() As Variant
        Dim iList As Long
        Dim selectedFiles As String
    
        With ListFiles_UF
            With .ListBox1
                .MultiSelect = fmMultiSelectMulti
                .List = Array("Sub WB1.xlsm", "Sub WB2.xlsm", "Sub WB3.xlsm")
            End With
            .Show
            With .ListBox1
                If .ListIndex > 0 Then
                    For iList = 0 To .ListCount - 1
                        If .Selected(iList) Then selectedFiles = selectedFiles & .List(iList) & "|"
                    Next
                    GetFName = Split(Left(selectedFiles, Len(selectedFiles) - 1), "|")
                End If
            End With
        End With
    End Function
    
  • add a UserForm to your VBA Project and name it after "ListFiles_UF" (you can choose any other valid name but be consistent with it throughout all code)

  • place a ListBox control (by default named after "ListBox1") and a CommandButton control (by default named after "CommandButton1") in the "ListFiles_UF" userform

  • put this code into "ListFiles_UF" code pane

    Private Sub CommandButton1_Click()
        Me.Hide
    End Sub