Fatturazione: emissione, stampa, registrazione fattura emessa. - dal 04/09/04 pagina vista: volte Difficoltà: Media. Le spiegazioni sono adatte a chi ha già abbia almeno letto articoli sui siti che trattino concetti legati a database, uso di ListBox, cicli For Next. Questo esercizio è un programma completo (o quasi). Lo scopo non è solo quello di fornire un file utilizzabile già così come sta, ma di proporre un esempio sufficientemente completo su come realizzare un progetto di lavoro. Chiaramente lo si potrà sviluppare per usi personalizzati, modificando e/o aggiungendo intestazioni di campi, numero dei campi, istruzioni, come ad esempio una maschera di introduzione nuovi articoli (tramite UserForm) sul Foglio "Magazzino", da me non prevista in questo esercizio, come pure applicazione di Filtri nel Foglio "Archivio", che potranno servire per statistiche su fatture emesse a clienti. Molte delle aggiunte possibili sono tranquillamente rintracciabili nei vari articoli presenti sui due siti ennius. La prima cosa da fare è impostare lo schema del progetto, organizzando gli elementi necessari alla realizzazione. Chiaramente un progetto può prevedere sezioni diverse, compresa una gestione totale amministrativa di un'azienda comprendente quindi Cassa, Scadenziari, Registro delle fatture acquisto, Archivio Fornitori, Statistiche, ecc. ecc, compreso quindi una sezione Fatture Emesse. Noi seguiremo solo la parte Fatture emesse. Nel caso del solo progetto Fattura emessa, penseremo quindi a quanti Fogli di lavoro sono di norma necessari:
Ognuno chiamerà i Fogli col nome che più preferisce, anche lasciare i classici nomi Foglio1, Foglio2, ecc. L'importante è non creare confusione quando compilando le istruzioni vba, dovremo identificare esattamente un determinato foglio. Il passo successivo è quello di determinare di quanti "campi" (colonne) abbiamo bisogno per i Fogli "Clienti" e "Magaz", decidendo i nomi che formeranno le "intestazioni di campo" (l'identificativo di cosa quel campo conterrà), e cosa importante, la sequenza con cui predisporre l'ordine dei "campi". E' in funzione di queste decisioni che potremo predispore sia come impostare i campi (celle) sul Foglio "Fattura", sia sul Foglio "Archivio". E' infatti buona norma mantenere lo stesso ordine di sequenza quando andremo a registrare i dati cliente e gli articoli in "Fattura", e altrettanto sarà quando aggiungeremo un nuovo cliente, o archivieremo i dati relativi alla fattura emessa. Sarà infatti possibile usare istruzioni, quando possibile, che usino cicli For Next su "insiemi", per velocizzare l'esecuzione delle istruzioni, e per noi scrivere meno righe di codice. Vediamo sotto due immagini della scelta dei "campi" per il foglio "Clienti", la prima, e del foglio "Magaz" la seconda: in giallo i "campi e loro intestazione"
I nomi sono di fantasia, o puramente casuali. Il numero dei campi è solo indicativo, e potrà essere ampliato in funzione delle proprie esigenze; sarà necessario in questo caso modificare anche il numero di TextBox sulla UserForm usata come maschera di introduzione dati, e relative istruzioni vba, oltre a modificare il numero di campi che ospiteranno ev. aggiunte, sul foglio Fattura. Il Foglio "Fattura"; questo lo possiamo considerare il "cuore" di questo progetto. Vediamo più da vicino le particolarità di alcune celle, che contengono formule o funzioni, che agiranno in funzione dei dati che inseriremo. Per prima la "testa" della fattura: Giusto per lasciare un "pò di lavoro" anche ad Excel e alle sue funzioni, ho inserito nella cella G3 la formula per ottenere la data di emissione fattura che normalmente corrisponde alla data del giorno, quindi =OGGI(). Nella cella A16 ho inserito la formula per ottenere la data di scadenza, che di norma viene sempre spostata alla fine del mese, usando la Funzione =FINE.MESE (ricordo che per poter disporre di alcune Funzioni (compreso appunto FINE.MESE), è necessario che sia spuntata la voce "Strumenti di Analisi" nella finestra che si chiama dal menù Strumenti/Componenti Aggiuntivi). La funzione FINE.MESE richiede due argomenti : la data di partenza (ed è la data di emissione fattura), e il numero di mesi a scadere), quindi per esempio =FINE.MESE(G3;2) per indicare una scadenza a 60 giorni data fattura fine mese. Ora, per indicare la scadenza, si usa la forma testo R.B.60 gg FM, oppure R.D.30 gg FM, ecc., cioè forme usuali commerciali per indicare le condizioni di pagamento. Per ottenere quindi il numero di mesi necessario alla funzione FINE.MESE, sarebbe necessario estrarre il numero di giorni contenuto nel testo condiz.pag, e convertirlo in mesi. Io propongo invece di usare una zona del Foglio dove usare una tabellina di conversione, come questa sotto, assegnarli un "nome" dal menù Inserisci/Nome/Definisci, da usare poi nella formula che vedremo sotto: il nome assegnato è "codpag", e questa la formula inserita nella cella A16: =SE(F16<>"";FINE.MESE(G3;CERCA.VERT(F16;codpag;2;FALSO));"") Sarà quindi possibile modificare o aggiungere condizioni diverse, in modo da averle disponibili nella composizione della fattura. La voce Scadenza, in fattura, voce che verrà poi registrata insieme agli altri dati necessari sul foglio Archivio, ci servirà poi per ottenere statistiche sui totali delle fatture clienti a scadere in una determinata data. Vediamo ora il "corpo" del Foglio Fattura; questa è la zona dove inseriremo gli articoli da fatturare, e di cui ho previsto i campi Codice articolo, descrizione articolo, unità di misura, quantità venduta, prezzo unitario, aliquota iva e parziale. In quest'area, solo nella colonna I, dalla riga 19 alla riga 48, saranno contenute le formule, una per ogni riga, che ci forniranno il parziale ottenuto dalla moltiplicazione della Quantità per il PrezzoUnitario, quindi esempio in I19 = F19*G19 Infine vediamo il "piede" del Foglio Fattura, l'area destinata ai riepiloghi e allo svolgimento dei conteggi. Ho simulato una situazione in cui gli articoli venduti saranno assoggettati ad aliquote Iva diverse;questo comporta che andranno sommati tutti i parziali degli articoli relativi ad ogni aliquota prevista, in modo da calcolarne l'importo iva. Faremo poi una somma dei vari importi iva che sommeremo al totale Imponibile per ottenere il Totale fattura. Vediamo un immagine e poi le formule usate: Ho colorato le celle solo per evidenziare quelle dove inseriamo formule. Nelle celle arancioni sono le formule che utilizzano la funzione SOMMA.SE; facciamo sommare solo gli "importi" dove l'aliquota iva corrisponde ai valori inseriti in formula, quindi in B51, B52, B53 avremo rispettivamente:
Nelle celle gialle avremo una semplice moltiplicazione delle due celle a sinistra, che forniranno l'importo iva, da notare che avendo scritto le aliquote con il segno della percentuale nelle celle A51:A53, non è necessario moliplicare i due valori e poi dividerli per 100, in quanto Excel, leggendo un valore percentuale, provvede già a fare il passaggio, quindi in C51, C52, C53 avremo rispettivamete:
Nella cella B52 (azzurra) inseriremo la funzione =SOMMA(C51:C53) per ottenere il totale importi iva. Nella cella I53 (celeste) avremo il totale fattura dato dalla somma del totale importi (I49) più il totale Iva (B52) Tutti questi calcoli potevamo tranquillamente farli eseguire dal codice vba, attraverso la maschera di composizione fattura, senza scrivere formule in nessuna cella, ma è opportuno prevedere la necessità di comporre la fattura anche manualmente, (senza la maschera, e quindi l'aiuto del codice) in casi particolari; in questi casi la presenza di formule già inserite ci risparmierà di dover riscrivere le necessarie formule. Ed ora passiamo ad esaminare la Maschera di Composizione fattura (una UserForm). Questo è lo strumento che ci consentirà di:
Vediamo un immagine della Maschera con l'esempio di dati inseriti: Vediamo le routine collegate ad eventi dei vari controlli ActiveX impiegati. Accorgimento: per assicurarci che quando useremo il pulsante "Riporta in Fattura", tutti i dati cliente e almeno una riga di articoli siano stati inseriti, uso una variabile come interruttore di consenso, variabile chiamata appunto "interruttore", alla quale si assegnerà un valore. All'apertura della UserForm si imposta "interruttore = True". Questo ci servirà come valore da controllare prima dell'esecuzione di alcune routine, come ad esempio la routine collegata al commandbutton "Riporta in Fattura", per assicurarci che i dati cliente siano stati inseriti. Vedremo nelle routine come usare questo "interruttore". Visto però che abbiamo bisogno di una variabile che sia "visibile" in tutto il progetto, dobbiamo usare una dichiarazione di tipo Public per la variabile, e andrà posta nella sezione "Generale - Dichiarazioni" del modulo della UserForm. Avremo bisogno anche di altre due variabili pubbliche da inserire in questa zona, una è la variabile "n" che ci servirà in più routine come vettore dell' indice di riga della ListBox1; l'altra è la variabile "Tot" che ci serve per totalizzare i parziali (quantità per prezzo articolo) che inseriremo nella ListBox1, quindi scriveremo:
All'apertura della UserForm, richiamata da un pulsante posto a lato dello schema fattura, abbiamo queste istruzioni: per fornire il RowSource alle tre ComboBox presenti sulla UserForm, ho sfruttato il sistema di assegnare un nome (dal menù Inserisci/Nome/Definisci) alle aree dei vari fogli che contengono i campi da visualizzare nelle tre combobox, e di assegnare il nome al RowSource; per ottenere in automatico il numero fattura, gli si fa cercare il valore massimo presente nel foglio "Archivio", tramite la Funzione MAX, usata con WorksheetFunction, e si somma 1 a questo valore più grande trovato, ponendo il nuovo numero nella TextBox1; poi si rende la variabile pubblica "interruttore" uguale a Vero, e questa azione servirà per consentire l'esecuzione di istruzioni successive che controlleranno appunto la condizione dell' "interruttore". Per ultima istruzione, si assegnano le larghezze delle colonne che formano la ListBox1, larghezze necessarie a differenziare la larghezza dei dati.
La prima azione che compiremo quando la UserForm è attivata, sarà quello di reperire il nome del cliente da fatturare, e lo cercheremo nella prima ComboBox, apriremoo la sua lista e cliccando su un nome, attiviamo le istruzioni che porteranno nome e dati correlati nelle TextBox preposte. Sotto un'immagine e le istruzioni: per le istruzioni sfruttiamo l'evento Change della ComboBox1, che si verifica quando selezioniamo (quindi cambiamo) un valore nella lista. Intanto si cambia condizione all'"interruttore" impostandolo a "False" poi impostiamo con "zonaclienti" l'area del foglio Clienti, che ci servirà per trovare il nome che avremo selezionano nella ComboBox1, per reperire i dati correlati al nome, sulla stessa riga, e con questi dati, riempiamo le relative TextBox della userform. Per questo usiamo un doppio ciclo : un ciclo For Each ..Next che cercherà nell'elenco clienti il nome del cliente selezionato, nell'area alla quale è stato assegnato il nome "clienti" e se trovato, inizia il secondo ciclo For Next che lavora sugli "insiemi": il ciclo inizia da 1 e termina a 6, perchè sono 6 i campi correlati al nome. Poichè le TextBox che ospiteranno i dati correlati, iniziano non dalla textbox1, ma dalla 3, al contatore "I" (che inizia da 1) dobbiamo aggiungere 2. Lo stesso contatore "I" ci servirà invece per identificare con Offset, da quale colonna leggere il dato, partendo dalla colonna A (nome cliente), stessa riga del nome trovato
Se ci accorgiamo che il cliente non è presente perchè cliente nuovo, possiamo usare le TextBox (a partire dalla 2), per scrivere i nuovi dati, che poi finiranno in fattura regolarmente, ma che vorremo anche registrare nel database clienti. Per questo usiamo il commandbutton "Aggiungi Cliente", che ha solo il compito di registrare i nuovi dati sul foglio "Clienti". Anche in queste istruzioni inseriamo dei controlli di verifica; useremo un ciclo For Next che "spazzoli" le Textox, dalla 2 alla 5 per verificare che almeno nome, indirizzo, città e partita iva non ce li siamo dimenticati; ma potremo estendere la verifica anche alle altre tre textbox rimanenti. Se ci saremo dimenticati di scrivere in queste textbox, verremo avvisati da un messaggio ed usciremo dalla routine. Dopo questa verifica inizia quindi un ciclo While... Wend che cercherà sul foglio "Clienti" la prima cella libera nella colonna A, a partire dalla riga 3; trovata la cella, copieremo in questa e nelle celle alla sua destra i dati presenti nelle textbox. Anche in questa routine imposteremo l'"interruttore" a "False". Segue l'istruzione che chiama la routine "OrdinaClienti": in questo modo ordineremo tutto il foglio Clienti per nome cliente comprendendoci anche il nuovo inserimento, dopodichè riassegnamo alla ComboBox1 il RowSource per avere l'aggiornamento del nuovo cliente anche nella sua lista.
e questa la macro "OrdinaClienti", posta nello stesso modulo della UserForm:
Maschera introduzione dati - sezione inserimento articoli e quantità. La seconda parte della UserForm, quella inferiore, serve a selezionare, nella terza ComboBox, l'articolo da fatturare. La ComboBox contiene la lista degli articoli reperita tramite il RowSource, lista caricata all'apertura della UserForm. Nella TextBox "Quantità" inseriremo la quantità venduta. Mentre per quanto riguarda i dati Cliente, ovviamente sceglieremo un solo cliente a cui fatturare, per quanto riguarda gli articoli potremo fatturare più articoli per cliente. Potevamo scegliere diverse strade per riportare i vari dati in fattura, io ho scelto di iunserire gli articoli da fatturare nella ListBox1. Ad ogni selezione di un articolo nella combobox, scriveremo quantità, articolo e dati correlati all'articolo (codice, prezzo aliquota iva) nella ListBox1 in modo da poterne controllare visivamente la composizione. Solo quando avremo completato il numero degli articoli venduti, potremo premere il commandbutton "Riporta in Fattura", e verranno trasferiti dati cliente e articoli sul foglio fattura, rendendo possibile poi la stampa e l'archiviazione dei dati fattura. Per il tipo di evento scelto,( l'evento Change della Combobox2 come attivazione delle istruzioni per copiare l'articolo scelto nella ListBox), si è reso necessario scrivere la quantità venduta prima di selezionare l'articolo (e che comunque sapremo già per quale articolo la scriviamo). Chi non desidera questa procedura, potrà usare un commandbutton che attivi la copia articolo dopo la sua selezione e il successivo inserimento della quantità. L'inserimento si basa quindi sulla proprietà Text della ListBox che corrisponde al valore che avremo selezionato. Per poter inserire anche i dati correlati all'articolo scelto, useremo un ciclo For Next che reperirà, dal foglio Magaz, i dati correlati all'articolo, e che verrano inseriti nella stessa riga tramite il metodo AddItem (che posiziona il valore selezionato nella prima riga libera della ListBox, e sempre nella prima (o unica se monocolonna) colonna a sinistra). Per poter inserire anche i dati correlati sulla stessa riga, ma in colonne successive, sfrutteremo la proprietà List(numeroriga, numerocolonna) della ListBox, che ci consente di sfruttare la stessa riga ottenuta con AddItem, ma di puntare alla colonna voluta. Solo come promemoria, ricordo che l'indice riga in una ListBox inizia sempre da zero, non da 1, quindi la prima riga è la riga zero, la seconda è la riga 1, ecc. ecc., come pure l'indice colonna, quindi la colonna che occuperà AddItem sarà la colonna zero, la colonna 1 sarà la seconda, ecc. ecc. Questa la routine associata all'evento Click della ListBox1:
Due precisazioni: le variabili pubbliche "n" e "Tot", ad inizio routine, hanno i valori equivalenti a zero, a fine routine, la variabile "n" si incrementa di 1 e resta tale anche se la routine termina, proprio perchè Pubblica ha visibilità sull'intero progetto, e se non si riazzera resta tale. Servirà a fornire il numero di riga successivo a quello già usato, nel caso di un nuovo inserimento articolo nella ListBox1. Lo stesso dicasi per la variabile "Tot", che fornirà quindi un progressivo dei conteggi ottenuti con la variabile "per". Vedremo poi come azzerare le variabili con le successive routine. Siamo arrivati al punto in cui si presume che tutti i dati sono stati inseriti, e dovremo "copiare" dati dalla UserForm alle rispettive celle nel layout della fattura. Per questo useremo il CommandButton "Riporta in Fattura", nel quale evento Click abbiamo la seguente routine:
La logica sequenza delle operazioni, una volta trasferiti i dati sul foglio fattura, sarà quella di stampare la fattura, che nel frattempo si è completata nei totali grazie alle formule residenti. Potremo anche salvare una copia del solo foglio fattura, ma queste istruzioni non le ho inserite; potrete aggiungerle se credete, leggendo l'articolo "Salvare una Fattura". Comunque queste sono le istruzioni contenute nell'evento Click del CommandButton "Stampa la Fattura":
Completeremo poi con la registrazione dei dati necessari all'archiviazione fattura, usando il CommandButton "Registra la Fattura". In questa routine, cercheremo con un ciclo While la prima riga libera nella colonna A dove inserire i dati necessari all'archivio, presenti nelle celle del foglio fattura
Mi sembra ci sia tutto; se ho dimenticato qualcosa, si potrà comunque consultare il file che inserisco sotto da scaricare. Questo esercizio, oltre che migliorabile, è ampliabile a piacere, datevi da fare, e buon lavoro.
File scaricabile e consultabile : Fatturaz2000.zip 33 Kb
prelevato sul sito www.ennius.altervista.org |