Aggiungere, Eliminare Moduli VBE e Creare, Eliminare Macro tramite istruzioni in VBA. - dal 04/09/04 pagina vista: volte

Su tutti i libri ai quali finora ho attinto, non ho mai trovato istruzioni o accenni alla possibilità di manipolare Oggetti del VBE (Visual Basic Editor) o procedure (macro) tramite altre istruzioni vba. In diversi mi hanno scritto chiedendomi come si poteva fare, e per quanto era a mia conoscenza ho sempre risposto che per me era impossibile modificare codice vba tramite altro codice vba. Dovrei porgere le mie scuse a questi signori, ma le migliori scuse sono ora quelle di provare a spiegare come fare, visto che dopotutto ho sempre sostenuto di essere un dilettante è non un esperto, quindi mi sia concesso di "non sapere" molte cose.

Le procedure che presento le ho reperite al sito  http://www.mvps.org/dmcritchie/excel/xlindex.htm sono state presentate e, credo realizzate da Chip Pearson , e sono rintracciabili all'articolo : VBE, Programming to The Visual Basic Editor, Chip Pearson, code to add/delete modules, [to manually delete from within the VBE, File, Remove Module] che comunque allego come file .doc zippato (Crea-elimina macro.zip 12 kb), nel quale trovate tutte le spiegazioni originali in inglese.

Mi limito ad illustrare solo quatto procedure, ( le altre potrete leggerle sul file zip ) :

  • Aggiungere un nuovo Modulo Standard al progetto VB

  • Eliminare un Modulo Standard dal progetto VB

  • Creare una macro in un Modulo Standard

  • Eliminare una Macro da un Modulo Standard

Esistono differenze operative che dipendono dalla versione di Excel installata, queste procedure sono disponibili per le versioni 2000 e 2002, per la versione 97, leggete le istruzioni sul file zip. Comunque per tutte le versioni, le procedure potranno lavorare SOLO se il progetto vba NON è protetto da password.

Prima di utilizzare le procedure, è necessario dal menù Strumenti/Riferimenti del Visual Basic Editor, caricare, mettendo un segno di spunta, e confermando con OK, la libreria  "Microsoft Visual Basic For Applications Extensibility 5.3 come mostrato nell'immagine sotto:

spostandosi poi sul foglio di lavoro, scegliere dal menu di Excel  Strumenti/Macro/Protezione, si aprirà questa finestra dove nella cartella "Fonti attendibili" dovrà essere messo un segno di spunta alla casella "Considera attendibile l'accesso al progetto Visual Basic".

Fatti questi passaggi senza i quali le procedure non funzionerebbero generando un errore, passiamo ad esaminarle.

  • Aggiungere un nuovo Modulo Standard al progetto VB - questa procedura consente di aggiungere un modulo standard al progetto della cartella di lavoro aperta (WorkBook). La procedura andrà inserita in un nuovo modulo, e gestita come una normale macro, quindi associata ad un pulsante per essere lanciata, oppure essere richiamata in qualsiasi altra procedura esistente nel progetto. La procedura si basa sul metodo Add (aggiungi) e richiede che venga fornito il nome con il quale chiamare il modulo. Attenzione a non usare nomi di moduli già esistenti. Potrà essere gestito (il nome) come una variabile, che prenderà il nome da una cella di un foglio di lavoro, assegnando la variabile alla riga VBComp.Name = "tua variabile"

Sub AddModule()
Dim VBComp As VBComponent
Set VBComp = ThisWorkbook.VBProject.VBComponents.Add(vbext_ct_StdModule)
VBComp.Name = "NuovoModulo"
Application.Visible = True
End Sub

  • Eliminare un Modulo Standard dal progetto VB - questa è la procedura inversa, per eliminare un modulo standard esistente nel progetto, anche qui, attenzione al nome del modulo da eliminare, nell'esempio eliminiamo il modulo creato sopra:

Sub DeleteModule()
Dim VBComp As VBComponent
Set VBComp = ThisWorkbook.VBProject.VBComponents("NuovoModulo")
ThisWorkbook.VBProject.VBComponents.Remove VBComp
End Sub

  • Creare una macro in un Modulo Standard - gestire questa procedura non è difficile, come si nota, si deve indicare in quale Modulo inserire la macro (usiamo ancora NuovoModulo ) e dopo le istruzioni che provvedono ad aggiungere una nuova riga, si devono inserire sia il nome che vorremo dare alla macro, sia le istruzioni relative, sia la fine della macro. Queste istruzioni vengono viste come stringhe, pertanto per ogni riga di istruzione della macro da creare, sarà necessario ricordarsi dei caratteri per andare a capo ( & Chr(13) & _ ) alla fine di ogni riga, e i doppi apici:

Sub AddProcedure()

Dim VBCodeMod As CodeModule
Dim LineNum As Long

Set VBCodeMod = ThisWorkbook.VBProject.VBComponents("NuovoModulo").CodeModule
With VBCodeMod
LineNum = .CountOfLines + 1
.InsertLines LineNum, _
"Sub MiaMacro()" & Chr(13) & _
" Msgbox ""Ciao,  sono una nuova macro"" " & Chr(13) & _
"End Sub"
End With
'questa riga sotto, dopo che la macro è stata creata, la lancia. Se vogliamo solo che venga 'creata, basta togliere la riga
Application.Run "MiaMacro"

End Sub

  • Eliminare una Macro da un Modulo Standard - finalmente arriviamo alla risposta di tante richieste: come eliminare una macro esistente. Anche qui dobbiamo indicare il nome del modulo sul quale risiede la macro da eliminare, e il nome della macro

Sub DeleteProcedure()

Dim VBCodeMod As CodeModule
Dim StartLine As Long
Dim HowManyLines As Long

Set VBCodeMod = ThisWorkbook.VBProject.VBComponents("NuovoModulo").CodeModule
With VBCodeMod
StartLine = .ProcStartLine("MiaMacro", vbext_pk_Proc)
HowManyLines = .ProcCountLines("MiaMacro", vbext_pk_Proc)
.DeleteLines StartLine, HowManyLines
End With

End Sub

Questa procedura può essere utilizzata alla chiusura di una cartella di lavoro, se non si voglia lasciare traccia di istruzioni, Un esempio ripreso da una domanda, potrebbe essere il seguente:

....quindi devo cancellare la macro in automatico e salvare la cartella senza di essa.
quindi fare SaveAs con questo codice (ma copia anche la macro)
    stringa = "C:\pippo_" & Format(Date, "yyyymmdd") & ".xls"

    ActiveWorkbook.SaveAs Filename:=stringa, _
    FileFormat:=xlNormal, Password:="", WriteResPassword:="", _
    ReadOnlyRecommended:=False, CreateBackup:=False

    ActiveWorkbook.Save
    ActiveWorkbook.Close

 

che potrebbe diventare, fornendo alla procedura Sub DeleteProcedure(), il nome del modulo e il nome della macro da cancellare (in questo modo, prima del salvataggio del nuovo file , si cancella la macro)


    stringa = "C:\pippo_" & Format(Date, "yyyymmdd") & ".xls"
    ActiveWorkbook.SaveAs Filename:=stringa, _
    FileFormat:=xlNormal, Password:="", WriteResPassword:="", _
    ReadOnlyRecommended:=False, CreateBackup:=False


    DeleteProcedure


    ActiveWorkbook.Save
    ActiveWorkbook.Close

  • Modificare (con una delle procedure viste sopra) un'altra cartella Excel. Questa aggiunta la propongo come variante, e come vedrete, non è difficile imparare il meccanismo; simuliamo la creazione di una nuova Macro in un modulo di un'altra cartella. Vediamo due esempi:

  • 1) con entrambe le cartelle aperte: quella che contiene le istruzioni, e l'altra che "riceve" la creazione della nuova macro dal nome "Pippo.xls" (si suppone di conoscere già il nome del modulo presente nella cartella Pippo, altrimenti andrebbe creato usando la procedura adatta):

Sub AddProcWkb()
Dim VBCodeMod As CodeModule
Dim LineNum As Long
'sotto, come si nota, si è aggiunto il nome dell'altro file aperto, dove si vuole che venga creata la macro, 'dopo la parola Workbooks
Set VBCodeMod=Workbooks("Pippo.xls").VBProject.VBComponents("NuovoModulo").CodeModule
'le altre istruzioni sono le stesse, e verrà creata una macro che lancerà un messaggio come istruzione da 'eseguire, ognuno inserirà le istruzioni a lui necessarie. Ricordarsi dei caratteri per andare a capo al termine 'di ogni riga, il tutto, per ogni riga della nuova macro, messo tra doppi apici, come si fa con le stringhe.
With VBCodeMod
LineNum = .CountOfLines + 1
.InsertLines LineNum, _
"Sub MiaProcedura()" & Chr(13) & _
" Msgbox ""Questa è una nuova macro"" " & Chr(13) & _
"End Sub"
End With
MsgBox "Completato" 
Alla fine avvisiamo con un messaggio
End Sub

  • 2) con il file destinazione chiuso. In questo caso esiste un problema di "indici". L'istruzione di impostazione della variabile VBCodeMod "vede" il Workbooks come l' "insieme" di workbook, e cerca l'indice per identificarlo; il file chiuso, non facendo parte dell'insieme, non possiede un indice e l'istruzione falla. Ho girato l'ostacolo in questa maniera: apro il file di destinazione, gli creiamo la macro, lo salviamo e lo richiudiamo. La cosa funziona velocemente, e non si nota nessun passaggio.:

Sub AddProcWb()

Dim VBCodeMod As CodeModule
Dim LineNum As Long
'sotto: si apre il secondo file indicando il percorso completo che mira al file
Workbooks.Open Filename:=("C:\Temp\Pippo.xls")

'si impostano le stesse istruzioni viste sopra:
Set VBCodeMod = Workbooks("Pippo.xls").VBProject.VBComponents("NuovoModulo").CodeModule

With VBCodeMod
LineNum = .CountOfLines + 1
.InsertLines LineNum, _
"Sub MiaProcedura()" & Chr(13) & _
" Msgbox ""Questa è una nuova macro"" " & Chr(13) & _
"End Sub"
End With
Workbooks("Pippo.xls").Save
'si salva il file con la nuova macro
Workbooks("Pippo.xls").Close
'si chiude il file modificato

MsgBox "fatto !!"
' e si avvisa con il messaggio
End Sub

Consiglio comunque di leggersi il file zip allegato, per la presenza di spiegazioni e di altre interessanti procedure non riportate in questo articolo.

Buon lavoro.

prelevato sul sito www.ennius.altervista.org