Maschere dinamiche

di il
18 risposte

Maschere dinamiche

Ciao a tutti, mi presento. Mi chiamo Sergio e sono un consulente di "altra robba"... che ogni tanto si diletta a fare qualche piccolo gestionale in Access.
Vi scrivo per sapere se qualcuno si è trovato di fronte a questo problema e se ha trovato qualche soluzione "creativa".
Ho una maschera che dovrebbe essere popolata con tanti CONTROLLI quanti sono i VALORI che escono da un RECORDSET tramite una query. Tendenzialmente, NON POSSO SAPERE in anticipo quanti sono i valori che la query restituirà. Allego un esempio.
So già che Access (2010) non consente la creazione di controlli in runtime, quindi nella mia soluzione io creo una maschera con un elevato numero di controlli NON VISIBILI in partenza ma resi visibili e valorizzati durante l'esecuzione del codice. Il problema è che l'esempio allegato funziona con 15 potenziali controlli, ma nel DB reale potrei avere una quantità di valori (e controlli corrispondenti) molto elevata, quindi non saprei proprio come gestire la cosa.
Nel DB "reale", anziché text box potrei avere caselle di controllo SI/NO, ma al momento questo è indifferente.
Di seguito il codice con la soluzione "posticcia" che ho applicato io. Questa soluzione è testata e funziona, ma vorrei tentare qualcosa "di più" e chiedo alla community se qualcuno ha fatto di meglio e può aiutarmi. I colori OK sono Rosso, Verde, Giallo e Blu; gli altri restituiscono una maschera vuota.
Grazie in anticipo e scusate la prolissità ma voglio essere il più chiaro possibile per non farvi perder tempo.
PdS
Private Sub Form_Current()

'**********************
'* Preparo l'ambiente *
'**********************

Dim DaBaCol As Database
Dim RecoSet As Recordset
Dim RecoSet2 As Recordset
Dim Camp As Field
Dim StConta As String
Dim StCerca As String
Dim ContaRec As Integer
Dim SeleRec As Integer
Dim Scelta As String

'******************************************
'* Chiedo all'utente di dirmi un colore.  *
'* Il DB contiene una sola tabella i cui  *
'* campi sono "Numero" e "Colore".        *
'* Il campo "Numero è quello che contiene *
'* gli "n" valori che mi serve estrarre.  *
'******************************************


Scelta = InputBox("Dimmi un colore")

'*************************************************************************
'* Preparo due query: una per sapere quanti record contiene la tabella   *
'* e una per estrarre i valori che mi servono per costruire la maschera. *
'*************************************************************************

StConta = "Select Count(Numero) as ContaRecord from [SeleCampi] Where [Colore]='" & Scelta & "'"

StCerca = "Select * from [Selecampi] Where [Colore]='" & Scelta & "'"

Set DaBaCol = CurrentDb

'*********************************************************************************************************
'* Uso il primo recordset per contare i record e archivio il valore in una variabile che userò più volte *
'*********************************************************************************************************

Set RecoSet = DaBaCol.OpenRecordset(StConta, dbOpenDynaset, dbReadOnly)

ContaRec = RecoSet.Fields("ContaRecord")

If ContaRec = 0 Then
    MsgBox "Nessun record con questo colore."
    RecoSet.Close
    Set RecoSet = Nothing
    Exit Sub
End If

'***************************
'* Pulisco. Mi piace così. *
'***************************

RecoSet.Close
Set RecoSet = Nothing

'*******************************************
'* Mi faccio dire quanti record ho trovato *
'*******************************************

'MsgBox "Numero di record corrispondenti: " & ContaRec

'************************************************
'* Uso il secondo recordset per estrarre i dati *
'************************************************

Set RecoSet2 = DaBaCol.OpenRecordset(StCerca, dbOpenDynaset, dbReadOnly)

RecoSet2.MoveFirst
i = 0

'*****************************************
'* Preparo un array monodimensionale per *
'* archiviare i valori e popolo l'array  *
'* utilizzando un ciclo semplice.        *
'*****************************************

ReDim Selezione(ContaRec) As Variant

    Do While Not RecoSet2.EOF
        Selezione(i) = RecoSet2!Numero
        i = i + 1
        RecoSet2.MoveNext
    Loop

'***************************
'* Pulisco. Mi piace così. *
'***************************

RecoSet2.Close
Set RecoSet2 = Nothing

'*********************************************************
'* A questo punto rendo visibili i campi della maschera  *
'* cui ho già assegnato nomi fissi seguiti da numeri     *
'* attraverso un ciclo ed usando ancora la variabile che *
'* contiene il numero di record.                         *
'*********************************************************

For zx = 0 To ContaRec - 1
    
    NomeCont = "Testo" & zx + 1
    Me.Controls(NomeCont).Visible = True
    Me.Controls(NomeCont) = "Colore " & Scelta & " trovato nel " & Selezione(zx)
    Set Cont = Nothing

Next

End Sub

18 Risposte

  • Re: Maschere dinamiche

    Sergio ciao...!
    Prima di esporti pareri sul codice, prematuro, è indispensabile capirsi bene... e serve qualche passaggio.

    Una query restituisce Records, ogni Record dell'insieme dei Records contiene un numero di Campi definiti Fields.

    Tu hai utilizzato termini non standard che mi lasciano mal interpretare l'esigenza.

    Ora i Controlli da rendere VISIBILI sono associati ai Campi o Fields e non al Numero di Records...
    Quindi se tu costruisci una Maschera che contiene il Numero di Controlli = NUmero di Campi tutto quello che stai facendo perde molto di significato... ed è quì che non ritrovo coerenza nel tuo progetto.

    La visualizzazione a maschere continue è fatta in modo tale che non richiede configurazioni in relazione al Numero dei RECORDS.

    Facci sapere.

    P.S. Usa i TAG code...!
  • Re: Maschere dinamiche

    Ciao @Alex, intanto grazie per la risposta.
    Mi scuso per non aver chiarito subito un concetto: i controlli della maschera debbono essere solo controlli non associati.
    Ovviamente quella che ho mostrato nel codice è solo una parte del tutto, ma è la più importante.
    L'esigenza è creare dinamicamente controlli che serviranno poi agli utenti per fare altre elaborazioni sulla maschera (tra cui anche modificare il contenuto del controllo che andrà poi a scrivere su un'altra tabella).

    Poi tu mi scrivi:
    Una query restituisce Records, ogni Record dell'insieme dei Records contiene un numero di Campi definiti Fields.


    Certamente. Infatti io debbo prendere una serie di valori contenuti in uno specifico campo dei record del recordset che soddisfano una certa condizione.

    Nella fattispecie, esempio:
    Query="Prendi tutti i valori del campo Numero dai record nei quali il campo Colore contiene Rosso".
    
    Poi, metto i valori in una variabile di tipo variant quindi uso i valori nella variant per creare i controlli di cui sopra.

    Poiché forse non mi esprimo correttamente, posto il link al db (84 Kb) così vedendo le prove fatte forse risulta più chiara la mia richiesta!

    https://www.dropbox.com/sh/tn9h2a0wx70vtro/AABBdwDVB5aGQb4JVYC_HeYla?dl=0

    Ciao e ancora grazie
    PdS[/size]
  • Re: Maschere dinamiche

    Prima vorrei comprendere il PERCHÉ devi o vuoi usare solo controlli non associati... l'esigenza è molto strana...
    Certo saprai bene che il numero di controlli per maschera ha un limite...
    Da dire poi che usi una matrice... per inserire i dati del recordset, anche questo risulta incomprensibile dal momento che un Recordset sotto certi punti di vista è meglio. ...

    Sai anche immagino che l'associazione di dati può essere fatta in modo dinamico e sfruttando sempre la visualizzazione Continua con un Recordset ADO basato su una tabella virtuale in memoria..?

    Insomma se ci dai una visione di insieme forse possiamo essere più tecnici.
  • Re: Maschere dinamiche

    Sai anche immagino che l'associazione di dati può essere fatta in modo dinamico e sfruttando sempre la visualizzazione Continua con un Recordset ADO basato su una tabella virtuale in memoria..?
    Uh, si alcune cose le so altre no. Questa per esempio si e no, nel senso che "dipende".

    Ti spiego bene cosa mi serve: ho un cliente che deve pianificare dei lavori su determinate zone.

    Le zone vengono (attualmente) scelte da una combobox il cui contenuto dipende dalla prima scelta che fa l'utente. Ad esempio, se l'utente deve fare "consegne", le zone per le "consegne" sono un tot (ma possono aumentare). Se invece l'utente deve fare "spedizioni", le zone per le spedizioni sono un altro tot e sono diverse dalle zone delle "consegne".

    La tabella "Zone" contiene un campo che identifica il tipo di attività, ossia: n record il cui campo "attività" è "spedizioni" e un campo con la zona.

    Quando l'utente sceglie quale attività svolgere, il DB mostra una combobox con tutte le zone per quell'attività. Per ora sono meno di 100 zone ma più di 50 per ogni attività.

    Adesso, il cliente mi ha chiesto: "Quando scelgo l'attività, voglio che mi mostri TUTTE le zone di quell'attività con vicino una check box per scegliere una o più zone".

    Di qui, l'esigenza di far vedere TUTTE le zone di quella SOLA attività. Ogni tanto può aggiungersi una zona, per questo volevo che la visualizzazione fosse dinamica.

    Mi sento un deficiente perché so di non usare terminologie ortodosse... ma spero di essermi spiegato!

    Grazie ancora!
    S.
  • Re: Maschere dinamiche

    Continuo a non capire la logica...
    Perchè non prendi in considerazione una Maschera in visualizzazione CONTINUA invece che singola...?
    Ci hai pensato...?
    Hai trovato delle limitazioni...? Quali...?

    Da quì poi cerco di comprendere, se riesco il senso...
  • Re: Maschere dinamiche

    @Alex ha scritto:


    Continuo a non capire la logica...
    Perchè non prendi in considerazione una Maschera in visualizzazione CONTINUA invece che singola...?
    @Alex, non la prendo in considerazione perché nel DB originale siamo già una maschera in visualizzazione continua che ha una combobox. I risultati della combo dovrebbero funzionare come la input box del mio esempio.

    Però se tu me la suggerisci forse è perché posso costruire una maschera in visualizzazione continua da un recordset e poi fare altre elaborazioni?
  • Re: Maschere dinamiche

    Se non dici come operi tutto è confuso per noi che non conosciamo lo scenario e magari poniamo domande stupide...

    Se già operi in Continua... la vedo male se non generare una NUOVA maschera CONTINUA ed inserirla come SubForm nel PieDiPagina Maschera, sincronizzarla con la Selezione della Combo...
    In quel modo non avresti bisogno di GENERARE Controlli ma semplicemente di rigenerare la Query di origine della SubForm...
  • Re: Maschere dinamiche

    @Alex, hai perfettamente ragione. Mi spiace di essere confusivo (e confuso) ma non sono un tecnico bensì uno smanettone (te ne sarai accorto... ) e quindi faccio fatica ad esprimermi correttamente.

    Facciamo così, di seguito posto le maschere.

    Questa è la maschera (continua) attuale: l'utente ha inserito le quantità su diverse zone;

    Maschera attuale 1
    Maschera attuale 1

    ora pianifica nuove quantità selezionando prima il tipo di attività.

    Maschera attuale 2
    Maschera attuale 2

    Le zone compaiono nella combobox successiva, dopo una requery, in base all'attività scelta. Infine, l'utente sceglierà la quantità di materiali da assegnare alla zona.

    Maschera attuale 3
    Maschera attuale 3

    Il cliente invece vuole una cosa del genere: sceglie il tipo di attività

    Nuova maschera 1
    Nuova maschera 1

    e poi il sistema gli fa vedere TUTTE le zone associate a quell'attività e una check box per scegliere questa o quella zona.

    Nuova maschera 2
    Nuova maschera 2

    Nota: quello che vedi in queste nuove maschere sono solo label.

    A questo punto, tramite le check box, le quantità di materiali vengono calcolate automaticamente e l'utente può fare altri lavori. Però, come dicevo, qui siamo già in una maschera continua risultato di una query e il numero di zone è ampiamente variabile. Per questo inizialmente avevo previsto due combo collegate (con requery della seconda in base al risultato della prima), ma all'utente questa soluzione non piace.

    Peraltro, il campo "zona" e la relativa check box non saranno associati ad un campo di tabella ma soltanto a variabili a livello di codice, perché il loro contenuto servirà solo per fare altre elaborazioni (calcoli, "giochi" sulle stringhe e varie altre).

    Spero ora sia comprensibile; posso cavarmela in tanti altri modi, ma ovviamente sono aperto come un bambino a qualsiasi soluzione!

    Grazie ancora
    PdS
  • Re: Maschere dinamiche

    Ora è più chiara...
    Ti rendi conto che quello che chiedi è vincolato da una relazione 1-M e che non è gestibile in modo grafico strutturale... se non usabndo una Maschera in visualizzazione continua all'interno di una Maschera in visualizzazione continua... e purtroppo non è possibile.

    Sono certo che anche tu eri già arrivato a questo visto che ora comprendo l'intento di CREARE CONTROLLI...

    ****************************** FAI ATTENZIONE A QUESTO ********************************
    Ora il difetto in generale di questa scelta, ma si riflette su qualsiasi scelta che prevede l'uso di una Maschera Continua, è che SOLO il RECORD CORRENTE potrà rappresentare graficamente bene la scelta da sviluppare... e che tutti gli altri RECORD saranno affetti dalla Formattazione GRAFICA che applichi al Record CORRENTE creando una situazione poco apprezzabile.

    L'idea sarebbe pertanto da rivolgere ad una sorta di FORM di dettaglio sul SINGOLO RECORD che ti consenta di avere una Form SINGOLA con all'interno la form Continua con la selezione delle ZONE.

    Spero di aver centrato l'argomento e chiarito il problema di Visualizzazione che ho cercato di evidenziarti...
  • Re: Maschere dinamiche

    Adesso si, comprendo perfettamente. Nel frattempo ho anche avuto modo di riflettere sulle tue osservazioni, così ho pensato ad una soluzione alternativa.

    Posso fare un compromesso con il cliente sul processo di lavoro (il modo in cui l'utente inserisce i dati) in modo da avere una sottomaschera continua (alimentata dal recordset) all'interno di una maschera singola.

    Visto che messa così mi funziona dal punto di vista logico, adesso il problema è (perché non sono riuscito a farlo): come alimento la maschera continua in modo che vi appaiano TUTTI i record del recordset?

    Ciclo "do while not recordset.eof"?
    Ciclo "for i=0 to numerodeirecorddelrecordset"?

    Grazie ancora
    PdS
  • Re: Maschere dinamiche

    Perchè la maschera continua non la ASSOCI a questo punto...?
  • Re: Maschere dinamiche

    ... ?
    Maschera che si apre con un pulsante?
  • Re: Maschere dinamiche

    Ho capito... se nella maschera SINGOLA metto la combobox, la query che ne deriva la associo alla subform?

    Ma poi, per gestire la selezione si/no come faccio? Se provo ora, come tocco la prima checkbox me le attiva tutte... (vedi immagine). Come si fa?

    NewMask_3.jpg
    NewMask_3.jpg

  • Re: Maschere dinamiche

    Quel Controllo CheckBox deve essere Associato ad un relativo CAMPO Si/No della Tabella...
    Devi sempre tenere in mente quella Evidenza in ROSSO che ti ho fatto... nelle Maschere CONTINUE solo Controlli Associati.
Devi accedere o registrarti per scrivere nel forum
18 risposte