Il blog di Gianni Giaccaglini

Blog su VBA e VSTO
Gianni Giaccaglini

My Links

News

NB - V. anche gli ARTICOLI (in fondo a questa barra)
Solo quesiti validi a: giannigiac@tin.it
Il mio Best seller su VBA
(v. www.hoepli.it)


Il mio ultimo libro su Open XML
(v. www.FAG.it):



La mia nipotina ELISA

Foto con dedica a ME di
Bill Gates giovanissimo
nei mitici anni 80!

Categorie Post

Categorie Articoli

Archivio

Immagini

Blog Stats

Creare automaticamente il backup di un modello Excel

Creazione automatica del backup di un modello

Mi pervengono le richieste più strane e inattese. L’ultima, espressa nel titolo e esternata da un tal Nonricordo Chisia , è la possibilità di effettuare tramite macro VBA un archivio Excel che sia la copia precedente di quello che di volta in volta viene aperto e, il più delle volte, aggiornato. Si tratta d’una pignoleria? Giudichi ognuno, di fatto l’esigenza nasce laddove è prevista una notevole attività di data entry ad esempio nelle righe di una tabella. La responsabilità dell’utente resta sempre malgrado opportune tecniche di convalida e persino con il rimedio che vado subito a suggerire.

Sia come sia ecco la ricetta, che comunque ritengo curiosa e interessante.

Nota. In quel che segue, per fissare le idee, si supporrà che il file da curare e la sua versione... postuma siano ModelloBase.xlsm e, rispettivamente, ModelloBaseBackup.xlsm. I perfezionisti se hanno voglia e tempo potranno sostituirli con generici parametri.

Primi tentativi, uno problematico l’altro... illusorio

Come sarà subito venuto in mente a molti, incluso il succitato Nonricordo Chisia (ignobile nomignolo che verrà perdonato, spero), si potrebbe ricorrere all’evento Open del modulo ThisWorkbook del nostro ModelloBase. Ne descrivo a parole le operazioni manuali:

  1. Salvare (subito) ModelloBase in ModelloBaseBackup;
  2. Chiudere ModelloBase! (infatti dopo il passo 1 è aperto solo ModelloBaseBackup);
  3. Aprire nuovamente ModelloBase.

Così facendo però se affidiamo tali operazioni all’evento di apertura di ModelloBase, perché il passo 3 implica la ripresa del passo 1, creando un loop infinito (o no?). Chi ne ha voglia può studiare una qualche variabile booleana del tipo switch di primo giro, ma il tutto appare macchinoso, poco chiaro e fonte di rischi più o meno (in)attesi.

Un uccellino (di quelli che frullano nella testa nottetempo o in tram) mi ha allora detto: perché non ricorrere all’istruzione FileCopy? Detto fatto:

Nota. L’ipotesi, direi scontata, è che ModelloBase e ModelloBaseBackup risiedano nella stessa cartella di file.

Private Sub Workbook_Open() ' Evento del file ModelloBase

  ChDir Me.Path ' Fissa la directory di ModelloBase

  FileCopy "ModelloBase.xlsm", "ModelloBaseBackup

End Sub

 

Giusto? Ahimè no, perché Excel rigetta l’istruzione FileCopy applicata a un ModelloBase.xlsm attualmente aperto. L’illusione nacque dall’idea che i file Excel risiedono su RAM. Vero, ma l’applicativo mantiene un contatto con l’archivio su disco (tra l’altro vitale e non virtuale nel caso di swapping con modelli enormi e/o con sovraccarico di RAM per altri motivi).

La ricetta, un ripiego comunque interessante

Prima di cedere le armi, ho infine escogitato il ricorso a un archivio ausiliario, diciamo Menu.xlsm, il cui scopo primario (o addirittura unico) sia quello di lanciare a sua volta ModelloBase.Xlsm. Si può pensare a qualcosa del genere, che suggerisce un Menu relativo a più modelli che a volte fanno parte di un’applicazione:

 

A

B

C

D

1

ModelloBase.xlsm

<= legame ipertestuale

 

 

2

QuestAltroModello

"

 

 

3

QuellAltroModello

"

 

 

4

ecc.

"

 

 

 

Nota. I legami ipertestuali costituiscono una variante rispetto a dei pulsanti di comando di cui non tutti si ricordano.

Insomma Menu.xlsm conterrà nel modulo ThisWorkbook la macro d’apertura seguente:

Private Sub Workbook_Open()

  ChDir Me.Path

  FileCopy "ModelloBase.xlsm", "ModelloBaseBackup.xlsm"

End Sub

L’utente dovrà poi cliccare sul link predetto. Stavolta Excel non protesta, ovviamente a patto che l’utente non abbia già aperto il fatidico ModelloBase (v. più avanti il rimedio a questo caso estremo).

Infine ho supposto che Menu.xlsm sia semplicemente un archivio “di lancio” relativo al ModelloBase, nel qual caso sarà meglio chiamarlo, piuttosto, ModelloBaseLancio.xlsm. esso potrebbe non contenere nulla, tranne il seguente codice nel solito ThisWorkbook:

Function ModelloAperto(NomeWrk As String) As Boolean

  Dim Wrk As Workbook

  ModelloAperto = False

  For Each Wrk In Workbooks

    If Wrk.Name = NomeWrk Then

      ModelloAperto = True

      Exit For

    End If

  Next

End Function

 

Private Sub Workbook_Open()

  Dim ModBase As String, ModBackup As String

  ChDir Me.Path

  ModBase = "ModelloBase.xlsm"

  ModBackup = "ModelloBaseBackup.xlsm"

  Dim Msg As String, Titolo As String

  If Not ModelloAperto("ModelloBase.xlsm") Then

    FileCopy ModBase, ModBackup

    Workbooks.Open ModBase

  Else

    Msg = "Non ho creato il backup " & ModBackup & _

          vbLf & "perché " & ModBase & " era già aperto..."

    Titolo = ModBase & " non va aperto prima di " & Me.Name

    MsgBox Msg, vbCritical, Titolo

  End If

  Application.DisplayAlerts = False

  If MsgBox("Chiudo il Menu?", vbYesNo, "") = vbYes Then Me.Close

End Sub

Commenti? Nisba, li affido all’esegesi fai-da-te del visitatore, cui dico solo che la funzione ModelloAperto esplora tutti gli oggetti dell’insieme Workbooks (cartelle di lavoro aperte) restituendo True se e solo se della combriccola fa parte la cartella di lavoro chiamata “NomeWrk” – che poi sarà la nostra ModelloBase.xlsm come passatale dalla macro Workbook_Open. E spero sia chiaro al proverbiale duo Chicche & Sia (*) il messaggio che uscirebbe se l’incauto utilizzatore aprisse per primo ModelloBase.xlsm.

(*) Di decurtisiana memoria, se ben ricordo.

 

?>

posted on mercoledì 14 aprile 2010 13.53