Newsgroup: it.comp.appl.access
Titolo: Riferimento ad una Seconda Sottomaschera

Ad una Maschera con Sottomaschera(Mask1 e Mask2), 
ho aggiunto una piccola Sottomaschera con poche info,(Mask3).
 
A questo punto devo fare riferimento a quest'ultima Mask3 per aggiornarla attraverso l'evento Corrente della Sottomaschera(Mask2) 
 
Ma non posso rifermi ad essa con Me. (Poiché semmai fa parte di Parent)
Non la trova con l'espressione me!Parent.....
Non la trova con l'espressione: Forms!Mask3!NomeControllo
Non la trova con l'espressione: Forms!Mask3.form!NomeControllo
.... come devo riferirmi a Mask3?
 


La premessa è che quello che fai pur fattibile è tecnicamente meglio evitarlo, ogni Oggetto dovrebbe essere INDIPENDENTE e si deve evitare di fare rimandi in giro per le SubForm.
Ci sono tecniche di programmazione che consentono di ACCENTRARE il coordinamento degli EVENTI delle SubForm nella Form e da li poi si gestisce il codice completo.
Questo rende il tuo codice più ROBUSTO e riutilizzabile...!
 
In ogni caso devi ragionare sugli OGGETTI e sul loro MODELLO.
Una Maschera contiene Controlli inseriti nella Collection CONTROLS.
   Me.Controls("NomeTextBox").Value
   Me.Controls("NomeSubForm")    <---- Attenzione a questo
Equivale a 
   Me!NomeSubForm
 
Il 2° esempio che ti ho fatto punta non esplicitamente all'Oggetto Form ma al suo Container che appunto è un Oggetto SubForm e può avere NOME differente dalla Form usata come SubForm.
Se la Form si chiama Mask3 il riferimento al Controllo di tipo SubForm può Chiamarsi PIPPO.
QUindi il container si CHiama pippo il suo Contenuto o Oggetto Form si chiama Mask3:
 
Me!
Pippo.Form.Name
 <---- Ottieni Mask3
 
Quindi per far riferimento alla Form di cui l'Oggetto SubForm è riferimento si fa così:
 
Me.Controls("NomeSubFormContainer").Form 
Me!ContainerMask3.Form
 
Ora se dalla Mask2(SubForm della MaskPadre) devi arrivare alla Mask3 hai diverse sintassi fruibili:
 
Forms("MaskPadre")!ContainerMask3.Form.NomeControllo.Value
Me.Parent.ContainerMask3.Form.NomeCOntrollo.Value
 
Dicevo sopra che l'Oggetto Container di tipo SubForm che contiene il vero Oggetto Form, può avere un Nome diverso dalla Form(Mask3), e tu in quel modo NON SARAI mai in grado di rggiungerlo in quanto non sai come si chiama... ed è anche per questo che si dovrebbe evitare.
Per ricavare dalla SubForm il Nome Del Container(Controllo nella Parent) si fa così:
 
Dim ctl As Access.Control
For each ctl in Me.Parent.Controls
   If ctl.ControlType=acSubForm then
       If ctl.Form is Me then MsgBox "IO SONO IL CONTAINER " & ctl.Name
   End if
Next  
 
Per ovviare a questo solitamente si programma, in modo un po avanzato si definisce una Public Property ti tipo Stringa nelle SubForm che corrisponde al Nome del Container, in questo modo puoi facilmente scalare BottomUP il riferimento.
 
Lo so che ti ho fatto più confusione di prima... ma con calma rileggiti questa spiegazione e vedrai che, entrando nella logica ad Oggetti di Access prende un senso...
 
@Alex

In ogni caso per abbracciare vari casi che ti servono per capire leggi questo:
 
http://access.mvps.org/access/forms/frm0031.htm
 
 
@Alex


Ciao Alex.
Premessa. Aldilà dei discorsi prettamente pratici, ci sono termini e concetti che pur arrivando a comprendere asetticamente ed intuitivamente, non li capisco fino in fondo poiché non ne ho riscontro nell’esperienza. Sono i concetti come “…evitare di fare rimandi in giro per le SubForm”. Perché no? Cosa accade?... Il termine ROBUSTO, lo capisco, ma cosa accade quando non lo è? Access certamente ci vizia. Il fatto che funzioni… ci vizia.   Termini come Riutilizzabile: in che senso? 
Non ho esperienze di “guai” relativi ai rimandi in giro per le subform, non mi sono mai maledetto per quel codice “debole” che ho sviluppato: una volta che funziona, funziona a vita. Per cui nella pratica, quali sono quei casi in cui il codice scritto è debole e sono guai?... 
Nei contenuti veri e propri entro domani.
Intanto infinite grazie! :-)

Le regole della programmazione sono concettuali e non troverai mai un abecedario con l'elenco..., sono regole di buona tecnica che poerò partono da concetti di teoria applicata, e si comprendono con l'esperienza operativa.
Di norma chi sviluppa MOLTE applicazioni e non solo il la gestione delle spese domestiche di casa propria, vuole/deve ottimizzare Tempo e Risorse.
Questi sono 2 concetti che forzano a ragionare prima di buttar giù codice a KG.
Quindi si creano Maschere, Report e Codice che può essere riutilizzato in molti lavori con un MINIMO di adattamento, senza così dover riscrivere da zero tutto.
Chiaro che per chi fa 3 maschere il concetto è poco "pratico" ma per chi realizza applicativi gestionali che magari spaziano su decine di Clienti con centinaia  di Maschere e Report, con oltre 20000 Righe di codice... la cosa inizia ad avere senso.
 
Quindi se ragioni in modo tecnico, vedi che una Form usata come SubForm potrebbe essere usata più di 1 Volta, ma se dentro ci metti codice che la vincola ad essere usata SOLO come SubForm della Mask1 e legata alla Mask2, non potrai riusarla in alcun modo, ma ti toccherà CLONARLA... moltiplicando inutilmente oggetti e codice.
 
Quindi solo rendendo gli OGGETTI INDIPENDENTI ma in grado di scambiare Eventi, Proprietà e Metodi potrai avere questa flessibilità.
 
Di fatto la programmazione ad Oggetti funziona proprio così, si Chiama OOP, Object-Oriented-Programming.
Ovviamente la stessa cosa si applica a Funzioni e Sub e Report e Query...
 
Tu dici se una cosa Funziona, Funziona per sempre...? Illuso ti dico io.
Se inizi ad avere Applicativi fruiti da decine di utenti, con una complessità discreta, pensare di NON aver introdotto BUGS o ERRORI è pura follia, non la chiamo arroganza perchè questa richiederebbe conoscenza, ma più inconsapevolezza per ignoranza.
Ora pensa di cercare un BACO in in un sistema, questo chiede tempo sapendo che non porterai a casa 1€, quindi se il tuo prodotto è flessibile, lo hai usato su molti clienti ed anche il BACO viene ammortizzato, altrimenti i BACHI da cercare sono N se ogni cliente ha un prodotto completamente CUSTOM.
 
Ecc.. ecc... ecc... meno male che è arrivato il WE.
 
Saluti
@Alex

Marco explained :

[Mask3].Form![ControlName]
 
Bruno

Il giorno giovedì 19 aprile 2018 19:54:01 UTC+2, @Alex ha scritto:

Ciao Alex.
Grazie per la tua accurata risposta.
Sto facendo qualche esperimento tra quelli da te citati ma ancora la cosa non mi è del tutto chiara, infatti non sono riuscito ancora a puntare su quella maschera, dopo mille tentativi.  
Nel frat-tempo, (tra l'altro poco a mia disposizione) il tempo stringe.
Quindi ho pensato di ovviare rinunciando ad alcuni pulsanti della famosa Maschera3, quindi eliminarla e puntare direttamente a una ListBox. Tutto bene: la listbox si aggiorna dopo il comando Requery lanciato dalla SubForm2. Il problema è che, non so come, ma la "Requery" la riceve anche la mia SubForm2 col risultato che ad ogni Requery di ListBox,la mia Subform2 si sposta al primo record.  Perchè? E come evitare questo fastidiosissimo inconveniente?
Spero di essermi spiegato. (La mia ListBox ha come origine Riga una query su una TabellaArticoli e va in Sincro con SubForm2 avendo messo sul campo ARTICOLO della query un Filtro: Forms!SubForm2!Articolo)


Risulta complesso dare un suggerimento sulla causa in quanto non vedo come operi in modo concreto.
Se esegui il REQUERY sul SOLO controllo ListBox non deve eseguire il Requery della SubForm... in teoria se fatto correttamente... ma ci sono diversi aspetti da valutare che a parole però risulta complesso in quanto io do per scontate cose che invece proprio scontate non sono per te e viceversa...
 
Come ti dicevo io opterei per rilanciare gli Eventi nella Form principale e da li poi gestire le azioni in modo più organizzato.
 
Solo a titolo di spiegazione della teoria espongo 2 modi con i quali si può operare:
 
1) Predisporre nella Form 1 o più Public Function/Sub(io uso Function per restituire l'esito) e dalla SubForm poi si chiama la Function.
Esempio:
Nella Form scrivo:
Public Function EseguiAggiornamento(ObjCaller as Object) As Boolan
   On Error bla bla....
   Select Case ObjCaller
      Case Is Me!NomeSubForm1.Form
         ' Esegui Sequenza 1....
      Case Is Me!NomeSubForm2.Form
         ' Esegui Sequenza 2....
      Case Is Me!NomeListBox
         ' Esegui Sequenza 3....
   End Select
   EseguiAggiornamento=true
Exit_Here:
   Exit Function
Err_Handler
   ....
   Resume Exit_Here
End Function
 
Dalla SubForm la richiami così:
Dim retVal  As Boolean
retVal=Me.Parent.Form.EseguiAggiornamento(Me)
 
2) Altrimenti, un poco più complicato, ma io lo preferisco,... è questo, sempre nella Form(Parent):
 
Option Compare Database
Option Explicit
 
Private WithEvents sf1   As Form_NomeSubForm1
 
Private Sub Form_Load()
    Set sf = Me.ChoseColor.Form
End Sub
 
Ora l'oggetto [sf] può ereditare gli Eventi di SubForm Predisposti.
 
Quindi nella SubForm ad esempio gestirai:
 
Option Compare Database
Option Explicit
 
Public Event CallRequery(ObjCaller As Object, Result As Boolean)
 
Private Test_Click()
  Dim retVal As Boolean
  RaiseEvent CallRequery(Me, retVal)
End Sub
 
Saluti
 
@Alex


ok....E con questo mi sono impegnato per le prossime settimane! Mia moglie mi lascerà! Lo so :-) 
Il secondo esempio l'ho capito meno. Il primo è molto bello!!
Parent gestisce tutto asseconda di chi "si muove"


Cmq...Per andare sul concreto: 
ti chiedevi quale fosse il contesto in cui mi muovevo in questa determinata circostanza... Una banalissima riga di codice.
Dopo Aggiornamento del campo ARTICOLO in SubForm2:
 
  Me.Parent!Storico.Requery
 
E non capisco perchè SubForm2 si sposti sul record 1 (tipico comportamento della requery) ...proprio mentre l'eventuale operatore sta compilando i records. Fastidiosissimo!
Almeno mi puoi dire come fare in modo che dopo la requery
torni ad essere Corrente, il record appena abbandonato?
Ho provato alcune righe con la proprietà BookMark ma non ne vuole sapere. :-)


Quì trovi la soluzione al solo problema del Riposizionamento del Record:
http://www.donkarl.com/it?FAQ4.5
 
 
Tuttavia non è la tua soluzione... che deve essere assolutamente trovata per evitare continui aggiornamenti non necessari.
 
@Alex