Autore Topic: [RISOLTO]Procedure comuni a più ComboBox  (Letto 883 volte)

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
[RISOLTO]Procedure comuni a più ComboBox
« il: 24 Ottobre 2010, 23:49:49 »
Nel mio programma cantiere ho inserito una nuova Form destinata a gestire l'inserimento di voci contabili nuove.
L'inserimento prevede  la compilazione delle relative ComboBox.List al fine di verificare le voci esistenti prima della digitazione. A fine inserimento ho previsto gli eventi ComboBox_LostFocus. Mi sono accorto però, che il codice scritto in detti contenitori é comune a tutte le ComboBox. Ho allopra cercato di creare un nuovo oggetto da richiamare all'interno di ciascuna ComboBox_LostFocus a cui passare i riferimenti, o meglio, la copia dei dati già presenti nelle rispettive ComboBox.Text e ComboBox.list. Per ottenere ciò, dall'alto della mie scarse conososcenze in merito al trattamento degli object ho scritto il seguente codice:
Codice: gambas [Seleziona]
PUBLIC SUB VoContCas_LostFocus()
VoCo_LostFocus AS VociCont_LostFocus
VoCo_LostFocus = new VociCont_LostFocus(VoContCas.List, VoContCas.Text)
end
....................................................................... e
PRIVATE SUB VociCont_LostFocus(VoContCas.List AS NEW String[], VoContCas.Text AS String) AS NEW Object
................bla bla bla ..........................
................bla bla bla ..........................
END


Lanciando il programma dall'IDE di Gambas ricevo subito l'errore Missing As alla linea 553 in Form13.Class

Ho capito di essere abbastanza fuori strada. Non riesco a capire dov'é l'errore e perciò non intuisco se quanto scritto possa essere aggiustato opportunamente o se invece devo pensare a qualcosa di completamente diverso.
 :specchio:  ???  :rolleyes:
 :(
« Ultima modifica: 31 Ottobre 2010, 17:47:26 da Picavbg »
:ciao:

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Procedure comuni a più ComboBox
« Risposta #1 il: 27 Ottobre 2010, 19:55:10 »
L'argomento riguarda, come ovviamente avrete già capito, la riunione di due o più ComboBox interne ad una Form sotto un unico gruppo per gestire dati della stessa natura. ma da considerare a segmenti distinti (Es. Un Elenco alfabetico di Nomi). Il mio caso é un pò diverso; infatti devo elencare i nomi di conto di una tabella di DB, in funzione della loro appartenenza a range diversi di codici numerici.
Per fare ciò dispongo di una form dove ho dichiarato 5 CombBox dove riunire i miei 5 segmenti di conti. Ho perciò dichiarato in fase di progettazione le 5 ComboBox come appartenenti allo stesso Gruppo "CmbVoci". Nelle rispettive Proprietà "TAG", ho dichiarato costanti stringa diverse l'una dall'altra. Poi, nella Form ho scritto:
Codice: gambas [Seleziona]
PRIVATE o_CmbVoci AS Object

PUBLIC SUB CmbVociCont_GotFocus()
DIM i AS Integer
DIM i_TotCar AS Integer
'----------------------------------------
  i_TotCar = 0
  DBOpen = NEW ApriDB
  b_SwErro = FALSE
  FOR EACH o_CmbVoci IN ME.Children
      SELECT CASE o_CmbVoci.tag
              CASE "vococas"
               ................bla bla bla .......................... 
               ................bla bla bla .......................... 
               CASE "vosotcocas"
               CASE "vopricolleg"
               CASE "vosecolleg"
               CASE "vosotcolleg"
      END SELECT
      FOR i = 0 TO o_CmbVoci.Max
      NEXT
      ................bla bla bla .......................... 
      ................bla bla bla ..........................     
  NEXT   


Il codice riporatato sopra ha funzionato solo in parte:
1) la SELECT CASE o_CmbVoci.tag posta subito dopo l'istruzione FOR EACH ha funzionato perfettamente;
2) la FOR i = 0 TO o_CmbVoci.Max posta dopo l'END SELECT, ma sempre dentro il gruppo di istruzioni racchiuso da FOR EACH...NEXT provoca l'errore
Citazione
Unknown symbol 'MAX' in class 'Label'
la stessa cosa succede se al posto di  FOR i = 0 TO o_CmbVoci.Max scrivo i = o_CmbVoci.Count.

Pensavo che lo studio fatto dopo il mio primo post senza risposta avesse prodotto la giusta ricompensa morale, ma purtroppo mi sono sbagliato. Spero che qualcuno mi possa dare una mano. Grazie
 :(
:ciao:

Offline milio

  • Senatore Gambero
  • ******
  • Post: 1.273
  • Chi parla poco dice tanto...
    • Mostra profilo
Re: Procedure comuni a più ComboBox
« Risposta #2 il: 27 Ottobre 2010, 20:27:15 »
prova a scrivere prima del For...Next:

Codice: gambas [Seleziona]
IF Object.Is(o_CmbVoci, "ComboBox") THEN 

  FOR i = 0 TO o_CmbVoci.Max  
     ....bla bla bla....
  NEXT  

ENDIF
« Ultima modifica: 27 Ottobre 2010, 20:39:39 da milio »

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Procedure comuni a più ComboBox
« Risposta #3 il: 27 Ottobre 2010, 22:56:59 »
prova a scrivere prima del For...Next:

Codice: gambas [Seleziona]
IF Object.Is(o_CmbVoci, "ComboBox") THEN 

  FOR i = 0 TO o_CmbVoci.Max  
     ....bla bla bla....
  NEXT  

ENDIF


Qualcosa é cambiato:
viene eseguito 4 volte il ciclo FOR EACH o_CmbVoci IN ME.Children ... NEXT, eseguendo la   SELECT CASE o_CmbVoci.tag, da cui esce sempre per <>, per cui la if che mi hai suggerito termina sempre per "NOT OBject.is" . Al 4° passaggio, il test  CASE "vococas"  da esito positivo, la if che mi hai suggerito termina  per "OBject.is", ma al For...NEXT successivo  si ripresenta inesorabile l'errore di prima!  ???
Spero di essermi spiegato con chiarezza.
 :(
« Ultima modifica: 27 Ottobre 2010, 23:34:52 da Picavbg »
:ciao:

Offline milio

  • Senatore Gambero
  • ******
  • Post: 1.273
  • Chi parla poco dice tanto...
    • Mostra profilo
Re: Procedure comuni a più ComboBox
« Risposta #4 il: 28 Ottobre 2010, 15:44:10 »
Ma non ho capito allora che cosa vuoi fare con quel for...next...
e' possibile avere tutto il codice del Form...
Magari vedendo com'e' strutturato il tutto, e capendoci un po' di piu' su che tipo di ricerca vuoi fare, ti posso dare una mano ;)

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Procedure comuni a più ComboBox
« Risposta #5 il: 28 Ottobre 2010, 16:23:28 »
Ma non ho capito allora che cosa vuoi fare con quel for...next...
e' possibile avere tutto il codice del Form...
Magari vedendo com'e' strutturato il tutto, e capendoci un po' di piu' su che tipo di ricerca vuoi fare, ti posso dare una mano ;)
Non ti preoccupare, penso di avere risolto col seguente ragionamento:
Ho rivisitato tutto il codice relativo al mio problema e, secondo me, in quello che ho scritto manca il collegamento fra la dichiarazione
Codice: [Seleziona]
# PRIVATE o_CmbVoci AS Object  
ed il gruppo ComboBox definito nella Form, in progettazione, per cui il comando
Codice: [Seleziona]
FOR i = 0 TO o_CmbVoci.Max
   
non riesce ad associare la proprietà ".Max" agli oggetti ComboBox.

Ho pensato allora di costruire una tabella coi puntamenti alle varie ComboBox nel metodo "_new", in modo da caricare detti puntamenti una sola volta, al momento dell'attivazione della Form:
Codice: gambas [Seleziona]
PUBLIC SUB CarPuntVociCo()     'Procedura di caricamento della Tabella dei puntamenti ad alcune ComboBox della Form
    o_ElCmbVoci.Add(ME.VoCont1)
    o_ElCmbVoci.Add(ME.VoCont2)
    o_ElCmbVoci.Add(ME.VoCont3)
    o_ElCmbVoci.Add(ME.VoCont4)
    o_ElCmbVoci.Add(ME.VoCont5)
END


Ho naturalmente dichiarato, nella sezione dichiarazioni della Form, l'array
Codice: [Seleziona]
PRIVATE o_ElCmbVoci AS NEW Object[] 

 ed ho modificato il codice così:
Codice: gambas [Seleziona]
' FOR EACH o_CmbVoci IN ME.Children     '####### istruzione eliminata #######
  FOR EACH o_CmbVoci IN o_ElCmbVoci   '.................... nuova istruzione sostitiva della precedente ....................
       SELECT CASE o_CmbVoci.tag 
              CASE "vococas" 
               ................bla bla bla ..........................   
               ................bla bla bla ..........................   
               CASE "vosotcocas" 
               CASE "vopricolleg" 
               CASE "vosecolleg" 
               CASE "vosotcolleg" 
      END SELECT   
      FOR i = 0 TO o_CmbVoci.Max 
      NEXT   
      ................bla bla bla ..........................   
      ................bla bla bla ..........................       
  NEXT     


Ho riavviato il programma e ... voilà, ha funzionato tutto benissimo.   :D

Però non sono proprio soddisfatto perché, in base al tuo suggerimento ed in base a quello letto sul wiki (ho provato anche LAST), avrebbe dovuto funzionare. Tuttavia avrò sicuramente commesso una qualche negligenza e credo proprio nella mancanza del collegamento di cui ho detto all'inizio di questa risposta.

Se vogliamo capire che cosa manchi per aver provocato l'errore, posso mandarti, oltre all'immagine della Form,  sia la sezione delle dichiarazioni che la procedura _GotFocus incriminata.

Al piacere di risentirti. :)
:ciao:

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Procedure comuni a più ComboBox
« Risposta #6 il: 29 Ottobre 2010, 17:03:40 »
Capisco che il mio problema é mio, perciò non t'interessa più di tanto, ma visto che abbiamo intrapreso uninteressante discussione, mi pare doveroso portarla fino in fondo, per poterla poi archiviare definitivamente.  ;D ;D

Una volta accertato che il metodo che ho messo in pratica funziona, il mio cruccio era di capire perché il metodo NomeGruppo.Tag non debba funzionare.
Provando e riprovando, sono giunto alla seguente conclusione: Essendo l'evento schedulato "NomeGruppo_GotFocus" comune a più ComboBox quando punto alla proprietà "NomeGruppo.Text", per es., Gambas non riesce a riconoscere la ComboBox che ha ricevuto il Focus; é necessario allora farsi comunicare da Gambas il riferimento alla ComboBox attiva e ciò si ottiene attraverso l'uso della parola magica "LAST". Rileggendo il wiki in proposito mi sono soffermato sul seguente concetto:
Citazione
Il valore contenuto in LAST può ovviamente essere copiato in un altra variabile, e può essere usato direttamente per determinare il valore delle proprietà dell'oggetto stesso (es. LAST.Value ritorna il valore corrente della CheckBox cliccata)
Ho pensato allora di interrogare il contenuto della proprietà "Tag" della ComboBox attiva e di scegliere così quale ComboBox.List interessare per il caricamento dei dati letti dal mio DB. Ho provato ed ha funzionato, risparmiando codice e pericolosi cicli iterativi .
Ecco alla fine quello che ho tirato fuori:
Codice: gambas [Seleziona]
PUBLIC SUB CmbVoci_GotFocus()
 ................ Dim varie ..........................
SELECT CASE LAST.tag
              CASE "vococas"
                 ................bla bla bla ..........................     
                 ................bla bla bla ..........................     
              CASE "vosotcocas"
                 ................bla bla bla ..........................     
                 ................bla bla bla ..........................     
END SELECT
DBOpen.RecTbpiacon = DBOpen.DB_Connection.EXEC("SELECT * FROM piancont WHERE NumVoce >= '" & i_NuContIni & "' AND NumVoce <= '" & i_NuContFin & "' ORDER BY NumVoce ")
FOR EACH DBOpen.RecTbpiacon
       LAST.Add(DBOpen.RecTbpiacon!NomeVoce)
NEXT
DBOpen.DB_Connection.Close
END


Da tutto ciò ho capito l'imporatnza della proprietà GROUP e del metodo LAST. Ho trovato quest'ultimo molto efficace, perché quando l'evento attivo é quello di un gruppo di oggetti come CheckBox, TextBox, ComboBox, ecc si può fare riferimento agevolmente alla proprietà desiderata dentro ciascun Box del gruppo di oggetti srivendo semplicemente LAST.Value,  LAST.Tag, LAST.Text,  .......

Posso dire ora di avere concluso con soddisfazione la discussione, non tanto per avere trovato una soluzione pratica e comoda, ma soprattutto perché ho imparato!!!
 :) :D ;D   :yeah:

Ho voluto comunicartelo perché il merito é anche tuo. Senza il tuo pungolo non ci sarei riuscito.
:ciao: