giovedì 16 ottobre 2014

VBA-Office: Aprire un file di Excel da VBA disabilitando le Macro

Capita a volte di dover aprire un file Excel da codice e che questo abbia al suo interno delle macro che possono interferire con il corretto funzionamento del nostro programma. I suggerimenti che ho trovato on-line su questo argomento non sono realmente efficaci in quanto tendono a disabilitare gli eventi dell'applicazione Excel e questo può interferire con il nostro stesso programma VBA. Per esempio se il mio codice VBA sta girando su una applicazione Excel e deve aprire un'altro file Excel e mettiamo in atto la disabilitazione degli eventi, questo impatterà anche sul file contenente il mio codice. Oppure: se debbo aprire due files di cui uno con le macro abilitate e l'altro no la soluzione di disabilitare gli eventi non è valida.
Per fortuna Microsoft ci da una soluzione che salva capra e cavoli. E' sufficiente alzare il livello di protezione macro di Excel a "Disattiva tutte le macro senza notifica" prima di aprire il file in questione e poi ripristinare il livello di protezione a quello che era impostato in precedenza. La proprietà da impostare è l'AutomationSecurity che restituisce dei valori elencati nel tipo MsoAutomationSecurity

Ecco un esempio:

    Dim Exc As Excel.Application
    Dim Wb As Excel.Workbook
    Dim secAutomation As MsoAutomationSecurity
    
    'Istanzio l'applicazione Excel e rilevo il livello di sicurezza corrente
    Set Exc = New Excel.Application
    secAutomation = Exc.AutomationSecurity
    'Imposto il livello di sicurezza a "Disattiva tutte le macro senza notifica"
    Exc.AutomationSecurity = msoAutomationSecurityForceDisable
    'Apro il file Excel con le macro disabilitate
    Set Wb = Exc.Workbooks.Open(FileName:="NomeFile.xlsm")
    'Reimposto il livello di sicurezza precedente

    Exc.AutomationSecurity = secAutomation


Alla prossima! :)

venerdì 3 ottobre 2014

VBA-Excel: Come reperire l'ultima riga/colonna di un foglio che contiene dati

A chi programma in VBA per Excel capita di aver bisogno di sapere qual'è l'ultima riga e/o l'ultima colonna di un foglio contenente dati, magari per fare un ciclo di lettura delle celle.
Spesso si usano accrocchi vari per reperire questa informazione che simulano l'esecuzione manuale come per esempio la pressione dei tasti Fine e Freccia giù, oppure improbabili cicli che leggono le celle una dopo l'altra fino a trovarne una vuota. A parte i tempi lunghi di questo approccio resta il problema che alla prima cella vuota trovata ci si ferma dando per assunto che quella sia la fine dei dati, cosa che non è sempre vera.
Il metodo migliore è di gran lunga più semplice e veloce nonché più sicuro di quelli sopracitati.
VBA per Excel offre una proprietà dell'oggetto Worksheet che è molto utile in questo caso e cioè: UsedRange. Tale proprietà restituisce un oggetto di tipo Range che compre l'intera area di celle utilizzata nel Worksheet a cui è associato.
Pertanto per sapere quali sono l'ultima riga e l'ultima colonna usati è sufficiente fare:

Dim UltimaRiga as Long
Dim UltimaColonna as Long

UltimaRiga = Thisworkbook.Worksheets("MioFoglio").UsedRange.Rows.Count
UltimaColonna = Thisworkbook.Worksheets("MioFoglio").UsedRange.Columns.Count

Facile e veloce! :-D