Excel / VBA循环仅在第一个文件上执行

时间:2018-10-08 01:08:49

标签: excel excel-vba data-processing

我在一个文件夹下有大约100个.xls文件,并且我有一个Macro脚本来遍历每个文件夹进行一些数据处理。目的是将每个工作簿分为三个名称分别为N1N2N3。到目前为止,我的SplitData宏工作正常,但是提取的工作簿存在问题。

我想将新提取的三个工作簿合并到已经存在的工作簿中,而不是像“文件N1已经存在”那样得到警报。每次。由于上一个问题的建议答案,我更改了Application.DisplayAlerts = false,但现在出现了一个新错误:

禁用警报后,我提取的前两个工作簿会继续更新我开始提取的第一个工作簿中的结果,而第三个工作簿会陷入循环,并从启动工作簿中添加相同的结果。我以为我的循环有问题,但是找不到,有人可以帮我检查一下吗?

非常感谢!

这是我要遍历文件夹的代码:

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

这是SplitData宏:

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

2 个答案:

答案 0 :(得分:1)

似乎必须打开和关闭文件。

void Main()
{
    var sp = new SpecialPlan();
    sp.Contact = new SpecialContact(); // new Contact(); won't compile
}

abstract class Contact
{
}

class SpecialContact : Contact
{
}

abstract class Plan<T> where T: Contact
{
    protected T contact;
    public virtual T Contact { get { return contact; } set { contact = value; } }
}

class SpecialPlan : Plan<SpecialContact>
{
    public override SpecialContact Contact { get { return contact; } set { contact = value; } }
}

答案 1 :(得分:0)

您需要在循环中添加xFile = Dir,以循环浏览文件。

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

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

目前尚不清楚xFile如何传递给SplitData。 SplitData是否应该有一个接收xFile的参数?