demid
demid

Reputation: 370

Excel/VBA loop only executes on the first file

I'm have about 100 .xls files under one folder and I have a Macro script to loop through each one to do some data processing. The objective is to split each workbook into three with name N1, N2, N3 respectively. So far my SplitData Macro worked fine but I have issue with extracted workbooks.

I want to merge newly extracted three workbooks to already existed ones instead of getting alerts like "File N1 already exists." every time. I changed Application.DisplayAlerts = false because of my previous question's suggested answer but now I got a new error:

After the alert is disabled, my first two extracted workbook keeps updating same result from the first workbook that I started extraction while the third one trapped in a loop, adding same result from the starting workbook. I assume there's something wrong with my loop but cannot find it, can anyone help me check please?

Thanks a lot!

This is my code to loop through folder:

Sub OpenFiles()
    Dim xStrPath As String
    Dim xFileDialog As FileDialog
    Dim xFile As String
    On Error Resume Next
    Set xFileDialog = Application.FileDialog(msoFileDialogFolderPicker)
    xFileDialog.AllowMultiSelect = False
    xFileDialog.Title = "Select a folder"
    If xFileDialog.Show = -1 Then
        xStrPath = xFileDialog.SelectedItems(1)
    End If
    If xStrPath = "" Then Exit Sub
    xFile = Dir(xStrPath & "\*.xls")

    Do While xFile <> ""
        Call SplitData
    Loop
End Sub

This is SplitData Macro:

Sub SplitData()
 ' 1. Fill every cells in merged columns for future steps
            Dim cell As Range, joinedCells As Range

            For Each cell In Range("E4:I60")
                If cell.MergeCells Then
                    Set joinedCells = cell.MergeArea
                    cell.MergeCells = False
                    joinedCells.Value = cell.Value
                End If
            Next


            ' 2. Split original sheet into three based on one col value 
            ' loop through selected column to check if has different values
            Const NameCol = "B"
            Const HeaderRow = 3
            Const FirstRow = 4
            Dim SrcSheet As Worksheet
            Dim TrgSheet As Worksheet
            Dim SrcRow As Long
            Dim LastRow As Long
            Dim TrgRow As Long
            Dim Student As String
            Application.ScreenUpdating = False
            Set SrcSheet = ActiveSheet
            LastRow = SrcSheet.Cells(SrcSheet.Rows.Count, NameCol).End(xlUp).Row
            For SrcRow = FirstRow To LastRow
                Student = SrcSheet.Cells(SrcRow, NameCol).Value
                Set TrgSheet = Nothing
                On Error Resume Next
                Set TrgSheet = Worksheets(Student)
                On Error GoTo 0
                If TrgSheet Is Nothing Then
                    Set TrgSheet = Worksheets.Add(After:=Worksheets(Worksheets.Count))
                    TrgSheet.Name = Student
                    SrcSheet.Rows(HeaderRow).Copy Destination:=TrgSheet.Rows(HeaderRow)
                End If
            TrgRow = TrgSheet.Cells(TrgSheet.Rows.Count, NameCol).End(xlUp).Row + 1
            SrcSheet.Rows(SrcRow).Copy Destination:=TrgSheet.Rows(TrgRow)
            Next SrcRow
            Application.ScreenUpdating = True


            ' 3. Extract three new worksheets into three workbooks 
            Dim Pointer As Long

            Set MainWorkBook = ActiveWorkbook
            Range("E4").Value = MainWorkBook.Sheets.Count

            Application.ScreenUpdating = False   'enhance the performance
            For Pointer = 2 To MainWorkBook.Sheets.Count
                Set NewWorkbook = Workbooks.Add
                MainWorkBook.Sheets(Pointer).Copy After:=NewWorkbook.Sheets(1)
                Application.DisplayAlerts = False
                NewWorkbook.Sheets(1).Delete
                Application.DisplayAlerts = False
                With NewWorkbook
                    .SaveAs Filename:="D:\***\Inventory\" & MainWorkBook.Sheets(Pointer).Name & ".xls"
                End With
                NewWorkbook.Close SaveChanges:=True
            Next Pointer

            Application.ScreenUpdating = True

End Sub

Upvotes: 0

Views: 1030

Answers (2)

Dy.Lee
Dy.Lee

Reputation: 7567

It seems to have to open and close the file.

Sub OpenFiles()
    Dim xStrPath As String
    Dim xFileDialog As FileDialog
    Dim xFile As String
    On Error Resume Next
    Set xFileDialog = Application.FileDialog(msoFileDialogFolderPicker)
    xFileDialog.AllowMultiSelect = False
    xFileDialog.Title = "Select a folder"
    If xFileDialog.Show = -1 Then
        xStrPath = xFileDialog.SelectedItems(1)
    End If
    If xStrPath = "" Then Exit Sub
    xFile = Dir(xStrPath & "\*.xls")

    Dim Wb As Workbook
    Do While xFile <> ""
        Set Wb = Workbooks.Open(Filename:=xStrPath & "\" & xFile) '<~~ open file
        Call SplitData
        Wb.Close (0) '<~~ close file
        xFile = Dir '<~~ re dir
    Loop
End Sub

Upvotes: 1

user4039065
user4039065

Reputation:

You need to add xFile = Dir in your loop to cycle through the files.

...
    xFile = Dir(xStrPath & "\*.xls")

    Do While xFile <> ""
        Call SplitData
        xFile = Dir
    Loop
...

It's unclear on how xFile gets passed to SplitData. Shouldn't SplitData have an argument that receives xFile?

Upvotes: 0

Related Questions