Caricare un elenco (lista) con dati da selezionare.    (05/07/03)

Tra le tante necessità quotidiane, ci troviamo spesso a dover aggiungere dei dati in un elenco. Un operazione che possiamo prendere ad esempio e che si presta per spiegare i concetti, riguarda l'inserimento degli articoli venduti, in una fattura. Infatti nella emissione di una fattura, useremo dati che verranno scritti (nelle celle appositamente designate) una sola volta, come il nome del Cliente, indirizzo, pagamento, p.iva, ecc. ecc., mentre avremo dati che dovremo o potremo scrivere più volte, come i prodotti da fatturare, con la loro descrizione, il codice articolo, unità di misura, quantità, prezzo unitario, ecc. ecc. In questi casi normalmente viene destinata una zona dove poter aggiungere, riga dopo riga, i vari prodotti e loro caratteristiche. Le procedure che presento riguardano appunto:

  • come reperire i prodotti da inserire tramite combobox su userform

  • come inserire i prodotti nell'area assegnata, disponendo i dati correlati all'articolo nelle celle di pertinenza.

  • svolgere una parte dei conteggi (quantità x prezzo - ev sconto) direttamente con l'inserimento dell'articolo.

Premetto che questo articolo è molto dettagliato e un pò lunghetto, consiglio a chi ne sia interessato di stamparsi le pagine (verranno stampate anche le immagini) e leggerselo TUTTO con calma a casa.

Come esercizio userò un file che un caro amico, Domenico Svolacchia, mi ha gentilmente messo a disposizione, e su cui ho sviluppato le procedure relative all'"inserimento articoli". Vediamo intanto la "struttura" di impostazione della fattura relativa alla zona inserimento articoli:

Come vediamo, a partire dalla riga 18, potremo inserire gli articoli, che andranno nel campo "descrizione", e dovremo inserire nei campi tutti i dati riguardanti l'articolo scelto. Gli articoli che inseriremo sono in una tabella del foglio "Magazzino", che avremo cura di strutturare sulla falsariga dell'ordine campi riportati in fattura, in modo da "allineare" i campi in entrambi i fogli. Logicamente sul foglio "Magazzino" non saranno presenti i campi che riguardano i conteggi (totale, sconti, imponibile) inutili in questo foglio. Vediamo il foglio Magazzino con l'impostazione della tabella articoli:

All'area del foglio Magazzino predisposta a contenere dati, assegniamo un nome : "maga" che corrisponde a =Magazzino!$A$2:$B$1000, per facilitare il riferimento alla zona quando lo useremo nel codice vba per assegnare il RowSource alla combobox posta sulla userform.

Bene, abbiamo visto la zona di destinazione, e la zona di origine dei dati, ora vediamo come reperirli (primo punto nelle descrizione delle procedure:

la prima procedura, è chiamare la userform dal foglio di emissione fattura, che useremo come "maschera" per la selezione dell'articolo, e lo faremo tramite il commandbutton  "Inserisci Articolo", nel cui evento Click, inseriamo questa istruzione:

            Private Sub CommandButton3_Click()  'pulsante "Inserisci Articolo"
            UserForm1.Show
            End Sub

e questo sarà l'aspetto della userform:, in cui vediamo una combobox che ci servirà per selezionare un'articolo tra quelli presenti sul foglio "Magazzino", una textbox per inserire la quantità da fatturare, e due textbox per inserire eventuali sconti concessi sull'articolo. Completa l'userform il commandbutton "In Fattura" , che nell'evento Click, ha inserito tutte le istruzioni (che vedremo) per l'inserimento dell'articolo e dei dati correlati nell'area della fattura predisposta:

Sfrutteremo quindi l'apertura della userform per assegnare l'area dati del foglio magazzino al RowSource della combobox, con questa istruzione:

                  Private Sub UserForm_Activate()
                  ComboBox1.RowSource = "Magazzino!maga"
                  End Sub

Come abbiamo notato dalle spiegazioni sopra, stiamo "caricando" nella combobox due colonne di dati : la colonna A con il codice articolo e la colonna B con la descrizione dell'articolo (A2:B1000). Un piccolo accorgimento che ci permetterà di identificare meglio l'articolo da fatturare, vedremo infatti sia il codice sia la descrizione (è possibile infatti che esistano più articoli con la stessa descrizione, e sarà quindi possibile identificare quello giusto tramite il codice articolo che dovrà necessariamente essere univoco). Vediamo un immagine della combobox col menù aperto:

Come facciamo ad avere visibili due colonne nella combobox ? Utilizzando alcune proprietà che troveremo nella "Finestra delle proprietà" della combobox, nell'editor del visual basic :

  • proprietà ColumnCount : la imposteremo a 2 in quanto vorremo vedere appunto due colonne.

  • proprietà ColumnWidths : con questa proprietà è possibile determinare la larghezza di ogni singola colonna, indicando un valore espresso in punti seguito da pt , separando con un punto e virgola i valori decisi; in questo esempio i valori assegnati sono : 48 pt;72 pt .Regolando questi valori assegneremo larghezze diverse alle colonne.

Vediamo poi come gestire via codice, altre due proprietà della combobox che determinano il modo di assegnazione del valore di ogni campo (ne abbiamo 2 nella combobox) a due celle distinte del foglio di lavoro

  • proprietà Text : con ComboBox1.Text  identifichiamo il valore che si trova nella prima colonna a sinistra della riga selezionata (in questo caso il codice articolo).

  • proprietà BoundColumn : con questa proprietà determiniamo, assegnandoli un numero, a quale colonna ci riferiremo perchè ci venga restituito il valore corrispondente nella riga selezionata. il numero che indicheremo, sarà sempre un indice che parte da 1 (e non da zero come in genere fanno i valori indice in vb). Poichè a noi interessa a questo punto la "descrizione articolo" che vediamo nella seconda colonna, abbiamo bisogno di due istruzioni; la prima assegna il valore indice alla proprietà BoundColumn, così :    ComboBox1.BoundColumn = 2

    la seconda dovrà fare riferimento non più al Text, bensì al Value (valore indice, cioè 2) della ComboBox, così  :  ComboBox1.Value  .Questo ci restituirà la descrizione articolo.

Ci siamo fino a questo punto? Bene, ora proseguiamo con l'esame della routine che dovrà provvedere a trovare, nel foglio fattura, la prima riga libera dove inserire i dati selezionati nella combobox. Ci affidiamo per questo ad un ciclo While...Wend, ciclo che controlla una condizione, e continua fintantochè si verifica la condizione richiesta. Poichè vorremo controllare, posta una riga di partenza (la riga 18. inizio inserimento articoli nella fattura) se una riga è vuota, abbiamo bisogno di un "contatore" che incrementi di uno il controllo per garantire l'avanzamento verso il basso di una riga, e queste sono le istruzioni del ciclo:

          Dim iRow As Integer
          iRow = 18
 'si imposta il numero riga dal quale iniziare il controllo, quindi iRow ora è uguale a 18
          While Cells(iRow, 2).Value <> "" 
'Fino a che la cella (ora la18, colonna 2) è diversa da vuoto (cioè
          iRow = iRow + 1 
'contiene dati) si incrementa il numero riga di uno e con Wend si richiama While
          Wend                  
'continuando la verifica, e quando si troverà una cella vuota, si esce dal ciclo

va da se che se la prima riga è vuota (la 18) si esce dal ciclo e si eseguiranno le istruzioni che seguiranno, altrimenti verrà controllata la condizione richiesta per la riga 19, poi la 20, ecc. ecc. Ricordo che quando si usa la proprietà Cells (dell'Insieme Range) il primo numero indica la riga, il secondo dopo la virgola indica la colonna. Questo ci dice due cose :

  • la prima è che stiamo controllando le righe della colonna due, cioè la colonna B, dove si troverà la descrizione articolo.

  • la seconda è che quando verrà trovata una cella vuota, quella sarà la cella identificata con (iRow, 2); se vorremo riferirci ad altre celle della stessa riga sarà sufficiente modificare il numero colonna; per esempio con (iRow, 4) identificheremo la cella della 4 colonna, cioè la D; il numero di riga dipenderà dal valore che in quel momento avrà iRow.

Fatte tutte queste premesse, passiamo ora ad esaminare la routine inserita nell'evento Click del CommandButton "In Fattura". Ultime considerazioni:

per automatizzare al massimo il lavoro, è stato previsto che l'inserimento della Quantità da fatturare avvenga dalla userform, attraverso l'immissione di un valore, che potrà essere anche decimale, nella casella di testo oppurtuna. Sempre dall'userform si disporrà per un eventuale sconto semplice o doppio, visto che si presume che gli sconti non sempre siano concessi, e comunque potranno variare in funzione del cliente e/o delle quantità. Predisporre dei campi sconti preimpostati nel foglio magazzino non lo ritengo utile ma limitante.

Saranno commentate in verde le istruzioni non ancora viste.

Private Sub CommandButton1_Click()

'sotto: si controlla solo se nella textbox1 è stata inserito un valore, in caso contrario si 'avvisa e si esce dalla routine

If TextBox1 = "" Then
MsgBox "Manca la quantità"
TextBox1.SetFocus
Exit Sub
End If

'sotto: inizia il ciclo While..Wend
Dim iRow As Integer
iRow = 18
While Cells(iRow, 2).Value <> ""
iRow = iRow + 1
Wend

'trovata la riga con la cella vuota, scrivo la selezione fatta nella combobox
Cells(iRow, 1) = ComboBox1.Text    'prendo il codice art. e lo inserisco nella colonna 1
X = Cells(iRow, 1).Address ' con la variabile X prendo il riferimento alla
'cella che userò poi come primo argomento nella funzione vLookUp più sotto

ComboBox1.BoundColumn = 2
Cells(iRow, 2) = ComboBox1.Value 'ora assegno alla riga, 2° colonna
'il valore trovato con BoundColumn, cioè la descrizione articolo

Cells(iRow, 4) = CDbl(TextBox1) 'assegno alla cella della colonna 4 (la D) la quantità 'dichiarandola come "tipo di dati" Double cioè numero con decimali
TextBox1 = ""  
 'pulisco la textbox1


'faccio cercare con vlookup i valori correlati al codice art. cioè unita misura, prezzo, al. 'iva. e li assegno alle rispettive colonne, stessa riga di iRow
Cells(iRow, 3).Formula = "=vlookup(" & X & ",Magazzino!A2:E500,3,0)"
Cells(iRow, 5).Formula = "=vlookup(" & X & ",Magazzino!A2:E500,4,0)"
Cells(iRow, 10).Formula = "=vlookup(" & X & ",Magazzino!A2:E500,5,0)"


'ora facciamo da codice tutte le operazioni per i conteggi:
'otteniamo il parziale: prezzo x quantità, usandoli come tipo di dati Double

Cells(iRow, 6) = CDbl(Cells(iRow, 4) * CDbl(Cells(iRow, 5)))


'ora conteggiamo l'imponibile considerando gli sconti:
'assegniamo a due variabili gli importi presenti nelle textbox per gli sconti.
'se lo sconto non esiste bisogna assegnare comunque un valore, altrimenti si genera un 'errore se il valore è vuoto, e quindi in mancanza di un valore impostiamo lo zero:

If TextBox2 = "" Then TextBox2 = 0
sc1 = CDbl(TextBox2)
'la variabile sc1 è uguale al primo valore di sconto

If TextBox3 = "" Then TextBox3 = 0
sc2 = CDbl(TextBox3)
' come sopra per sc2 uguale al secondo valore di sconto


'ora scontiamo il parziale per il primo sconto e lo memoriziamo
'in una variabile nps (netto primo sconto)

nps = CDbl(Cells(iRow, 6) - CDbl(Cells(iRow, 6) * CDbl(sc1) / 100))


'ora se il primo valore di sconto è maggiore di zero lo scriviamo in fattura
If sc1 > 0 Then Cells(iRow, 7) = sc1


'poi anche se il secondo valore di sconto è maggiore di zero lo scriviamo in fattura ed 'eseguiamo il calcolo
If sc2 > 0 Then
Cells(iRow, 8) = sc2
'ora scontiamo il nps per il secondo sconto e lo memoriziamo in una variabile nss (netto 'secondo sconto)
nss = CDbl(nps) - CDbl((nps * sc2) / 100)

Cells(iRow, 9) = nss 'ora l'imponbile è uguale a netto secondo sconto
Else ' altrimenti (se il secondo sconto è zero)
Cells(iRow, 9) = nps 'l'imponibile è uguale al netto primo sconto
End If
TextBox2 = ""       'pulisco la textbox2
TextBox3 = ""       'pulisco la textbox3
'sotto, reinizializzo la combobox per una successiva selezione articolo
ComboBox1.Text = "Seleziona un'articolo"
End Sub

Abbiamo scritto un bel pò di codice, ma i risultati sono eccellenti : ci troveremo già con tutti i calcoli fatti, ed in più se non avremo assegnato sconti, i relativi campi in fattura non porteranno neanche lo zero, cosa che se ci fosse comunque un valore in fattura, potrebbe far pensare al cliente che gli sconti sono previsti e quindi gestibili, mentre così si potrà dire che le colonne sconti le ha inserite il compilatore del modulo fattura ma che in realtà non esiste sconto (infatti i campi sono vuoti). L'ultima colonna, quella dell'aliquota iva, servirà perche i conteggi dei totali useranno la funzione SOMMA.SE  reperendo il totale dei parziali collegati alle varie aliquote, ed applicando quindi l'iva di pertinenza sul relativo imponibile. Un immagine della zona totali:

Ho indicato la Formula per la somma degli importi relativi all'aliquota iva 4%, nelle celle sottostanti ci saranno le formule per iva 10% e iva 20%. Gli importi iva si ottengono con una semplice moltiplicazione, e i totli portaranno la somma degli imponibili, la somma degli importi iva e quindi il totale fattura. Allego il file per consultazione premettendo che le procedure andranno ultimate a cura dei "pellegrini" che vorranno scaricarsi il file: manca la registrazione dei dati fattura, il salvataggio del solo foglio fattura come copia, ed altre amenità lasciate ai bisogni di ogni singolo utente. Mi interessava illustrare le procedure per l'inserimento dei dati, e questo credo di averlo espletato.

 

File consultabile e scaricabile  :  Fattura2000.zip   38  Kb

 

Buon lavoro.


prelevato sul sito http://ennius.interfree.it