Condividi tramite

merge files excel

Anonimo
2018-12-19T14:20:12+00:00

Ciao a tutti. Ho questo problema. Ho un certo numero di file excel che hanno il foglio 1 con la stessa struttura a tabella. Dovrei fare un merge per avere un solo foglio riassuntivo. Potrei aprire ogni singolo foglio, selezionare l'area da copiare e incollare le singole aree in un nuovo foglio. Per velocizzare volevo scrivere una routine che si posizionasse sulla cartella e per ogni file presente nella cartella effettuasse l'apertura, la copia e l'incolla nel nuovo file.

Sono un po' arrugginito con il vba (a memoria mi sembra che si può creare un ciclo for each ... next definendo come variabile il percorso della cartella) per cui se qualcuno ha un esempio a portata di mano sarei veramente grato.

Massimo.

Microsoft 365 e Office | Excel | Per la casa | Windows

Domanda bloccata. Questa domanda è stata eseguita dalla community del supporto tecnico Microsoft. È possibile votare se è utile, ma non è possibile aggiungere commenti o risposte o seguire la domanda.

0 commenti Nessun commento

3 risposte

Ordina per: Più utili
  1. Anonimo
    2019-01-02T08:48:58+00:00

    Ciao tos58, 

    Per richieste relative lo sviluppo di macro, nel frattempo che attendi le indicazioni di Norman David Jones, ti suggerisco anche di confrontarti con il nostro forum gemello MSDN. Si tratta di una Community di Sviluppatori IT, tra cui Norman stesso, entusiasti di approfondire con te questa tipologia di richiesta.

    Rimaniamo a tua disposizione.

    Saluti, 

    Francesca

    La risposta è stata utile?

    0 commenti Nessun commento
  2. Anonimo
    2018-12-21T10:49:11+00:00

    Grazie intanto per il codice. Ho aggiunto una funzione SheetExits per la verifica dell'esistenza del foglio in quanto si bloccava sul punto. La routine quando la lancio vedo che lavora fino ad un certo punto che da l'errore "metodo Calculation in _application non riuscito". Inoltre sul foglio "sSummary" non viene copiato nessun dato. Ti copio di seguito il codice con le modifiche che ho inserito (percorso cartella, colonna "N" come ultima per l'area di copia, la funzione SheetExist).

    Ti ringrazio se lo controlli.

    CODICE

    Option Explicit

    Public Sub Crea_Riepilogo_Di_Tutti_File_In_Cartella()

        Dim FSO As Object

        Dim oFile As Object

        Dim oFiles As Object

        Dim oFolder As Object

        Dim srcWb As Workbook, destWB As Workbook

        Dim srcSH As Worksheet, destSH As Worksheet

        Dim srcRng As Range, destRng As Range

        Dim arrIn() As Variant, arrHeaders() As Variant

        Dim iCtr As Long, jCtr As Long, kCtr As Long

        Dim i As Long, j As Long

        Dim LRow As Long, iCol As Long

        Dim sName As String

        Dim sMsg As String, sTitle As String

        Dim iButtons As Long

        Dim CalcMode As Long

        Const sSummary As String = "Riepilogo"

        Const sPercorso As String = "C:\Users\mantonini\Desktop\Nuova cartella"                    '<<=== Modifica

        Const sFileType As String = "*.xlsx"                '<<=== Modifica

        Const sUltimaColonna As String = "N"            '<<=== Modifica

        On Error GoTo XIT

        Set destWB = ThisWorkbook

        With destWB

            On Error Resume Next

            With Application

                .EnableEvents = False

                .ScreenUpdating = False

                CalcMode = .Calculation

                .Calculation = xlCalculationManual

            End With

            If Not SheetExists(sSummary) Then

                Set destSH = destWB.Sheets.Add(After:=.Sheets(.Sheets.Count))

                destSH.Name = sSummary

            Else

                Set destSH = .Sheets(sSummary)

                destSH.UsedRange.Offset(1).ClearContents

            End If

        End With

        iCol = destSH.Columns(sUltimaColonna).Column

        Set FSO = CreateObject("Scripting.FileSystemObject")

        Set oFolder = FSO.GetFolder(sPercorso)

        If oFolder Is Nothing Then

            Err.Raise 76

            GoTo XIT

        End If

        Set oFiles = oFolder.Files

        If oFiles Is Nothing Then

            Err.Raise 100

            GoTo XIT

        End If

        For Each oFile In oFiles

            With oFile

                If .Name Like sFileType Then

                    kCtr = kCtr + 1

                    Set srcWb = Workbooks.Open(oFile)

                    Set srcSH = srcWb.Sheets(1)

                    With srcSH

                        LRow = LastRow(srcSH, .Columns("A:A"))

                        Set srcRng = .Range("A2").Resize(LRow - 1, iCol)

                        jCtr = iCtr

                        iCtr = iCtr + LRow - 1

                        If Not IsArrayAllocated(arrHeaders) Then

                            arrHeaders = srcRng.Rows(0).Value

                            ReDim Preserve arrHeaders(1 To 1, 1 To iCol + 1)

                            arrHeaders(1, iCol + 1) = "File Originario"

                        End If

                    End With

                    ReDim Preserve arrIn(1 To iCol + 1, 1 To iCtr)

                    For i = 1 To LRow - 1

                        For j = 1 To iCol

                            arrIn(j, jCtr + i) = srcRng.Cells(i, j).Value

                        Next j

                        arrIn(j, jCtr + i) = oFile.Name

                    Next i

                    srcWb.Close savechanges:=False

                End If

            End With

        Next oFile

        If Not CBool(iCtr) Then

            Call MsgBox(Prompt:="Nessun file del tipo designato  " & sFileType & " è stato trovato ", Buttons:=vbInformation, Title:="REPORT")

            Exit Sub

        End If

        With destSH

            Set destRng = destSH.Range("A2").Resize(iCtr, j)

            destRng.Value = Application.Transpose(arrIn)

            With destRng.Rows(0)

                .Value = arrHeaders

                .Font.Bold = True

            End With

            .UsedRange.EntireColumn.AutoFit

        End With

    XIT:

        With Application

            .ScreenUpdating = True

            .Calculation = CalcMode

            .EnableEvents = True

        End With

        Select Case Err.Number

        Case Is = 0

            sMsg = "Finito!" & vbNewLine & vbNewLine & kCtr & " file sono stati gestiti"

            sTitle = "REPORT"

            iButtons = vbInformation

        Case Is = 76

            sMsg = "Il percorso " & sPercorso & " non è valido!"

            iButtons = vbCritical

            sTitle = "CONTROLLA PERCORSO!"

        Case 100

            sMsg = "Nessun file del tipo " & sFileType & " è stato trovato!"

            iButtons = vbCritical

            sTitle = "CONTROLLA CARTELLA!"

        Case Else

            sMsg = "Errore " & Err.Number & vbNewLine & Err.Description

            iButtons = vbCritical

            sTitle = "ERRORE!"

        End Select

        Call MsgBox(Prompt:=sMsg, Buttons:=iButtons, Title:=sTitle)

    End Sub

    Public Function LastRow(SH As Worksheet, Optional rng As Range, Optional minRow As Long = 1, Optional sPassword As String)

        Dim bProtected As Boolean

        With SH

            If rng Is Nothing Then

                Set rng = .Cells

            End If

            bProtected = .ProtectContents = True

            If bProtected Then

                Application.ScreenUpdating = False

                .Unprotect Password:=sPassword

            End If

        End With

        On Error Resume Next

        LastRow = rng.Find(What:="*", After:=rng.Cells(1), Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False).Row

        On Error GoTo 0

        If LastRow < minRow Then

            LastRow = minRow

        End If

        If bProtected Then

            SH.Protect Password:=sPassword, UserInterfaceOnly:=True

        End If

        Application.ScreenUpdating = True

    End Function

    Public Function IsArrayAllocated(Arr As Variant) As Boolean

        On Error Resume Next

        IsArrayAllocated = IsArray(Arr) And Not IsError(LBound(Arr, 1)) And LBound(Arr, 1) <= UBound(Arr, 1)

    End Function

    Function SheetExists(SheetName As String) As Boolean

    Dim Test As Boolean

    On Error Resume Next

    Test = Sheets(SheetName).Range("A1").Select

    If Test Then

        SheetExists = True

    Else

        SheetExists = False

    End If

    End Function

    La risposta è stata utile?

    0 commenti Nessun commento
  3. Anonimo
    2018-12-19T16:49:46+00:00

    Ciao Massimo,

    Ho questo problema. Ho un certo numero di file excel che hanno il foglio 1 con la stessa struttura a tabella. Dovrei fare un merge per avere un solo foglio riassuntivo. Potrei aprire ogni singolo foglio, selezionare l'area da copiare e incollare le singole aree in un nuovo foglio. Per velocizzare volevo scrivere una routine che si posizionasse sulla cartella e per ogni file presente nella cartella effettuasse l'apertura, la copia e l'incolla nel nuovo file.

    Sono un po' arrugginito con il vba (a memoria mi sembra che si può creare un ciclo for each ... next definendo come variabile il percorso della cartella) per cui se qualcuno ha un esempio a portata di mano sarei veramente grato.

    Prova qualcosa del genere:

    ·   Alt+F11 per aprire l'editor di VBA

    ·   Alt+IMper inserire un nuovo modulo di codice

         ·   Nel nuovo modulo vuoto, incolla il seguente codice:

     '===========>>

    Option Explicit

    '----------->>

    Public Sub Crea_Riepilogo_Di_Tutti_File_In_Cartella()

        Dim FSO As Object

        Dim oFile As Object

        Dim oFiles As Object

        Dim oFolder As Object

        Dim srcWb As Workbook, destWB As Workbook

        Dim srcSH As Worksheet, destSH As Worksheet

        Dim srcRng As Range, destRng As Range

        Dim arrIn() As Variant, arrHeaders() As Variant

        Dim iCtr As Long, jCtr As Long, kCtr As Long

        Dim i As Long, j As Long

        Dim LRow As Long, iCol As Long

        Dim sName As String

        Dim sMsg As String, sTitle As String

        Dim iButtons As Long

        Dim CalcMode As Long

        Const sSummary As String = "Riepilogo"

        Const sPercorso As String = _

              "**C:\Users\NDJ\Documents**"                    '<<=== Modifica

        Const sFileType As String = "*.xlsx"                '<<=== Modifica

        Const sUltimaColonna As String = "G"            '<<=== Modifica

        On Error GoTo XIT

        Set destWB = ThisWorkbook

        With destWB

            On Error Resume Next

            With Application

                .EnableEvents = False

                .ScreenUpdating = False

                CalcMode = .Calculation

                .Calculation = xlCalculationManual

            End With

            If Not SheetExists(sSummary) Then

                Set destSH = destWB.Sheets.Add( _

                             After:=.Sheets(.Sheets.Count))

                destSH.Name = sSummary

            Else

                Set destSH = .Sheets(sSummary)

                destSH.UsedRange.Offset(1).ClearContents

            End If

        End With

        iCol = destSH.Columns(sUltimaColonna).Column

        Set FSO = CreateObject("Scripting.FileSystemObject")

        Set oFolder = FSO.GetFolder(sPercorso)

        If oFolder Is Nothing Then

            Err.Raise 76

            GoTo XIT

        End If

        Set oFiles = oFolder.Files

        If oFiles Is Nothing Then

            Err.Raise 100

            GoTo XIT

        End If

        For Each oFile In oFiles

            With oFile

                If .Name Like sFileType Then

                    kCtr = kCtr + 1

                    Set srcWb = Workbooks.Open(oFile)

                    Set srcSH = srcWb.Sheets(1)

                    With srcSH

                        LRow = LastRow(srcSH, .Columns("A:A"))

                        Set srcRng = .Range("A2").Resize(LRow - 1, iCol)

                        jCtr = iCtr

                        iCtr = iCtr + LRow - 1

                        If Not IsArrayAllocated(arrHeaders) Then

                            arrHeaders = srcRng.Rows(0).Value

                            ReDim Preserve arrHeaders(1 To 1, 1 To iCol + 1)

                            arrHeaders(1, iCol + 1) = "File Originario"

                        End If

                    End With

                    ReDim Preserve arrIn(1 To iCol + 1, 1 To iCtr)

                    For i = 1 To LRow - 1

                        For j = 1 To iCol

                            arrIn(j, jCtr + i) = srcRng.Cells(i, j).Value

                        Next j

                        arrIn(j, jCtr + i) = oFile.Name

                    Next i

                    srcWb.Close savechanges:=False

                End If

            End With

        Next oFile

        If Not CBool(iCtr) Then

            Call MsgBox( _

                 Prompt:="Nessun file del tipo designato  " & sFileType _

                         & " è stato trovato ", _

                 Buttons:=vbInformation, _

                 Title:="REPORT")

            Exit Sub

        End If

        With destSH

            Set destRng = destSH.Range("A2").Resize(iCtr, j)

            destRng.Value = Application.Transpose(arrIn)

            With destRng.Rows(0)

                .Value = arrHeaders

                .Font.Bold = True

            End With

            .UsedRange.EntireColumn.AutoFit

        End With

    XIT:

        With Application

            .ScreenUpdating = True

            .Calculation = CalcMode

            .EnableEvents = True

        End With

        Select Case Err.Number

        Case Is = 0

            sMsg = "Finito!" _

                   & vbNewLine & vbNewLine _

                   & kCtr & " file sono stati gestiti"

            sTitle = "REPORT"

            iButtons = vbInformation

        Case Is = 76

            sMsg = "Il percorso " & sPercorso & " non è valido!"

            iButtons = vbCritical

            sTitle = "CONTROLLA PERCORSO!"

        Case 100

            sMsg = "Nessun file del tipo " _

                   & sFileType _

                   & " è stato trovato!"

            iButtons = vbCritical

            sTitle = "CONTROLLA CARTELLA!"

        Case Else

            sMsg = "Errore " & Err.Number _

                   & vbNewLine & Err.Description

            iButtons = vbCritical

            sTitle = "ERRORE!"

        End Select

        Call MsgBox( _

             Prompt:=sMsg, _

             Buttons:=iButtons, _

             Title:=sTitle)

    End Sub

    '--------->>

    Public Function LastRow(SH As Worksheet, _

                            Optional rng As Range, _

                            Optional minRow As Long = 1, _

                            Optional sPassword As String)

        Dim bProtected As Boolean

        With SH

            If rng Is Nothing Then

                Set rng = .Cells

            End If

            bProtected = .ProtectContents = True

            If bProtected Then

                Application.ScreenUpdating = False

                .Unprotect Password:=sPassword

            End If

        End With

        On Error Resume Next

        LastRow = rng.Find(What:="*", _

                           After:=rng.Cells(1), _

                           Lookat:=xlPart, _

                           LookIn:=xlFormulas, _

                           SearchOrder:=xlByRows, _

                           SearchDirection:=xlPrevious, _

                           MatchCase:=False).Row

        On Error GoTo 0

        If LastRow < minRow Then

            LastRow = minRow

        End If

        If bProtected Then

            SH.Protect Password:=sPassword, _

                       UserInterfaceOnly:=True

        End If

        Application.ScreenUpdating = True

    End Function

    '--------->>

    Public Function IsArrayAllocated(Arr As Variant) As Boolean

        On Error Resume Next

        IsArrayAllocated = IsArray(Arr) And _

                           Not IsError(LBound(Arr, 1)) And _

                           LBound(Arr, 1) <= UBound(Arr, 1)

    End Function

    '<<========= 

    ·  Alt+Q per chiudere l'editor di VBA e tornare a Excel

    ·  Salva il file con l’estensione xlsm

    ·  Alt+F8 per aprire  la finestra di gestione delle macro

    ·  Seleziona Tester 

    ·  Esegui

    ===

    Regards,

    Norman

    La risposta è stata utile?

    0 commenti Nessun commento