Salvare TUTTI i moduli basfrmcls



  • Salvare TUTTI i moduli (.bas,.frm,.cls)
    di marxitpa data: 29/11/2013 09:32:14

    Se può essere utile segnalo modulo per Salvare TUTTI i moduli macro (.bas, .frm, .cls) in una directory.
    E' necessario:
    * in VisualBasic: Aggiunte > Riferimenti > spuntare Microsoft Visual Basic forApplications Extensibility 5.3
    * in Excel: macro > protezione > Fonti attendibili > spuntare la voce "Considera attendibile l'accesso al modello a oggetti dei progetti VBA"

     
    Sub esporta_moduliVBA()
    '--------------------------
    ' Copiare n moduli macro in un altro file
    '// Si deve aggiungere un riferimento alla Library: -
    '// "Microsoft Visual Basic forApplications Extensibility 5.3"
    '// Menù> Strumenti | Riferimenti
    '--------------------------
    Dim VBComp As VBIDE.VBComponent
    Dim VBComps As VBIDE.VBComponents
    Dim miapath As String
    miapath = "d:macro" ' cambia la destinazione a tuo piacimento
    Set VBComps = ThisWorkbook.VBProject.VBComponents
    For Each VBComp In VBComps
    If VBComp.Type = 1 Then
    VBComp.Export miapath & "" & VBComp.Name & ".frm"  ' form
    VBComp.Export miapath & "" & VBComp.Name & ".bas"  ' moduli
    VBComp.Export miapath & "" & VBComp.Name & ".cls"  ' thisWorkbook
    
    End If
    Next VBComp
    End Sub
    



  • di Vecchio Frac data: 29/11/2013 09:47:26

    Ottimo spunto marxitpa, grazie.

    Ma l'hai testato?
    A naso mi sembra che qualcosa non funzioni bene dentro l'If, perchè lì si controlla il type di ogni componente e quando è 1 avviene l'esportazione... però questa esportazione avviene in sequenza del medesimo componente che viene salvato tre volte con tre estensioni diverse. Forse questo comportamento è da rettificare proprio in funzione del Type di ciascun oggetto.

    In particolare ti do questa informazione:
    (valore di type: tipo di oggetto)
    1: moduli
    2: moduli di classe
    3: UserForm


    p.s. non servirebbe nemmeno referenziare il riferimento citato, perchè basta dimensionare as object VBComp e VBComps.
    Infatti VBIDE è un riferimento nascosto e quindi i singoli componenti del VBProject vengono visti lo stesso.
    Quanto sopra non è una critica, anzi apprezzo moltissimo il tuo contributo! e ti invito a proporne altri.
    Diciamo che si tratta solo di una verifica per il miglioramento :)





  • di marxitpa data: 29/11/2013 09:54:01

    ho verificato e sembra funzionare.
    Ben vengano tutti i miglioramenti.

    ... a seguire lavoriamo per importare in altro file TUTTI i codici non sovrapponendo quelli esistenti.


  • ... Importa TUTTI i moduli
    di marxitpa data: 29/11/2013 11:12:56

    e a seguire il codice che dovrebbe importare TUTTI i moduli macro .bas (ma poi si può procedere con .frm, .cls) da una directory in altro file (attenzione ai codici con stesso nome).

    Non mi funziona ...
    dov'è l'errore?
     
    Sub importa_Bas()
    miapath = "d:macro"
    ChDir miapath
    FileName = Dir("*.bas")
    If FileName = "" Then Exit Sub
    While FileName <> ""
    Application.VBE.ActiveVBProject.VBComponents.Import _
    (FileName)
    FileName = Dir
    Wend
    End Sub


  • IMPORTANTE !!!
    di marxitpa data: 29/11/2013 11:22:44

    ovviamente i due codici possono essere verificati, migliorati e utilizzati a piacere.
    Devo però evidenziare che spuntare la voce 'Considera attendibile l'accesso al modello a oggetti dei progetti VBA' è una scelta molto delicata perchè si tocca una protezione importante. "Consente di evitare che un codice maligno proveniente da un documento apparentemente innocuo possa contenere del codice che possa andare a modificare l'ambiente VBA"



  • di marxitpa (utente non iscritto) data: 29/11/2013 11:35:46


    Vecchio Frac hai ragione (come sempre!) e me ne scuso (il medesimo componente viene salvato tre volte con tre estensioni diverse).
    Il codice comunque mi sembra funzionare per i form.

    L'entusiasmo mi ha portato a creare confusione ... me ne scuso.

    Però può essere un punto di partenza per un buon risultato complessivo


     
    If VBComp.Type = 1 Then
    VBComp.Export miapath & "" & VBComp.Name & ".frm"  ' form
    End If



  • di marxitpa data: 29/11/2013 11:44:34

    ... sono fuso (che figura) ... volevo dire per i .bas
     
    If VBComp.Type = 1 Then
    VBComp.Export miapath & "" & VBComp.Name & ".bas"  ' moduli
    End If



  • di Vecchio Frac data: 29/11/2013 13:53:55

    cit. " la voce 'Considera attendibile l'accesso al modello a oggetti dei progetti VBA' è una scelta molto delicata perchè si tocca una protezione importante. "
    ---> Già. Ma non è come accettare caramelle da uno sconosciuto: di solito, anche se recupero codice qua e là, prima di farlo girare prendo qualche precauzione ^_^
    E poi diciamocelo: VBA può fare qualche danno al sistema, ma solo in casi davvero estremi.





  • di patel data: 29/11/2013 15:08:14

    un codice per l'esportazione che mi sembra funzioni bene è

     
    Public Sub ExportModules()
    szExportPath = "C:esporta"
        On Error Resume Next
            Kill szExportPath & "*.*"
        On Error GoTo 0
        szSourceWorkbook = ActiveWorkbook.Name
        Set wkbSource = Application.Workbooks(szSourceWorkbook)
        For Each cmpComponent In wkbSource.VBProject.VBComponents
            bExport = True
            szFileName = cmpComponent.Name
            Select Case cmpComponent.Type
                Case vbext_ct_ClassModule
                    szFileName = szFileName & ".cls"
                Case vbext_ct_MSForm
                    szFileName = szFileName & ".frm"
                Case vbext_ct_StdModule
                    szFileName = szFileName & ".bas"
                Case vbext_ct_Document
                    bExport = False
            End Select
            
            If bExport Then
                cmpComponent.Export szExportPath & szFileName
            ' remove it from the project if you want
            'wkbSource.VBProject.VBComponents.Remove cmpComponent
            End If
        Next cmpComponent
        MsgBox "Esportazione terminata"
    End Sub
    






  • di patel data: 29/11/2013 15:27:47

    Scusate, il codice sopra riportato salva senza estensione
     
    Public Sub ExportModules()
    szExportPath = "C:UsersandreDesktopexcelUserformesporta"
        On Error Resume Next
            Kill szExportPath & "*.*"
        On Error GoTo 0
        szSourceWorkbook = ActiveWorkbook.Name
        Set wkbSource = Application.Workbooks(szSourceWorkbook)
        For Each cmpComponent In wkbSource.VBProject.VBComponents
            bExport = True
            szFileName = cmpComponent.Name
            ct = cmpComponent.Type
            Select Case ct
                Case 100
                    szFileName = szFileName & ".cls"
                Case 3
                    szFileName = szFileName & ".frm"
                Case 1
                    szFileName = szFileName & ".bas"
                Case Else
                    bExport = False
            End Select
            
            If bExport Then
                cmpComponent.Export szExportPath & szFileName
            ' remove it from the project if you want
            'wkbSource.VBProject.VBComponents.Remove cmpComponent
            End If
        Next cmpComponent
        MsgBox "Esportazione completata"
    End Sub
    






  • di patel data: 29/11/2013 15:55:38

    per l'importazione potrebbe essere usata questa, penso da migliorare
     
    Public Sub ImportModules()
        delmodules = True
        If ActiveWorkbook.Name = ThisWorkbook.Name Then delmodules = False
        szTargetWorkbook = ActiveWorkbook.Name
        Set wkbTarget = Application.Workbooks(szTargetWorkbook)
        szImportPath = "C:UsersandreDesktopexcelUserformesporta"
        Set objFSO = CreateObject("Scripting.FileSystemObject")
        If objFSO.GetFolder(szImportPath).Files.Count = 0 Then
           MsgBox "Nessun file da importare"
           Exit Sub
        End If
        Call DeleteVBAModulesAndUserForms(delmodules)
        Set cmpComponents = wkbTarget.VBProject.VBComponents
        For Each objFile In objFSO.GetFolder(szImportPath).Files
            If (objFSO.GetExtensionName(objFile.Name) = "cls") Or _
                (objFSO.GetExtensionName(objFile.Name) = "frm") Or _
                (objFSO.GetExtensionName(objFile.Name) = "bas") Then
                cmpComponents.Import objFile.Path
            End If
        Next objFile
        MsgBox "Importazione completata"
    End Sub
    
    Function DeleteVBAModulesAndUserForms(delmodules)
            Set VBProj = ActiveWorkbook.VBProject
            For Each VBComp In VBProj.VBComponents
                If VBComp.Type = 100 Or VBComp.Type = 1 Then
                    'Thisworkbook or worksheet module
                    'We do nothing
                Else
                    VBProj.VBComponents.Remove VBComp
                End If
            Next VBComp
    End Function






  • di marxitpa data: 29/11/2013 16:23:17

    FUNZIONANO sia codice per esportazione che quello per l'importazione !!!
    Grazie Patel ... sei FORTE.



  • di patel data: 29/11/2013 17:07:37

    la mia forza sta nel usare Google





  • di marxitpa data: 29/11/2013 18:58:56