Извлеките строки из электронной таблицы и поместите в несколько электронных таблиц

#excel #vba

#excel #vba

Вопрос:

Я хочу перебрать папку с файлами Excel и для каждого файла просмотреть каждую строку (начиная со строки 4) и для каждой строки посмотреть, какое значение находится в столбце «d», и вставить эту строку в конкретный файл Excel с именем, каким бы ни было значение в столбце «d».

  • Если файл не существует, его необходимо будет создать перед вставкой строки (при вставке начинайте со строки 4). Именем вновь созданного файла будет любое значение, указанное в столбце «d».

  • Если файл существует, копируемая строка будет добавлена (значение столбца d в данной строке).

Мой код не хочет перебирать все файлы.

 Sub CopyRowsIntoAppSpreadsheet()

Dim LastRow As Integer, i As Integer, erow As Integer
Dim AppFileName As String
Dim FilePath As String
Dim MyFolder As String
Dim MyFile As String
Dim wbk As Workbook

On Error Resume Next

Application.ScreenUpdating = False

With Application.FileDialog(msoFileDialogFolderPicker)

    .Title = "Please select a folder"
    .Show
    .AllowMultiSelect = False

    If .SelectedItems.Count = 0 Then 'If no folder is selected, abort
        MsgBox "You did not select a folder"
        Exit Sub
    End If

    MyFolder = .SelectedItems(1) amp; "" 'Assign selected folder to MyFolder

End With

MyFile = Dir(MyFolder) 'DIR gets the first file of the folder

'Loop through all files in a folder until DIR cannot find anymore

Do While MyFile <> “”

    'Opens the file and assigns to the wbk variable for future use
    Set wbk = Workbooks.Open(FileName:=MyFolder amp; MyFile)

    'Replace the line below with the statements you would want your macro to perform
    LastRow = ActiveSheet.Range("A" amp; Rows.Count).End(xlUp).Row

    For i = 4 To LastRow

        Range("d" amp; i).Select
        AppFileName = Selection.Value
        Rows(i).Select
        Selection.Copy
        FilePath = "C:UsersGaryDesktopEx Folder" amp; AppFileName amp; ".xlsx"

        If Not Dir(FilePath, vbDirectory) = vbNullString Then
            Workbooks.Open FileName:=FilePath
            Worksheets("Sheet1").Select
            erow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
            ActiveSheet.Cells(erow, 1).Select
            ActiveSheet.Paste
            Cells.Select
            Cells.EntireColumn.AutoFit
            ActiveWorkbook.Save
            ActiveWorkbook.Close
            Application.CutCopyMode = False

        Else
            Dim wkb As Workbook
            Set wkb = Workbooks.Add
            Rows(4).Select
            ActiveSheet.Paste
            wkb.SaveAs FileName:=FilePath
            Cells.Select
            Cells.EntireColumn.AutoFit
            ActiveWorkbook.Save
            ActiveWorkbook.Close
            Application.CutCopyMode = False

        End If

    Next i

    MyFile = Dir 'DIR gets the next file in the folder

Loop

Application.ScreenUpdating = True

MsgBox "Macro has completed! Woot! Woot!"

End Sub
  

Комментарии:

1. Итак, это работает, но не перебирает все файлы? Признаюсь, я обычно не использую dir (myfolder), но я протестирую это и посмотрю, смогу ли я помочь.

2. Прямо сейчас он только дважды просматривает последний файл, а затем завершает основной цикл, чтобы завершить программу. У меня нет никаких файлов (на основе значения столбца d), созданных в папке назначения. Я просто хотел, чтобы макрос их создавал.

3. Я внесу это изменение. Я действительно ценю это! Да, самая большая проблема на данный момент заключается в том, что он перебирает только один или два файла, а затем останавливается.

4. Это происходит с самым последним файлом в моем списке папок, поэтому он останавливается после первого файла.

5. Цикл строк, похоже, работает нормально. Похоже, проблема в цикле папок.

Ответ №1:

Хорошо, попробуйте это:

 Option Explicit
Sub CopyRowsIntoAppSpreadsheet()
Dim LastRow As Integer, erow As Integer, Rowcounter As Long
Dim AppFileName As String
Dim FilePath As String
Dim MyFolder As String
Dim MyFile As String
Dim Source As Workbook, shSource As workseet, Dest As Workbook, shDest As Worksheet
On Error Resume Next
Application.ScreenUpdating = False
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Please select a folder"
.Show
.AllowMultiSelect = False
If .SelectedItems.Count = 0 Then 'If no folder is selected, abort
    MsgBox "You did not select a folder"
    Exit Sub
End If
MyFolder = .SelectedItems(1) amp; "" 'Assign selected folder to MyFolder
End With
MyFile = Dir(MyFolder) 'DIR gets the first file of the folder
'Loop through all files in a folder until DIR cannot find anymore
Do Until MyFile = ""
    DoEvents
    Set Source = Workbooks.Open(Filename:=MyFolder amp; MyFile)
    Set shSource = Source.Sheets(1)
    LastRow = shSource.Range("A" amp; Rows.Count).End(xlUp).Row
    For Rowcounter = 4 To LastRow
        'get the name of the workbook to copy to
        AppFileName = Source.Cells(Rowcounter, 4)
        FilePath = "C:UsersGaryDesktopEx Folder" amp; AppFileName amp; ".xlsx"
        'and open it
        If FileExists(FilePath) Then
            Set Dest = Workbooks.Open(Filename:=FilePath)
        Else
            Set Dest = Workbooks.Add
        End If
        Set shDest = Dest.Sheets(1)
        'get the bottom row of the destination sheet
        erow = shDest.Cells(shDest.Rows.Count, 1).End(xlUp).Row
        shSource.Cells(Rowcounter, 1).EntireRow.Copy Destination:=shDest.Cells(erow   1, 1)
        Dest.SaveAs Filename:=FilePath
        Dest.Close
    'continue with next row
    Next Rowcounter
    Source.Close
    'repeat for next file
    MyFile = Dir()  'DIR gets the next file in the folder
Loop
Application.ScreenUpdating = True
MsgBox "Macro has completed! Woot! Woot!"
End Sub
Function FileExists(FilePath As String) As Boolean
Dim FSO As Object
Dim sFile As String
Set FSO = CreateObject("Scripting.FileSystemObject")
If Not FSO.FileExists(FilePath) Then
    FileExists = False
Else
    FileExists = True
End If
End Function
  

Комментарии:

1. я протестирую это сейчас.

2. Нет, я этого не делаю. Я довольно новичок в Excel VBA.

3. Большое вам спасибо. Я собираюсь возобновить это либо позже сегодня, либо завтра. Я обязательно свяжусь с вами. Большое вам спасибо!

Ответ №2:

Я удалил неправильно используемые On Error Resume Next и заменил ссылки на ActiveWorkbook и ActiveSheet. В большинстве случаев этого было бы достаточно.

Здесь оказывается, что второе использование Dir противоречит первому, поэтому проверьте существование рабочей книги другим способом.

 Option Explicit

Sub CopyRowsIntoAppSpreadsheet()

Dim LastRow As Long
Dim i As Long
Dim erow As Long

Dim AppFileName As String
Dim FilePath As String
Dim MyFolder As String
Dim MyFile As String

Dim wbk As Workbook
Dim wbkTarget As Workbook

Dim sht As Worksheet

'On Error Resume Next   ' Misused here

'Application.ScreenUpdating = False

With Application.FileDialog(msoFileDialogFolderPicker)

    .Title = "Please select a folder"
    .Show
    .AllowMultiSelect = False

    If .SelectedItems.Count = 0 Then 'If no folder is selected, abort
        MsgBox "You did not select a folder"
        Exit Sub
    End If

    MyFolder = .SelectedItems(1) amp; "" 'Assign selected folder to MyFolder
    Debug.Print MyFolder

End With

MyFile = Dir(MyFolder) 'DIR gets the first file of the folder

'Loop through all files in a folder until DIR cannot find anymore
'Do While MyFile <> “”
Do While MyFile <> ""

    'Opens the file and assigns to the wbk variable for future use
    Set wbk = Workbooks.Open(FileName:=MyFolder amp; MyFile)

    LastRow = wbk.Worksheets("Sheet1").Range("A" amp; Rows.Count).End(xlUp).Row

    For i = 4 To LastRow

        Range("d" amp; i).Select
        AppFileName = Selection.Value

        Rows(i).Select
        Selection.Copy

        FilePath = "C:UsersGaryDesktopEx Folder" amp; AppFileName amp; ".xlsx"

        ' Reset wbkTarget or
        '  the tricky On Error Resume Next keeps the previous valid wbkTarget
        Set wbkTarget = Nothing
        On Error Resume Next
        Set wbkTarget = Workbooks.Open(FileName:=FilePath)
        ' turn off error bypass as soon as the purpose is served
        On Error GoTo 0

        If Not wbkTarget Is Nothing Then

            Set sht = wbkTarget.Worksheets("Sheet1")
            erow = sht.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row

            With sht
                .Cells(erow, 1).Select
                .Paste
                .Cells.Select
                .Cells.EntireColumn.AutoFit
            End With

            wbkTarget.Close True

         Else ' Address the bypassed error

            Set wbkTarget = Workbooks.Add
            Set sht = wbkTarget.Worksheets("Sheet1")

            With sht
                .Rows(4).Select
                .Paste
                .Cells.Select
                .Cells.EntireColumn.AutoFit
            End With

            With wbkTarget
                .SaveAs FileName:=FilePath
                .Close
            End With

        End If

        Application.CutCopyMode = False

    Next i

    wbk.Close False

    MyFile = Dir 'DIR gets the next file in the folder
    Debug.Print MyFile

Loop

Application.ScreenUpdating = True

MsgBox "Macro has completed."

End Sub