Agenda Gestione Appuntamenti con Access

Se volete creare un agenda per gestire gli appuntamenti con Microsoft Access ma non sapete da dove iniziare questo progetto è quello che fa per voi!

Ci sono 2 aspetti principali da considerare: il primo è l'interfaccia grafica, la quale dovrebbe emulare il più fedelmente possibile agende e calendari reali, strumenti cartacei ai quali magari eravamo un tempo abituati, il secondo aspetto è quello relativo all'implementazione di tutte le necessarie routine di codice VBA. Questo progetto si occupa di entrambi gli aspetti.

La soluzione che abbiamo scelto per questo progetto prevede un'unica maschera di dimensioni abbastanza grandi da contenere il plannining settimale completo con le tipiche 7 colonne per ciascun giorno e con lo spazio per inserire annotazioni tra le ore 8.00 e le ore 22.00. La maschera visibile in figura, si chiama PlanningSettimanale. (figura1).

Nella stessa maschera abbiamo tuttavia inserito anche un controllo struttura a schede (tabstrip) composto di 2 schede, sulla prima di esse (Settimana) sono stati inseriti tutti i controlli che costituiscono il planning settimanale e che avete visto nella fgura precedente.

Nella seconda scheda, Mese, abbiamo inserito un calendario mobile perpetuo per poter selezionare qualsiasi altra settimana differente da quella corrente. Basta infatti fare clic sul qualsiasi giorno e la prima scheda si ridisporrà in modo da visualizzare la settimana nella quel cade il giorno selezionato, anche se si trova in un mese o addirittura in un anno differente.

Inizialmente il planning settimanale si riferisce sempre alla settiaman che comprende il giorno corrente, secondo l'orologio di sistema di windows. Nella parte superiore della seconda scheda ci sono 2 caselle combinate per selezionare rispettivamente mese e anno differenti. Nella routine evento dopo aggiornamento di entrambi i controlli viene richiamata la routine che aggiorna il calendario, con l'indicazione in rosso dei sabati e delle domeniche.

La data di oggi viene evidenziata con lo sfondo colorato in celeste, come in figura. (figura2).

Passiamo ora ad esaminare la struttra della maschera e in particolare il modo in cui i relativi controlli recuperano i dati dalle tabelle di access. Della struttura delle 2 tabelle ci occuperemo tra pochissimo. Nella prima delle 2 schede del controllo struttura a schede, Settimana, abbiamo inserito 7 controlli sotto-maschera, di nome MemoOrario1, MemoOrario2 e così via fino a MemoOrario7.

Immediatamente sopra ad ognuno dei 7 controlli sotto-maschera c'è un controllo etichetta per visualizzare la data cui si riferiscono i memo orari rappresentati in ognuna delle 7 sottomaschere.

Ciascuna sottomaschera è in formato maschere continue ed è dotata di 2 soli controlli, un controllo etichetta per visualizzare l'ora nel formato HH:MM ad intervalli di mezz'ora dalle 8 alle 22 ed un secondo controllo, casella di testo, per visualizzare la parte iniziale di un controllo memo la cui funzione è quella di poter inserire le annotazioni relative a quell'ora, per esempio un appuntamento, una telefonata da fare, un azione da compiere, ecc. (figura3).

La proprietà Origine record di ciascuna sottomaschera è impostata su una query che estrai i memo orari da una unica tabella: MemoOrario. Per esempio la proprietà Origine record della prima sottomaschera, che mostrerà sempre gli appuntamenti del lunedì, è:

SELECT MemoOrario.* FROM MemoOrario WHERE (((MemoOrario.Giorno)=1));

Prima di esaminare la strutture delle 2 tabelle, diamo ancora un occhiata alla struttura dei controlli presenti nella seconda scheda del controllo struttura a schede: Mese.

Qui, oltre ai 2 controlli casella combinata per la selezione del mese e dell'anno, di cui abbiamo già parlato, ci sono 49 controllo etichetta, i primi 7 dei quali sono colorati con sfondo azzurro e colore del font bianco: si tratta delle iniziali dei 7 giorni della settimana: L, M,M,G,V,S e D.

Le restanti 42 etichette sono bordate di azzurro e sono di dimensioni più grandi. In ognuna di esse verrà inserita la data del giorno, allineata al centro. Il nome assegnato ai 42 controlli etichetta è C1, C2, ecc. fino a C42 in modo che da codice si possa trattarle come un array di controlli mediante l'istruzione vba seguente (i è una variabile integer):

Me.Controls("C" + CStr(i)).Caption (figura4).

Per capire dove sono memorizzati i memo orari e come vengono assegnati ai controlli delle 7 sottomashere, occore esaminare la tabella MemoOrario, visibile nella parte sinistra delle figura seguente. La tabella MemoOrario contiene 203 record fissi, 29 per ogni giorno moltiplicato 7 fa 203. Il contenuto dei primi 3 campi resta in effetti costante, mentre viene modificato soltanto il contenuto del quarto campo, Note, che è un campo memo.

Per fare in modo che il planning settimanale visualizzi gli appuntamenti di una settimana differente occorre tuttavia una seconda tabella, ArchivioMemo, dotata di un campo Data, che vedremo tra un attimo.

Nella parte destra della figura è visibile la struttura della prima sottomaschera, MemoOrario1. Ricordiamo che l'origine record è impostata su una query che di fatto estrae solo le prime 29 righe della tabella MemoOrario, quelle il cui valore Giorno è pari a 1, cioè lunedì. La seconda sottomaschera estrarrà e visualizzerà le righe relative al giorno 2, martedì e così via fino a domenica. (figura5).

La tabella ArchivioMemo contiene 4 campi, un ID, un campo DataMemo, un campo OraMemo e un campo Note (tipo Memo). Gli ultimi 2 campi hanno le stesse caratteristiche di quelli della tabella MemoOrario. In questa tabella vengono di fatto memorizzati tutti gli appuntamenti o le azioni da compiere relative alla nostra agenda, indipendentemente dalla settimana alla quale si riferiscono, infatti ad ognuno di essi è assegnata una data specifica, oltre all'ora.

Quindi in sostanza, ci servono 2 efficienti routine VBA che fanno tutto il lavoro: la prima all'apertura del form, con il compito di recuperare tutti i memo che contengono gli appuntamenti o le annotazioni relative alla settimana corrente, in base al campo DataMemo della tabella ArchivioMemo, e la seconda, sulla chiusura del form (PlanningSettimanale), con il compito inverso, cioè quello di salvare nella tabella ArchivioMemo gli eventuali nuovi appuntamenti o azioni inserite nei controlli.

In pratica la prima routine legge i dati dalla tabella ArchivioMemo e li scrive nella tabella MemoOrario (il cui campo memo Note viene azzerato ogni volta), la tabella MemoOrario alimenta i controlli delle 7 sottomaschere. La seconda routine invece legge i dati della tabella MemoOrario e li scrive, se non già presenti, nella tabella ArchivioMemo. In questo modo non si perderà mai nessun dato. (figura6).

Ora che abbiamo capito il modo in cui funziona la nostra agenda gestione appuntamenti, passiamo all'esame delle principali routine VBA, partendo dalla routine su apertura del form PlanningSettimanale, mostrata in figura. (figura7).

Siccome il planning deve riferirsi sempre e comunque ad una data settimana, la prima volta che l'utente apre la maschera, si troverà sempre la settimana corrente, già ma come recuperare la data del lunedì relativo alla settimana corrente, specialmente nel caso che questa capiti a cavallo di 2 mesi differenti?

Semplice, tramite la funzione FirstDayInWeek:

Function FirstDayInWeek(dt As Date)

FirstDayInWeek = dt - Weekday(dt, vbUseSystemDayOfWeek) + 1

End Function

Anche se non è specificato, la funzione ritorna sempre un valore data completo, sottraendo semplicemente dalla data passata come argomento, dt, che può essere oggi oppure qualunque altra data, un numero di giorni pari all'intero che rappresenta il giorno della settimana di dt +1

Facciamo un esempio concreto: Se dt vale 1 agosto 2015, l'espressione varrà:

1/08/2015 - 6 + 1 = 27/07/2015

Perché il 1 agosto è sabato (6), quindi il valore di ritorno rappresenta il lunedì precedente: 27/7/2015.

Nella routine su apertura abbiamo visto che il valore di Dt è pari Today, cioè al giorno corrente secondo l'orologio di sistema di windows (la funzone Date() ritorna sempre la data corrente).

A questo punto vengono eseguite le routine AggiornaMemoSettimanaCorrente e AggiornaSettimanaCorrente. La prima, che vedremo in seguito, elabora i recordset di ArchivioMemo e MemoOrario nel modo che abbiamo già spiegato, cioè recupera gli appuntamenti dall'archivio storico e li passa alla tabella temporanea e quindi ai controlli del planning.

Vediamo invece ora un po’ più da vicino il contenuto della seconda routine: AggiornaSettimanaCorrente, per capire il modo in cui vengono impostate le caption dei 7 controlli etichetta relativi ai 7 giorni della settimana corrente. (figura8).

La prima istruzione è in realtà superflua ma potrebbe rivelarsi utile qualora questa routine venga richiamata anche da un'altra parte dell'applicazione, magari quando l'utente ha selezionato un giorno differente dal calendario che si trova nella seconda scheda del controllo struttura a schede.

DtFirst rappresenta quindi sempre la data relativa al primo lunedì della settimana corrente, mentre dtSelected è il giorno selezionato dall'utente oppure è la data di oggi.

intG è il giorno della settimana di dtSelected (1-7), Gsett è la descrizione del nome del giorno della settimana relativo a dtSelected.

Ora che sappiamo qual è la data del lunedì relativo alla settimana corrente (dtFirst), assegnare i nomi e le date alle proprietà caption dei 7 label il cui sfondo è colorato in blu, è un gioco da ragazzi:

Per esempio il settimo controllo (Domenica) sarà:

lbDomenica.Caption = "Domenica " & CStr(Day(dtFirst + 6))

Vediamo ora la routine AggiornaMemoSettimanaCorrente, che in realtà viene eseguita prima della precedente In figura è mostrato il listato. (figura9).

La routine impiega 2 oggetti DAO.Recordet, il primo per aprire in sola lettura la tabella ArchivioMemo e il secondo per aprire invece in scrittura la tabella MemoOrario.

Per velocizzare l'elaborazione, il primo recordset non apre tutti i record di ArchivioMemo ma solo quelli relativi alla settimana corrente. Infatti l'argomento Name del primo OpenRecordset è impostato sul seguente enunciato SQL:

SELECT * FROM ArchivioMemo WHERE DataMemo BetWeen #" & ReverseDate(dtFirst) & "# AND #" & ReverseDate(dtFirst + 6) & "#", dbOpenSnapshot)

In questo modo si evita di ciclare tutti gli appuntamenti anche se lontani nel tempo, ad ogni apertura della maschera o ad ogni selezione di un determinato giorno nel calendario da parte dell'utente (questa routine è richiamata anche dal clic sul calendario)

La parte restante della routine si preoccupa di impostare su Null i campi Memo della tabella MemoOrario se non ci sono memo per la settimana corrente (Rs1.EOF = True), se invece ce ne sono, li cicla e li assegna alla tabella MemoOrario in base al numero del giorno della settimana ricavato per mezzo dell'espressione:

intG = Weekday(Rs1("DataMemo"), vbMonday)

Per sicurezza viene anche controllato con un FindFirst se per caso i memo erano già al loro posto.

Al termine tutti gli appuntamenti della settimana corrente vengono recuperati e mostrati nei controlli dei 7 subform del planning settimanale.

Quando l'utente chiude il form, quindi esce dall'applicazione, occorre compiere il processo inverso, dato che nel frattempo avrà inserito o eliminato diversi appuntamenti.

Nella figura successiva sono mostrate sia la routine su scaricamento (Form_Unload) del form PlanningSettimanale, sia il listato della sub-routine AggiornaArchivioMemo, che si trova in un modulo generale.

La prima parte della routine è identica a quella della routine precedente, con l'unica differenza che ora il recordset Rs1 (ArchivioMemo) è un dynaset (scrittura), mentre Rs2 (MemoOrario) è uno snapshot (sola lettura). (figura10).

Al solito venfono ciclati entrambi i recordse e verificato per mezzo di FindFirst se per caso esistono già i record da scrivere prima di farlo effettivamente. Di particolare rilevanza è l'istruzione che consente di ricavare un valore data completa a partire dalle informazioni presenti nella tabella MemoOrario, che non contiene invece valori data:

dtTemp = DateSerial(Year(dtFirst), Month(dtFirst), Day(dtFirst) + intG - 1)

dtTemp è una variabile Data che servirà al metodo FindFirst nella riga successiva, DateSerial è una funzione di sistema del VBA che consente di ricavare un valore Data a partire dai singoli elementi integer che la compongno e cioè l'anno, il mese e il giorno).

IntG vale Rs2("Giorno") che è disponibile nella tabella MemoOrario, mentre gli altri 2 parametri vengono ricavati per mezzo delle funzioni Year() e Month() sulla data del lunedì della settimana corrente, cioè dtFirst.

Al termine tutte le variazioni effettuate dall'utente agli appuntamenti della settimana corrente, comprese le eliminazioni, vengono anche aggiornate sull'archivio storico, cioè su ArchivioMemo.

Vediamo ora come funziona l'inserimento di un singolo promemoria in corrispondenza di un dato giorno e di un dato orario (a intervalli di mezzora). Ricordiamo che le sottomaschere sono in modalità a maschere continue, quindi ogni riga corrisponde ad un record differente di tabella MemoOrario.

Quando l'utente fa clic su di una qualsiasi casella di testo (collegata al campo Note, che è di tipo Memo) si apre una ulteriore finestra di dialogo: il form MemoZoom. (figura11).

Il form MemoZoom è una maschera di Access dotata di alcune property Let per passare i dati del giorno e dell'ora alla caption della mascherina e per scrivere nel campo Note. Inoltre serve anche per passar al controllo casella di testo del form MemoZoom il contenuto del campo Note relativo alla casella di testo cliccata.

La proprietà 'Funzione Tasto Invio' del controllo (scheda Altro delle Proprietà) è impostata su 'Nuova riga del campo' anziché su quella predefinita. In questo modo è possibile andare a capo all'interno del memo anziché spostare il focus su un altro controllo quando si preme il tasto Invio.

Se l'utente fa clic su Chiudi o se preme Esc sulla tastiera, il form MemoZoom si chiude e il contenuto del memo viene salvato nel campo Note in corrispondenza del giorno e dell'orario selezionato prima dell'apertura, in tabella MemoOrario. (figura12).

Nella routine evento su Clic del controllo casella di testo Note nella sottomaschera MemOrario1 c'è il richiamo ad una routine esterna che sta nel Modulo1. La routine prevede 2 argomenti: un riferimento all'oggetto sottomaschera (inteso come oggetto form) e un riferimento alla casella di testo Note su cui si è fatto Clic.

Private Sub Testo2_Click()

Call ApriMemo(Me, Testo2)

End Sub

Nella figura seguente vediamo il listanto della sub-routine ApriMemo e al contempo la routine su clic di cui abbiamo appena parlato. (figura13).

Lo scopo di questa routine è quello di preparare tutte le variabili da passare a MemoZoom tramite le Property Let, che sono 5:

f.Giorno = strGiorno

f.ng = intGG

f.Mese = strMese

f.Ora = strOra

f.boolOK = True

La prima è la descrizione del giorno della settimana ('lunedì', 'martedì', ecc.), la seconda è il numero del giorno (1,2,ecc.), la terza è la descrizione del mese (Gennaio, Febbraio, ecc.), la quarta è l'ora e la quinta è un flag logico che serve per non eseguire alcune istruzioni nella routine su apertura di MemoZoom quando la si apre la prima volta in modalità PropertySetting.

La descrizione del mese vene ricavata per mezzo della riga di codice seguente:

MonthName(Month(dtFirst + TB.Parent.Giorno - 1), False)

TB è il riferimento alla casella di testo Note del form MemoOrario1 su cui è stato fatto clic. La proprietà Parent fa riferimento al form stesso, quindi si accede all'indice del giorno corrente (1 = lunedì, 2 = martedì', ecc.) che sommato a dtFirst (data del primo lunedì) -1 ritorna la data del giorno corrente. Month ritorna il numero del mese (1,2,acc) e MonthName ritorna la relativa descrizione (Gennaio, Febbraio, ecc.)

Notate come il form MemoZoom venga aperto una prima volta in modalità acFormPropertySetting e una seconda volta in modalità acNormal

Passiamo ora alla soluzione di un altro problema tecnico: ricordate il modo in cui avevamo assegnato un nome ai controlli etichetta nella sottoscheda Mese del controllo struttura a schede? Parliamo del calendario. Avevamo assegnato c1, c2, fino a c42 come nomi in modo da poterli ciclare come fossero un vettore di controlli. Questo semplifica il lavoro della routine AggiornaCalendario, che vedremo tra poco, ma non risolve il problema della duplicazione del codice da inserire nelle 42 routine evento su clic dei rispettivi controlli etichetta.

Per evitare di dover scrivere 42 routine tutte uguali abbiamo costruito una function di nome DaySelected() dotata di un argomento integer corrispondente al numero della casella (da 1 a 42).

La routine deve essere richiamata inserendo un segno di uguale davanti come mostrato in figura. Per esempio nel caso della prima etichetta: Su clic = DaySelected(1)), per la successiva sarà su clic = DaySelected(2) e così via fino al 42. (figura14).

Nella figura seguente è visibile il listato della routine DaySelected. L'argomento G è il numero della etichetta (da 1 a 42). Per prima cosa viene controllato che l'utente abbia fatto clic su una casella che contiene un valore, altrimenti esce.

Successivamente vengono letti i parametri relativi al mese e all'anno selezionati sui 2 controlli casella combinata in alto, quindi viene costruita la data relativa al giorno selezionato mediante la funzione DateSerial, già vista in precedenza.

Le ultime 2 righe portano il focus sulla scheda Settimana (Planning) e sulla sottomaschera relativo al giorno della settimana di riferimento (ng = Weekday(dtSelected,vbMonday)). Il parametro vbMonday serve per dire al Visual Basic che intendiamo che la settimana inizi di lunedì e non di domenica come nei paesi anglosassoni. (figura15).

Vediamo ora a runtime cosa succede quando l'utente cambia mese e o anno agendo sui rispettivi controlli casella combinata nella scheda Mese. Sul clic di entrambi i controlli scatta la chiamata alla routine GeneraCalendario che ora andiamo ad esaminare in dettaglio. (figura16).

Per prima cosa vengono azzerate tutte e 42 le etichette (proprietà caption = stringa nulla) ed inoltre viene riportato a colore bianco il colore di sfondo e a colore nero il colore del font (per azzerara attributi grafici dell'eventuale giorno corrente, dei sabati e delle domeniche). A questo pensa la routine AzzeraCalendario.

Successivamente viene determinato il valore dell'ultimo giorno del mese corrente:

UltGG = Day(DateSerial(Anno, Mese + 1, 1) - 1)

In pratica viene dapprima determinata la data del primo giorno del mese successivo quindi viene sottratto 1 giorno da quella data. Se siamo in febbraio, ULTGG varrà 28 ( a meno di non essere in un anno bisestile).

Il numero indice della cella della prima riga di etichette dalla quale fare iniziare il conteggio dei giorni del mese corrente viene ricavata semplicemente per mezzo della funzione WeekDay:

C = Weekday(DateSerial(Anno, Mese, 1), vbMonday)

utilizzando come primo argomento la data del primo giorno del mese, quindi per esempio nel caso del mese di luglio 2015, essendo il 1 luglio un mercoledì, la prima cella sarà la terza. Il resto del listato, visibile in figura, è di semplice comprensione. (figura17).

In pratica vengono ciclate tutte le date del mese selezionato, impostata la proprietà Caption di ciascun controllo etichetta sul numero corrispondente al giorno, verificato se si tratta di sabato, domenica o giorno feriale o del giorno corrente, applicando in tali casi i valori appropriati alle proprietà ForeColor e BackColor dei relativi controlli etichetta.

Il ciclo termina esattamente alla casella il cui indice è pari all'espressione (ULTGG+C-1)

Passiamo ora all'ultima funzionalità del progetto: l'utilizzo della proprietà evento su timer della maschera principale PlanningSettimanale per fare in modo che venga riprodotto un file wav (segnale acustico) e venga aperto automaticamente il promemoria (MemoZoom) quando la data e l'ora di sistema sono superiori all'ora (o mezz'ora) del promemoria e per tutti i 15 minuti successivi ad intervalli di 5 secondi. La proprietà Intervallo Timer della maschera è impostato infatti su 5000.

Nella routine vengono utilizzati 2 oggetti DAO.Recordset: il primo cicla continuamente tutti i promemoria della sottomaschera relativa al giorno della settimana relativo alla data corrente (se oggi è mercoledì sarà la terza sottomaschera, e così via)

Il primo recordset è impostato sul metodo RecordSetClone della sottomaschera, in modo da non provocare spostamenti di focus nei relativi controlli. Il secondo invece è un oggetto recordset che punta realmente sul record che contiene il promemoria da visualizzare e poi esce (questo serve per portare effettivamente il focus sul promemoria scaduto, indipendentemente da quello che sta facendo l'utente in quel momento).

Se la data è quella corrente e l'ora di sistema è uguale o superiore a quella del promemoria + 15 minuti, allora scatta l'esecuzione dell'avviso sonoro (file wav con il suono di un orologio a cu-cu) che dura un paio di secondi, quindi viene portato il focus direttamente sul record interessato tramite la proprietà bookmark (ricordiamo che la sottomaschera è in modalità maschere continue, quindi occore posizionarsi su un record specifico).

Dopo l'esecuzione dell'avviso acustico e la visualizzazione del promemoria (Call ApriMemo), viene resa visibile una casella di controllo per consentire all'utente di sospendere la riproduzione dell'avviso, che altrimenti avverrebbe ripetutamente ad intervalli di 5 secondi per 15 minuti! In questo caso chkStopTimer varrà -1 e alla successiva esecuzione della routine l'avviso non viene mostrato. (figura18).

Nella figura seguente è visibile a titolo di esempio lo scattare del promemoria quando sono effettivamente le 8.00 di Lunedì 20 Luglio. Il file wav è pure eseguito in sottofondo. Il promemoria può essere richiuso premendo il tasto esc o facendo clic su chiudi ma se non si stoppa il timer l'avviso viene ripetuto ogni 5 secondi per 15 minuti anche se l'utente si trova su un altro giorno de planning settimanale.

Dopo la prima chiusura del promemoria, apparirà la casella di controllo Ferma il Timer nella parte superiore della maschera. (figura19).

Naturalmente il progetto può essere ampliato e migliorato notevolmente. Il nostr scopo infatti era soltanto quello di fornirvi una traccia di partenza per sviluppare il vostro proprio progetto di agenda appuntamenti con access.

Ecco a titolo di esempio alcuni possibili miglioramenti e funzionalità ulteriori:

1. Inserire una tabella con l'indicazione dei giorni festivi per completare la parte relativa al calendario.

2. Inserire la possibilità di importare / esportare i promemoria dalla tabella ArchvioMemo ad Excel e viceversa

3. Aggiungere le categorie o tipologie di promemoria (esempio: appuntamenti, telefonate, invio mail ecc..)

4. Aggiungere informazioni ulteriori al calendario (esempio: fasi lunari, santo del giorno, ecc. ecc.)

5. varie ed eventuali (a seconda della vostra fantasia…..)



Avvertenza !

Il file dell'esempio Agenda Gestione Appuntamenti con Access contenente tabelle, query, macro, maschere e il codice VBA di cui si è discusso in questo tutorial è disponibile nell'area 'Videotutorial Download' riservata agli iscritti ai nostri corsi on line.

Nella colonna di destra puoi vedere una anteprima della 'Videotutorial Download area' e quanti e quali altri progetti Access, Excel, VBA sono disponibili.

Acquista anche uno solo dei nostri corsi per avere immediatamente accesso alla 'Videotutorial Download Area': è facile, basta un clic:

http://www.mc2.it






Tutorials su Microsoft Access


Home page MC2 E-Learning



Dr.Maurizio Cucchiara

Amministratore unico
MC2 E-Learning S.a r.l.
Formazione per il Web
autore del corso:
"Corso Base di Microsoft Access"
disponibile on line su questo sito
http://www.mc2.it/html/access.html

Condividi sui social network:

Social buttons



Iscriviti al nostro
nuovissimo
canale Youtube!


Iscrivi al nostro canale Youtube



Potrai restare aggiornato
sui nostri più recenti
video-tutorial su:
Microsoft Access ed Excel
e molto altro...



Cerca sul web con Google:




Guarda i video-tutorial
sul nostro canale Youtube:


Agenda Gestione Appuntamenti con Access



NOVITA'!

'VIDEO TUTORIAL
DOWNLOAD AREA'

(Fai clic sull'immagine
qui sotto per vedere
una anteprima della
pagina di accesso)



L'accesso è riservato agli iscritti ai corsi on line www.mc2.it

Acquista anche uno solo
dei nostri corsi
per avere immediatamente
accesso alla
'Videotutorial Download Area': è facile, basta un clic:

http://www.mc2.it



Iscriviti alla newsletter: E' GRATIS! (?)

 Nome: (?)

 (?)

e-mail: (?)

 (?)

Newsletter:

formato preferito:

Microsoft Access (?)

Impariamo Excel e il VBA(?)

Internet "da zero"! (?)

Html (?)

Consiglio

(?) = Aiuto

Leggi qui la Informativa completa sulla privacy.