Option Explicit
'======================================================================================
'Requires the Reference "Microsoft for Visual Basic for Applications Exetnsibility 5.3"
'======================================================================================
Sub Test()
    Call CopyWorkbookToNewWorkbook(ThisWorkbook, IncludeVBAProject:=True)
End Sub
'------------------------------------
'Copy as Workbook into a new Workbook
'------------------------------------
Sub CopyWorkbookToNewWorkbook(SourceWorkbook As Workbook, Optional IncludeVBAProject As Boolean = False)
    Dim TargetWorkbook As Workbook
    Dim TabArray() As Variant
    Dim VBComponents As VBComponents
    Dim VBComponent As VBComponent
    Dim VBComponentExtension As String
    Dim VBComponentFileName As String
    Dim VBComponentsCollection As New Collection
    Dim ErrNumber As Long
    Dim S As String
    Dim i As Integer
    Dim k As Integer
    Dim p As Integer
    Dim Rep As VbMsgBoxResult
    Dim Rep2 As VbMsgBoxResult
    
    Application.ScreenUpdating = False
    
    On Error Resume Next
    If IncludeVBAProject Then
        Set VBComponents = SourceWorkbook.VBProject.VBComponents
        If Err Then
            Rep = MsgBox("En l'etat le niveau de sécurité dans les options d'Excel" & vbCrLf & _
                          "Ne permet pas la copie des modules" & vbCrLf & vbCrLf & _
                          "Vous devez cochez l'accès aprouvé à l'objet du modèle de projet vba" & vbCrLf & vbCrLf & _
                          "Voulez vous aller activer  cet accès approuvé " & vbCrLf & _
                          "Vous pourez réessayer apres l'export", vbYesNo + vbInformation)
            
            If Rep = vbYes Then
                Application.CommandBars.ExecuteMso "MacroSecurity"
                Exit Sub
            Else
                Rep2 = MsgBox("Très bien pas de modules exportés" & vbCrLf & _
                               "Voulez vous continuer la creation" & vbCrLf & "du clone de ce classeur Sans ces Macros !!!", vbYesNo, vbInformation)
                If Rep2 = vbNo Then Exit Sub
            End If
        End If
    End If
    
    '----------------------------------------------------------------------------------
    'Copy the source Workbook & Worksheets with their VBA code to a new target Workbook
    '----------------------------------------------------------------------------------
    With SourceWorkbook
        ReDim TabArray(1 To .Worksheets.Count)
        ReDim chartarray(1)
        For i = 1 To .Worksheets.Count
            TabArray(i) = i
        Next i
        
        'Creates a new target Workbook with the selected source Workbook Worksheets
        .Worksheets(TabArray).Select
        Worksheets.Copy
        Set TargetWorkbook = ActiveWorkbook
        '-------------------------------------
        'Added by patricktoulon
        'Ajout de la copie des feuilles graphiques(thisworkbook.charts)
        'exemple
        'un graphique dans une feuille  =        Worksheets("Feuil1").ChartObjects ("mongraphique")
        'une feuille graphique          =        ThisWorkbook.Charts("mongraphique")
        '-------------------------------------
        Dim C
        For Each C In ThisWorkbook.Charts
            C.Copy After:=ActiveWorkbook.Sheets(ActiveWorkbook.Sheets.Count)
        Next
        '--------------------------------------
        'Added by patricktoulon
        'copie du code dans Thisworkbook
        Dim code$
        With ThisWorkbook.VBProject.VBComponents("Thisworkbook")
            code = .CodeModule.Lines(1, .CodeModule.CountOfLines)
        End With
        If Trim(code) <> "" Then
            With ActiveWorkbook.VBProject.VBComponents("Thisworkbook")
                .CodeModule.InsertLines 1, code
            End With
         End If
        
        
        'Needed to "unlock" the all Worksheets Selection
        With SourceWorkbook
            .Activate
            .Worksheets(1).Select
        End With
        
        TargetWorkbook.Activate
        
        '---------------
        'Copy the Shapes
        '---------------
        For i = 1 To .Worksheets.Count
            For k = 1 To .Worksheets(i).Shapes.Count
                'Copy the Shape and its position
                .Worksheets(i).Shapes(k).Copy
                TargetWorkbook.Worksheets(i).Paste
                TargetWorkbook.Worksheets(i).Shapes(k).Left = .Worksheets(i).Shapes(k).Left
                TargetWorkbook.Worksheets(i).Shapes(k).Top = .Worksheets(i).Shapes(k).Top
                
                'Adapt the OnAction string
                S = .Worksheets(i).Shapes(k).OnAction
                If Not Len(S) = 0 Then
                    p = InStr(S, "!")
                    If p > 0 Then
                        If Replace(Left(S, p - 1), "'", "") = SourceWorkbook.Name Then
                            TargetWorkbook.Worksheets(i).Shapes(k).OnAction = "'" & TargetWorkbook.Name & "'!" & Mid(S, p + 1)
                        End If
                    End If
                End If
            Next k
            
            'Release the last Shape selected
            ActiveCell.Select
        Next i
    End With
    
    '------------------------------------------------------------
    'Include the VBA Project Modules, Class Modules and UserForms
    '------------------------------------------------------------
    If IncludeVBAProject Then
        If VBEOK Then
            Set VBComponents = SourceWorkbook.VBProject.VBComponents
            
            If Not VBComponents Is Nothing Then
                'Export VBComponents of the source Workbook
                For Each VBComponent In VBComponents
                    Select Case VBComponent.Type
                        Case vbext_ct_StdModule
                            VBComponentExtension = ".bas"
                            
                        Case vbext_ct_ClassModule
                            VBComponentExtension = ".cls"
                            
                        Case vbext_ct_MSForm
                            VBComponentExtension = ".frm"
                            
                        Case Else
                            VBComponentExtension = ""
                    End Select
                    
                    If Not Len(VBComponentExtension) = 0 Then
                        VBComponentFileName = Environ("TMP") & "\" & VBComponent.Name & VBComponentExtension
                        
                        If Not Len(Dir(VBComponentFileName)) = 0 Then
                            Kill VBComponentFileName
                        End If
                        
                        VBComponent.Export VBComponentFileName
                        VBComponentsCollection.Add VBComponentFileName
                    End If
                Next VBComponent
                
                'Import VBComponents to the new target Workbook
                Do While VBComponentsCollection.Count > 0
                    TargetWorkbook.VBProject.VBComponents.Import VBComponentsCollection(1)
                    Kill VBComponentsCollection(1)
                    VBComponentsCollection.Remove 1
                Loop
                
                'Copy the Reference list of the source Workbook into the target new Workbook
                With SourceWorkbook
                    On Error Resume Next
                    For i = 1 To .VBProject.References.Count
                        TargetWorkbook.VBProject.References.AddFromFile .VBProject.References.Item(i).FullPath
                    Next i
                    On Error GoTo 0
                End With
            End If
        End If
    End If
    
    Application.ScreenUpdating = True
    
    'Close the source Workbook
    SourceWorkbook.Close SaveChanges:=False
End Sub
'-------------------------------------------------------------------------------------
'Return True if the "Trust Access to the VBA Project Object Model" checkbox is checked
'-------------------------------------------------------------------------------------
Function VBEOK() As Boolean
    Dim Version As String
    Dim ErrNumber As Long
    
    On Error Resume Next
    Version = ThisWorkbook.VBProject.VBE.Version
    ErrNumber = Err.Number
    On Error GoTo 0
    
    If ErrNumber = 0 Then
        'Return value
        VBEOK = True
    End If
End Function