Il VBA e la gestione delle date Abbiamo già detto che in Excel esistono due modi per poter lavorare : inserendo formule e funzioni direttamente nelle celle del foglio di lavoro, oppure attraverso l'inserimento di opportune istruzioni sfruttando il codice, il VBA, usando l'Editor di Visual Basic. Parlando di date, è necessario vedere le differenze tra i due modi di operare. Premesso che Excel pone come inizio calendario la data del 01/01/1900, e che vede una data inserita in una cella come UN NUMERO che rappresenta la differenza DEI GIORNI tra la data immessa e l'inizio calendario, parlando di gestione date, è necessario capire che esistono due modi di interpretazione delle date in Excel:
In questa sezione ci occuperemo delle date viste dal VBA, va precisato comunque che in programmazione, la conversione tra i due sistemi non impegna il programmatore: se si inserisce tramite una textbox (in una UserForm) una variabile di tipo "Date" nella cella del foglio di lavoro, la data che ivi apparirà sarà quella giusta. Per memorizzare una data o un orario, e necessario definire una variabile di tipo Date e ricorrere per assegnare un valore alla variabile, ad una sintassi particolare che prevede di inserire la data tra due caratteri "cancelletto" (#): per esempio, il 10 agosto 2002, può essere scritto:Private Sub
CommandButton1_Click()
Come si può notare il formato prevede l'inserimento della data alla maniera inglese, invertito rispetto alla maniera italiana, cioè Mese/Giorno/Anno, questo perchè, lo ripeto, le istruzioni in codice vba devono essere compilate in inglese. Ci penserà lo stesso VisualBasic a convertire immediatamente nel formato standard, per cui nella TextBox1 noi vedremmo la data scritta all'italiana : 10/08/2002 e lo stesso nella cella A1 del foglio di lavoro. (la visualizzazione del formato data con anno a 4 cifre, dipende dalle impostazioni di settaggio contenute in "Pannello di Controllo/Impostazioni Internazionali/Data, voce:"Formato data breve": se è impostato gg/MM/aa tutte le visualizzazioni delle date saranno con l'anno a due cifre (le ultime due), se impostato gg/MM/aaaa invece l'anno sarà visualizzato a quattro cifre. Questo come visualizzazione standard in tutti i programmi; le celle di un foglio di Excel consentono di scegliere il formato data voluto, indipendentemente dalle impostazioni di sistema. Gli ultimi S.O. sono normalmente settati con anno a quattro cifre). Vorrei richiamare l'attenzione su un particolare: nell'esempio sopra, la parola "Date" è stata usata per definire il tipo di variabile (Dim Mydate è una Data), ma la parola "Date" è anche una Funzione e un'istruzione, e può essere usata per definire la data di sistema (data del giorno in cui si lavora). Vediamo l'esempio sopra modificato in questo senso: Private Sub
CommandButton1_Click()
E nella textbox1 e in A1 vedremmo la data del giorno nel formato italiano. Questa istruzione ci consente di evitare di scrivere la data in tutte le occasioni in cui la registrazione di una data corrisponde alla data del giorno. (nel vba l'istruzione Date equivale alla Funzione =OGGI() inserita in una cella del foglio di lavoro). Ritornando al primo esempio (usato per definire la sintassi del formato data), notiamo che l'istruzione non ci consente di gestire liberamente l'inserimento di una data, in quanto la data è fissata via codice; (questo andrebbe bene se dovessimo inserire sempre una stessa data, e avremmo potuto fare a meno della textbox1, bastava infatti scrivere : WorkSheets(1).Range("A1") = Mydate ), come fare allora per far capire che stiamo inserendo una data e al tempo stesso usare la textbox per inserire date a nostro piacere? Possiamo usare usare due metodi : il primo sarà quello di assegnare una variabile di tipo Date alla textbox interessata, il secondo di impostare la formattazione della textbox in "formato data (Format)" prima della scrittura sul foglio di lavoro. Vediamo i due metodi: primo metodo: Private Sub
CommandButton1_Click()
Con l'istruzione sopra otterremo il riconoscimento da parte di Excel della data come tale, e verrà rispettato anche l'eventuale formato cella preimpostato: abbiamo scelto per A1 il formato cella : categoria Data, e come tipo : Data 14 marzo 2001 (cioè con la data scritta col nome del mese e l'anno a 4 cifre), avremmo questo risultato anche se nella textbox abbiamo scritto la data usando il formato classico: Non solo, ma l'istruzione precedente passa la data (immessa nella textbox1) ad Excel COME DATA, ed Excel l'avrebbe riconosciuta come tale, anche se avessimo lasciato la cella A1 con il formato cella impostato a "Generale", che è il Formato cella di default di tutte le celle. Sarebbe solo stata scritta con il formato data tradizionale, cioè 15/10/02, MA, sottolineo, come DATA, e non come diversamente potrebbe avvenire, come TESTO; visivamente avremmo visto lo stesso in A1 scritto 15/10/02, ma a sinistra nella cella (come un testo) e cosa più importante, sarebbero sorti problemi se avessimo utilizzato il dato contenuto in A1 per conteggi su date. Definirei l'istruzione sopra, come l'istruzione TIPO da usare quando si usino textbox per trasferire DATE al foglio di lavoro. Se poi vorremo un tipo di Formato data personalizzato, lo IMPOSTEREMO non via codice (Format), ma come Formato cella. Nel caso si avesse più di una textbox dove si immettono date e si userà un unico comando per trasferire le date sul foglio di lavoro, sarà sufficiente dimensionare la variabile una volta sola (Dim), assegnandogli più variabili (X,Y,Z), ,una per ogni textbox usata. Vediamo un esempio: Private Sub
CommandButton1_Click()
secondo metodo:
gli esempi : Private Sub
CommandButton1_Click() va bene anche : Private Sub
CommandButton1_Click() Con le due istruzioni sotto, se si dichiara una variabile (X) come Date e gli si assegna un Formato, il Formato NON viene considerato e passa solo il formato Date della variabile che è quello classico 12/03/02, a meno che non si sia predisposto il Formato cella diversamente. Private Sub
CommandButton1_Click() oppure Private Sub
CommandButton1_Click() Dal momento che si comincia a fare confusione, e non credo per colpa mia, ho riassunto nella tabella sotto i risultati che si ottengo usando sia l'istruzione che ho definito TIPO (con dimensionamento come Date), sia l'istruzione Format (senza dimensionamento come Date) e proveremo a trarre delle conclusioni. Nella colonna A ci sono i risultati delle date scritte nella textbox1, sempre scritti col formato classico: 12/02/02 ecc., nella colonna B, se è stata usata la Variabile Date o la formattazione e di che tipo, nella colonna C si trova il "formato cella" impostato in A, e nella colonna D , dove è stato impostato il formato cella a Data, il tipo di formato data. Nella colonna A le date riconosciute da excel come data, sono scritte a destra nella cella, le altre scritte sulla sinistra, vengono impostate come TESTO (senza triangolino verde in alto a sinistra nella cella) e dove appare il triangolino, Excel rileva che è necessaria una precisazione: confermare un formato data, considerarlo errore, ignorare e lo considera testo. La colonna C, dove si legge "generale > data", vuol dire che il formato cella, prima dell'inserimento della data, era impostato a "generale", dopo l'inserimento viene aggiornato da excel il formato cella in "data" e quindi si desume che la formattazione via codice è stata riconosciuta giusta. Non mi sono dilungato a proporre tutti i formati, per non diventare scemo. Chi vuole si farà tutte le prove che vorrà. Questa è una panoramica su uno degli aspetti di Excel che giudico molto confusionari, ma tant'è. Rimane ancora una cosa da vedere : fino ad ora abbiamo visto come impostare il codice per il trasferimento di una data dalla textbox al foglio di lavoro, ma cosa dobbiamo fare se vogliamo che anche la data inserita nella textbox assuma il formato voluto? Dovremo usare l'istruzione Format inserita in un evento della textbox. Non è possibile ottenere una formattazione durante la digitazione, e gli unici eventi utilizzabili sono l'evento AfterUpdate oppure l'evento Exit (simile a LostFocus del Vb). Ecco due esempi: Private
Sub TextBox1_AfterUpdate() Private
Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean) Entrambi gli eventi si verificano quando si toglie il focus dalla textbox1: o spostandoci su un'altra textbox, oppure nell'istante in cui si preme sul commandbutton. ATTENZIONE!! Questo tipo di formattazione serve solo per la visualizzazione della data nella textbox, per cui NON bisogna usare il sistema inglese (Mese/Giorno/Anno), ma il nostro sistema (Giorno/Mese/Anno). Esiste un altro evento che potremo però utilizzare SOLO se usiamo una textbox per mostrarci delle date presenti in una cella : è l'evento Change della textbox, quindi useremo un'istruzione per caricare la textbox con il contenuto della cella A1, usando l'evento Activate della UserForm, Private
Sub UserForm_Activate() e nell'evento Change della textbox1 metteremo l'istruzione per visualizzare la data nel formato che avremo scelto e che può essere diverso dal formato data presente in A1: Private
Sub TextBox1_Change() Volendo evitare di scrivere due istruzioni, potremo saltare l'evento Change e usare la formattazione nell'evento Activate dell'UserForm, così: Private
Sub UserForm_Activate() ComboBox e le date Ancora una precisazione: Quando si lavora usando delle ComboBox prese da "Strumenti di Controllo" (o casella degli strumenti), essendo oggetti che fanno parte delle ActiveX e quindi tipici del VisualBasic piuttosto che di Excel, è necessario provvedere alla "formattazione" dei dati che ricevono dal foglio di lavoro. Trattando di date, una ComboBox il cui ListFillRange va a "pescare" dati in una colonna di date, mostrerà nel menù a tendina, le date così come sono scritte nelle celle del foglio di lavoro, MA, nel momento in cui selezioniamo una di queste date per averla nella cella collegata (LinkedCell), le date presenti nel menù si trasformano in numeri : sono i numeri seriali con i quali excel "vede" le date, anche se sul foglio noi vediamo le date scritte con il giusto formato, e come tali le passa alla combobox. Per ovviare a questo comportamento, sono necessarie delle istruzioni che consentano il mantenimento del formato data scelto nelle celle, e, evitando di collegare la proprietà LinkedCell della combobox a nessuna cella, usare a suo posto una riga di istruzione. Nell'esempio sotto vediamo il costrutto : sfruttiamo l'evento Change della combobox in modo che ad ogni selezione di una data presente nel menù della stessa, si attivi l'esecuzione del codice: prima impostiamo la formattazione della data nel formato 5-feb-02 (d-mmm-yy)(scritto col formato italiano ma usando i termini inglesi), poi dichiariamo la variabile mydate di tipo Date, poi assegniamo la variabile alla combobox, indi gli diciamo quale cella del foglio di lavoro dovrà essere collegata (LinkedCell) al dato selezionato nella combobox. Le celle del foglio di lavoro interessate alle date dovranno avere il formato cella impostato uguale al formato scelto per formattare la combobox (personalizzato : g-mmm-aa)(sul foglio di lavoro i termini sono solo in italiano) : Private
Sub ComboBox1_Change() Per la trattazione degli orari, è previsto un nuovo paragrafo che seguirà questo. Buon appetito, gente!
|