Come unire piu fogli Excel in un unico foglio

Anonimo
2017-09-14T14:10:56+00:00

Ciao a tutti

ho molteplici file Excel che vorrei unire in un unico foglio/file.

Grazie a chiunque potrà darmi uno aiuto.

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
Risposta accettata dall'autore della domanda
Anonimo
2017-10-03T13:11:45+00:00

Ciao Flavia,

Scusami scausami scusami Norman

Ti scuso tutto e ti scuso sempre!  

...hai ragione...mi sono dimenticata di dirti che in questo caso mi serve l'unione in un unico foglio. In pratica, avevo eseguito la macro "CreaRiepilogo",  la prima che mi hai inviato, unendo tutti i singoli fogli di ogni file in un unico file/foglio. Per questo non ho avuto problema con il nome uguale dei fogli. Scusami...troppe cose insieme !

Ho trovato due problemi che non avevo previsto con i tuoi file, ossia:

  1. Alcune celle dei fogli di interesse contengono testo con più di 255 caratteri, un fatto che provocca un errore con il metodo Application.Transpose;
  2. Alcune celle dei fogli di interesse sono vuote nella colonna A.

Quindi, per gestire anche queste possibilità, sostituisci il codice della procedura 

CreaRiepilogoPerOgniFileInCartella con la seguente versione:

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

Public Sub CreaRiepilogoPerOgniFileInCartella()

    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, ArrOut() 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 UB As Long, UB2 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 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)

                    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

        UB = UBound(arrIn)

        UB2 = UBound(arrIn, 2)

        ReDim ArrOut(1 To UB2, 1 To UB)

        For i = 1 To UB2

            For j = 1 To UB

                ArrOut(i, j) = arrIn(j, i)

            Next j

        Next i

        Set destRng = destSH.Range("A2").Resize(UB2, UB)

        destRng.Value = ArrOut

        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

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

Eseguendo questa versione del codice, e utililizzando i dieci file caricati da te, ottengo un foglio di riepilogo del seguente genere:

===

Regards,

Norman

La risposta è stata utile?

2 persone hanno trovato utile questa risposta.
0 commenti Nessun commento
Risposta accettata dall'autore della domanda
Anonimo
2017-09-21T15:28:58+00:00

Ciao Flavia,

L'ideale sarebbe mantenere i nomi originali dei vari fogli ma se questo non dovesse essere possibile va benissimo anche come hai suggerito tu. Posso sempre rinominarli dopo se necessario.

OK, ma nota che questo metodo richieda che i nomi di tutti i fogli di tutti i file di interesse siano unici in quanto non è possibile avere due fogli con lo stesso nome nello stesso file.

Detto ciò, prova a sostituire il codice precedente con la seguente versione:

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

Option Explicit

    Private Const sPercorso As String = _

          "**C:\Users\Flavia\Documenti\Pippo**"                    '<<=== Modifica

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

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

Public Sub CreaFoglioPerOgniFoglioDiOgniFileInCartella()

    Dim FSO As Object

    Dim oFile As Object

    Dim oFiles As Object

    Dim oFolder As Object

    Dim srcWb As Workbook, destWB As Workbook

    Dim SH As Worksheet, srcSH As Worksheet, destSH As Worksheet

    Dim srcRng As Range, destRng As Range

    Dim iCtr As Long, jCtr As Long, iSheets As Long

    Dim LRow As Long, LCol As Long

    Dim sName As String

    Dim sMsg As String, sTitle As String

    Dim iButtons As Long

    Dim CalcMode As Long

    On Error GoTo XIT

    Set destWB = ThisWorkbook

    iSheets = destWB.Sheets.Count

    On Error Resume Next

    With Application

        .EnableEvents = False

        .ScreenUpdating = False

        CalcMode = .Calculation

        .Calculation = xlCalculationManual

    End With

    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

                iCtr = iCtr + 1

                Set srcWb = Workbooks.Open(oFile)

                For Each SH In srcWb.Worksheets

                    jCtr = jCtr + 1

                    Set srcSH = SH

                    With srcSH

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

                        LCol = LastCol(srcSH)

                        Set srcRng = .Range("A1").Resize(LRow, LCol)

                    End With

                    sName = SH.Name

                    With destWB

                        If Not SheetExists(sName) Then

                            Set destSH = .Sheets.Add(after:=.Sheets(.Sheets.Count))

                            destSH.Name = sName

                        Else

                            Set destSH = .Sheets(sName)

                            destSH.UsedRange.ClearContents

                        End If

                    End With

                    Set destRng = destSH.Range("A1")

                    srcRng.Copy

                    With destRng

                        .PasteSpecial Paste:=xlPasteColumnWidths

                        .PasteSpecial Paste:=xlPasteAll, _

                                      Operation:=xlNone, _

                                      SkipBlanks:=False, _

                                      Transpose:=False

                    End With

                Next SH

                srcWb.Close savechanges:=False

            End If

        End With

    Next oFile

    Call SortWorksheets(aWB:=ThisWorkbook, _

                        iPrimoFoglioDaOrdinare:=iSheets + 1, _

                        SortDescending:=False)

    If Not CBool(iCtr) Then

        Call MsgBox( _

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

                     & " è stato trovato ", _

             Buttons:=vbInformation, _

             Title:="REPORT")

        Exit Sub

    End If

XIT:

    With Application

        .ScreenUpdating = True

        .Calculation = CalcMode

        .EnableEvents = True

    End With

    Select Case Err.Number

    Case Is = 0

        sMsg = "Finito!" _

               & vbNewLine & vbNewLine _

               & iCtr & " file  comprendendo " _

               & jCtr & " fogli di lavoro 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 Sub CreaRiepilogoPerOgniFileInCartella()

    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"                   '<<=== 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 Sub SortWorksheets(Optional aWB, _

                          Optional iPrimoFoglioDaOrdinare As Long = 1, _

                          Optional SortDescending As Boolean = False)

    Dim i As Long, j As Long

    Dim iSheets As Long

    If IsMissing(aWB) Then

        Set aWB = ActiveWorkbook

    End If

    With aWB

        iSheets = .Worksheets.Count

        For j = iPrimoFoglioDaOrdinare To iSheets

            For i = j To iSheets

                If SortDescending = True Then

                    If UCase(.Worksheets(i).Name) > UCase(.Worksheets(j).Name) Then

                        .Worksheets(i).Move Before:=.Worksheets(j)

                    End If

                Else

                    If UCase(.Worksheets(i).Name) < UCase(.Worksheets(j).Name) Then

                        .Worksheets(i).Move Before:=.Worksheets(j)

                    End If

                End If

            Next i

        Next j

    End With

End Sub

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

Public Function LastRow(SH As Worksheet, _

                        Optional Rng As Range, _

                        Optional minRow As Long = 1, _

                        Optional strPassword As String)

    Dim bProtected As Boolean

    With SH

        If Rng Is Nothing Then

            Set Rng = .Cells

        End If

        bProtected = .ProtectContents = True

        If bProtected Then

            .Unprotect Password:=strPassword

        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:=strPassword, _

                   UserInterfaceOnly:=True

    End If

End Function

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

Public Function LastCol(SH As Worksheet, _

                        Optional Rng As Range, _

                        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

            .Unprotect Password:=sPassword

        End If

    End With

    On Error Resume Next

    LastCol = Rng.Find(What:="*", _

                       after:=Rng.Cells(1), _

                       Lookat:=xlPart, _

                       LookIn:=xlFormulas, _

                       SearchOrder:=xlByColumns, _

                       SearchDirection:=xlPrevious, _

                       MatchCase:=False).Column

    On Error GoTo 0

    If bProtected Then

        SH.Protect Password:=sPassword, _

                   UserInterfaceOnly:=True

    End If

End Function

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

Public Function SheetExists(sSheetName As String, _

                            Optional ByVal WB As Workbook) As Boolean

    On Error Resume Next

    If WB Is Nothing Then

        Set WB = ThisWorkbook

    End If

    SheetExists = CBool(Len(WB.Sheets(sSheetName).Name))

    On Error GoTo 0

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

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

Nota che, dato il numero di fogli da importare,  per facilitarne la ricerca, ho aggiunto una procedura per ordinarli,  in modo crescente, dopo i fogli esistenti.

===

Regards,

Norman

La risposta è stata utile?

2 persone hanno trovato utile questa risposta.
0 commenti Nessun commento

34 risposte aggiuntive

Ordina per: Più utili
  1. Anonimo
    2017-09-22T10:44:11+00:00

    Ciao Norman,

    ho provato a eseguire la macro e ho notato che le schede non vengono create nello stesso ordine in cui si trovano all'interno di ogni file ma in ordine alfabetica. A questo punto penso che mi sarebbe più utile usare la versione proposta inizialmente da te:

    Se non è chiederti troppo, me la potresti mandare ?

    Pippo-1, Pippo-2 ... Pippo-n

    Pluto-1, Pluto-2 ... Pluto-n

    ... ... ...

    Paperino, Paperino-2 ... Paperino-n

    Grazie mille per la tua pazienza  #^_^#

    Flavia

    La risposta è stata utile?

    0 commenti Nessun commento
  2. Anonimo
    2017-09-21T13:16:07+00:00

    Ciao Norman,

    L'ideale sarebbe mantenere i nomi originali dei vari fogli ma se questo non dovesse essere possibile va benissimo anche come hai suggerito tu. Posso sempre rinominarli dopo se necessario.

    Grazie per la tua immensa disponibilità,

    Flavia

    La risposta è stata utile?

    0 commenti Nessun commento
  3. Anonimo
    2017-09-21T11:29:11+00:00

    GRAZIE MILLE, Norman !! Mi hai già risolto un grande problema e non saprei ringraziarti !

    Inizialmente l'esecuzione dell'ultima versione (con le due Public Sub: CreaRiepilogoPerOgniFileInCartella + CreaFoglioPerOgniFileInCartella) mi dava errore nella Sub CreaFoglioPerOgniFileInCartella. Allora l'ho confrontata con la penultima versione e ho visto che mancava l'istruzione On Error GoTo 0in Plubli Function SheetExists. L’ho aggiunta e funziona alla grande 😊

    Public Function SheetExists(sSheetName As String, _

                                Optional ByVal WB As Workbook) As Boolean

        On Error Resume Next

        If WB Is Nothing Then

            Set WB = ThisWorkbook

        End If

        SheetExists = CBool(Len(WB.Sheets(sSheetName).Name))

       On Error GoTo 0

    End Function

    Mi manca in realtà un ultimo passaggio che non ti avevo specificato prima. Se non è chiederti troppo, se possible, vorrei che venissero creati si un foglio per ogni file ma se qualche file contiene più di un foglio vorrei che venissero creati tutti quanti (es. CreaFoglioPerOgniFoglioDeiFileInCartella). Potresti aiutarmi anche in questo ? Spero non averti complicato troppo la vita.

    La risposta è stata utile?

    0 commenti Nessun commento