Sincronizzare stato pulsante e aggiornamento maschera

di
Anonimizzato11418
il
12 risposte

Sincronizzare stato pulsante e aggiornamento maschera

Buongiorno,
dopo aver risolto, grazie all'aiuto di Alex, il problema di verifica se una tabella contiene dati mi trovo ora con altri due problemi da risolvere collegati fra loro.
Nella maschera Contatti ho il pulsante che apre la maschera Documenti in forma Add o ReadOnly (in realtà sono due maschere uguali ma con le proprietà impostate diversamente) in funzione del fatto che la tabella corrispondente contenga o meno dati. Questo aspetto è stato risolto facendo la verifica preliminare con il Dcount. La maschera Contatti e la maschera Documenti sono sincronizzate in modo che cambiando il Contatto nella principale cambia anche il record collegato nella Documenti. Può accadere però che scorrendo nei record della maschera contatti si verifichi che la relativa popup sia vuota. A questo punto ho inserito nella maschera popup Documenti un pulsante AggiungiRecord che apre la maschera DocumentiAdd per l'inserimento dei dati (è la maschera popup che si apre se alla verifica del Dcount non ci sono record). I problemi che vorrei risolvere sono:
1.se la maschera non è vuota (ovvero la tabella è popolata) il pulsante AggiungiRecord risulta non visibile e/o non abilitato, diversamente risulta visibile e/o abilitato. E la verifica del cambio di stato deve avvenire ogni volta che si cambia il record Contatti nella maschera principale.
Ho tentato varie soluzioni, cercando di agire nell'evento current della maschera Contatti che gestisce la sincronia. Ma non sono riuscito ad ottenere il risultato.
2. Quando scorro i record della form principale, e incontrando una maschera vuota, se decido di inserire i dati premendo il tasto AggiungiRecord si apre la maschera DocumentiAdd per l'inserimento dei dati. Aggiungo le informazioni che occorrono e salvo. Effettivamente nella tabella collegata i dati risultano inseriti, ma la form Documenti (che è aperta) non si aggiorna con il nuovo record. Potrei forzare la chiusura e riapertura della maschera ma penso che non sia la soluzione giusta, perchè questo evento si verificherebbe anche quando la maschera DocumentiAdd viene aperta alla verifica se la tabella collegata contiene dati o meno.
Spero di aver esposto i due problemi con chiarezza anche se con un po' di prolissità.
Grazie per i validi suggerimenti che date in questo forum.

12 Risposte

  • Re: Sincronizzare stato pulsante e aggiornamento maschera

    Problema 1. Sperando che tu non sia incappato in un dilemma da "botte piena e moglie ubriaca", mi pare che, a questo punto, ti convenga togliere l'impostazione Pulsante AggiungiRecord attivo indipendentemente dalla condizione DCount. Se così è, temo che tutto il discorso sul controllare se tale condizione è Vera o Falsa, non ti interessa più.

    Problema 2. Credo che in Visual Basic il problema si risolva elegantemente con una istruzione, mi pare REQUERY (Alex ti può spiegare meglio).
    In assenza di questo espediente, la strada Chiudi/Riapri è percorribile, se fatta con alcune azioni macro coerenti, funziona.
    Altrimenti, a maschere aperte, puoi utilizzare l'azione ImpostaValore. ImpostaValore avrebbe solo un piccolo difetto: se si tratta di campo casella combinata, potrebbe non visualizzarti subito correttamente il dato, anche se in realtà lo memorizza ugualmente. La correttezza input dato, la verificheresti al successivo chiudi/apri.
    Ho parlato in termini generali, non ho seguito per bene il tuo problema, volendo si può raccontare tutto più dettagliatamente.

    Spero di non aver travisato tutto il discorso.
  • Re: Sincronizzare stato pulsante e aggiornamento maschera

    Confesso di aver avuto le tue stesse perplessità... quindi non mi sento di aggiungere altro se non il suggerimento per [lormac] di chiarire meglio alcuni concetti importanti per le eventuali risposte.
  • Re: Sincronizzare stato pulsante e aggiornamento maschera

    Certo la botte piena e la moglie ubriaca. Potrebbe essere.
    Vediamo un po' se ci sono incappato.
    Questa la sequenza.
    Ho la form Contatti aperta.
    Clicco sul pulsante Documenti
    Interviene il DCount che mi controlla se nella tblDocumenti sono presenti dati.
    Se no: mi apre la frmDocumentiAdd
    Fin qui tutto ok.
    Se si: mi apre la frmDocumenti.
    La frmDocumenti è sincronizzata per mezzo di IDContatto
    Mi sposto nella frmContatti e scorro i record Contatti e contemporaneamente la frmDocumenti si aggiorna in sincronia mostrandomi i Documenti di quel contatto in funzione di IDContatto.
    Accade che incontro il Contatto che non ha Documenti. La maschera è vuota. E questo perchè nella tblDocumenti non esiste il relativo IDContatto.
    Pensavo: se riesco a intercettare questo evento:
    se IDContatto non c'è (ovvero non ho inserito Documenti per quel contatto)
    allora
    rendo il tasto AggiungiRecord disponibile

    Mi è chiaro quello che vorrei fare, ma a questo punto non saprei se posso farlo senza rinunciare al controllo preventivo se la tabella contenga o meno record.
    Penso che mi sto incartando.

    Grazie
  • Re: Sincronizzare stato pulsante e aggiornamento maschera

    Per me ti stai davvero incartando.
    Semplicemente associa ad ogni pulsante l'evento Clic--->ApriMaschera e basta, senza fare controlli DCount o chicchessia. Ce l'hai vuoto--->Aggiungi record. Ce l'hai con almeno un record--->lo guardi alcuni secondi e poi decidi se modificare/aggiungere record oppure chiudere la maschera.
  • Re: Sincronizzare stato pulsante e aggiornamento maschera

    Sta bene.
    Questa soluzione era effettivamente era lo stato iniziale dell'arte. Ma poi volendo migliorare l'usabilità ho iniziato a modificare la struttura del mio piccolo database. Aggiungendo pulsanti, maschere, abilitando e disabilitando controlli e così via.
    Ma vorrei fare un ultimo ragionamento.
    Il controllo preventivo con il DCount avviene solo nell'evento click del pulsante Documenti.
    Poniamo che DCount>0 --> ApriMaschera Documenti
    A questo punto sono aperte le sole due maschere frmContatti e frmDocumenti.
    Quindi:
    visto che le due maschere sono sincronizzate, possibile che l'evento "tbl Vuota" non sia nuovamente intercettabile?
    Ossia:
    Evento1---> mi sono spostato in un altro record nella frmContatti
    Evento2---> la frmDocumenti mi mostra l'eventuale record collegato--->il record c'è--->lo visualizzo (non ho bisogno di altro)
    Evento3---> nella tblDocumenti non c'è un record collegato (certo non c'è IDContatto)
    Evento4---> rendo AggiungiRecord disponibile

    Perchè non posso intercettare Evento3 (e quindi Evento4)?

    Non per insistere, ma per capire.

    Grazie
  • Re: Sincronizzare stato pulsante e aggiornamento maschera

    lormac ha scritto:


    se la maschera non è vuota (ovvero la tabella è popolata) il pulsante AggiungiRecord risulta non visibile e/o non abilitato, diversamente risulta visibile e/o abilitato. E la verifica del cambio di stato deve avvenire ogni volta che si cambia il record Contatti nella maschera principale
    Tu vuoi che accada sempre così. È vero?
    Tieni presente che io so usare le macro e non Visual Basic.
    1) Crea una nuova macro e apri la colonna Condizioni
    2)
    1. Al primo rigo condizioni ci scrivi la sintassi relativa al DCount=0
    2. Al primo rigo Azioni scegli ImpostaValore e sotto scrivi:
    Elemento: [Maschere]![nome maschera]![nome controllo pulsante].[Enabled]
    Espressione: Vero
    3)
    1. Al secondo rigo condizioni scrivi la sintassi relativa al DCount>0
    2. Al secondo rigo condizioni scegli ImpostaValore e sotto scrivi:
    Elemento: [Maschere]![nome maschera]![nome controllo pulsante].[Enabled]
    Espressione: Falso
    4) Salva la macro con nome "AbilitaAggiungiRecord"
    5) Vai in visualizzazione struttura maschera (adesso non ricordo più quale) e, all'evento "Su corrente" associa la macro AbilitaAggiungiRecord

    Fai molta attenzione alle sintassi "punto esclamativo" per separare maschere e controlli, "punto" per fare riferimento a una proprietà.
  • Re: Sincronizzare stato pulsante e aggiornamento maschera

    Grazie.
    Ci proverò anche se le Macro le mastico male. Trovo VBA più comprensibile.

    Tuttavia la soluzione suggerita non equivale a scrivere in VBA nell'evento current della frmDocumenti:
    Dim CRITERIO As String
    CRITERIO = "[IDContatto]=" & Me![IDContatto]
    If DCount("*", "tblDocumentiContatto", CRITERIO) = 0 Then
        Me.cmdAddNew.Enabled = True
        Else
        Me.cmdAddNew.Enabled = False
        End If
  • Re: Sincronizzare stato pulsante e aggiornamento maschera

    lormac ha scritto:


    la soluzione suggerita non equivale a scrivere in VBA nell'evento current della frmDocumenti
    Concettualmente non sono d'accordo. Se proprio tu hai chiesto un controllo "ad ogni cambio di record", solo l'evento Su corrente può garantirlo. Non posso contestare il codice VBA perchè non conosco la corretta sintassi, ma il mio ragionamento credo che sia coerente.
  • Re: Sincronizzare stato pulsante e aggiornamento maschera

    Al di là della corretezza del codice.
    Penso che stiamo parlando della stessa cosa. E infatti avevo fatto lo stesso ragionamento.
    Il codice o la macro deve stare nell'evento su corrente della frmDocumenti (ovvero la form in cui il cmdAggiungi è situato)
    Tuttavia:
    il codice non mi funziona (sicuramente vi è un errore di sintassi o interpretazione)
    la macro non mi funziona (e sicuramente ho sbagliato la sintassi nell'Espressione in Condizioni. Ma avevo anticipato che le mastico davvero male).
    Di seguito quello che ho scritto:

    Condizione 1

    DCount([tblDocumenti]![IDContatto];[tblDocumenti])=0
    Azione--> ImpostaValore
    [Maschere]![frmDocumenti]![cmdAggiungiRecord].[Enabled]
    Vero

    Condizione2

    DCount([tblDocumenti]![ContactID];[tblDocumenti])>0
    Azione--> ImpostaValore
    [Maschere]![frmDocumenti]![cmdAggiungiRecord].[Enabled]
    Falso

    Ma vi è di più. Poichè l'evento suCorrente è già occupato da una routine Evento, mi trovo nella condizione di scegliere Macro o VBA.
    Però: se posso farlo con le macro, posso farlo anche con VBA. Giusto?
  • Re: Sincronizzare stato pulsante e aggiornamento maschera

    Ciò che si può fare con macro si può sempre tradurre in VBA.
    Se hai già una routine evento a Su corrente, dovresti fare in modo che tutta la routine faccia più controlli, quindi anche quella sulla proprietà Enabled del pulsante. Dovrai rivedere tutto il ciclo di controlli ecc...ecc...
    Attento alla sintassi DCount, io ricordo che ha 3 argomenti separati da ; poi credo che andrebbe scritta così (almeno nelle macro, non so in VBA):
    DCount("*";"tblDocumenti";"")=0
  • Re: Sincronizzare stato pulsante e aggiornamento maschera

    Grazie per tutte le risposte.
    Anche se avrei bisogno di farlo da codice (visto che ho altre istruzioni nell evento su Corrente), ho corretto la sintassi come suggerito per vedere se la macro comunque funziona.
    Ma c'è qualcosa che non quadra. Ora non so se perchè ho impostato male le condizioni della macro. Ma ho seguito quanto suggerito da OsvaldoLaviosa
    Attento alla sintassi DCount, io ricordo che ha 3 argomenti separati da ; poi credo che andrebbe scritta così (almeno nelle macro, non so in VBA):
    DCount("*";"tblDocumenti";"")=0
    e
    1) Crea una nuova macro e apri la colonna Condizioni
    2)
    1. Al primo rigo condizioni ci scrivi la sintassi relativa al DCount=0
    2. Al primo rigo Azioni scegli ImpostaValore e sotto scrivi:
    Elemento: [Maschere]![nome maschera]![nome controllo pulsante].[Enabled]
    Espressione: Vero
    3)
    1. Al secondo rigo condizioni scrivi la sintassi relativa al DCount>0
    2. Al secondo rigo condizioni scegli ImpostaValore e sotto scrivi:
    Elemento: [Maschere]![nome maschera]![nome controllo pulsante].[Enabled]
    Espressione: Falso
    4) Salva la macro con nome "AbilitaAggiungiRecord"
    5) Vai in visualizzazione struttura maschera (adesso non ricordo più quale) e, all'evento "Su corrente" associa la macro AbilitaAggiungiRecord
    Per completezza posto anche i pezzi di codice che accadono nella sequenza degli eventi. Magari può servire a risolvere il problema.

    La frmDocumenti viene aperta dall'evento click del cmdDocumenti nella frmContatti:
    questo il codice del button (ho modificato una routine che avevo trovato in un libro):
    Private Sub cmdDocumentiContatto_Click()
    'Messaggio preliminare per richiedere se si vuole o no aprire la maschera documenti contatto
    If MsgBox("Visualizzare la maschera DOCUMENTI CONTATTO?", vbYesNo + vbQuestion + vbDefaultButton2, AppTitle) = vbYes Then
    'ho scelto YES ed esegue la routine di apertura della maschera sincronizzandosi con IDContatto
    On Error GoTo Err_cmdDocumentiContatto_Click
    Dim frmName As String
    Dim frmName1 As String
    Dim Criterio As String
    frmName = "frmDocumenti"
    frmName1 = "frmDocumentiAdd"
    Criterio = "[IDContatto]=" & Me![IDContatto]
    'Controllo preliminare per verificare se nella tabella tblDocumenti esistono dati
    '*********************questo è l'esempio***********************************
    'IF DCOUNT("*","NomeTabella","CRITERIO se serve")>0 Then
    'Docmd.OpenForm "NomeForm"
    'Else
    'MsgBox "Non ci sono Record"
    'End If
    '******************************************************************************
    If DCount("*", "tblDocumenti", Criterio) > 0 Then
    'se la tabella contiene dati allora apre la frmDocumenti
    DoCmd.OpenForm frmName, , , Criterio
    Else
    'diversamente avvisa che non ci sono record e se si vogliono aggiungere dati
    If MsgBox("Non esistono DOCUMENTI CONTATTO. Vuoi Aggiungere?", vbYesNo + vbQuestion + vbDefaultButton2, AppTitle) = vbYes Then
    'in caso affermativo apre la frmDocumentiAdd
    DoCmd.OpenForm frmName1, , , Criterio, acFormAdd, acDialog
    End If
    End If
    Exit_cmdDocumentiContatto_Click:
    Exit Sub
    Err_cmdDocumentiContatto_Click:
     MsgBox Err.Description
     Resume Exit_cmdDocumentiContatto_Click
     Exit Sub
    'ho scelto NO: semplicemente esce dalla sub
    Else
    Exit Sub
    End If
    End Sub
    La frmDocumenti si apre e nell'evento open ho:
    Private Sub Form_Open(Cancel As Integer)
    'imposta IDContatto corrente come predefinito nella maschera frmDocumenti
    If Aperta("frmContatti") Then
    IDContatto.DefaultValue = Forms!frmContatti!IDContatto
    End If
    'blocca e disabilita tutti i controlli della maschera
    Dim ctl As Variant
    On Error Resume Next
    For Each ctl In Me.Controls
    If ctl.Enabled = True Then ctl.Enabled = False
    If ctl.Locked = False Then ctl.Locked = True
    Next ctl
    'e setta i cmd da tenere abilitati
    Me.cmdClose.Enabled = True
    Me.cmdModifica.Enabled = True
    Me.cmdAddNew.Enabled = True
    End Sub
    nell'evento Current della frmContatti (la maschera principale) ho:
    'sincronizza frmDocumenti e frmContatti
    'mediante un filtro su IDContatto
    'utilizza funzione Aperta settata nel Modulo Varie
    If Aperta("frmDocumenti") Then
    Forms!frmDocumenti.Filter = "IDContatto = " & Nz(IDContatto, 0)
    End If
    mentre nell'evento current della frmDocumenti ho alcune istruzioni sulla visibilità di controlli in funzione della scelta di una combo box, che credo sia ininfluente ai fini della soluzione del problema posto.

    Altra informazione utile è che la frmDocumenti ha le proprietà Immissione Dati,Consenti Aggiunte, Consenti Eliminazioni, Consenti Modifiche e Consenti Filtri impostate a no.

    Va segnalato che i codici postati non sono farina del mio sacco ma solo il riadattamento alle mie esigenze di codici trovati nella guida, in alcuni libri e nel web.

    Sicuramente esistono soluzioni stilisticamente più corrette e lineari, ma visto che tutto quanto ho postato funziona mi accontento visto che non devo costruire un applicativo per qualcuno ma semplicemente per me stesso.
    E allora adotterò la soluzione proposta da OsvaldoLaviosa:
    Semplicemente associa ad ogni pulsante l'evento Clic--->ApriMaschera e basta, senza fare controlli DCount o chicchessia. Ce l'hai vuoto--->Aggiungi record. Ce l'hai con almeno un record--->lo guardi alcuni secondi e poi decidi se modificare/aggiungere record oppure chiudere la maschera
    Anche se non era quello che avrei voluto fare e che purtroppo le mie scarse conoscenze di VBA non mi consentono di andare oltre.

    Grazie per il tempo e l'attenzione dedicata.
  • Re: Sincronizzare stato pulsante e aggiornamento maschera

    Mi rispondo da solo.
    La convinzione di poterlo fare era troppo forte mi sono dato un'altro paio di giorni per analizzare la questione. Finché dopo il caffè del pranzo BLINK!! si è accesa la lampadina e la luce mi ha illuminato la strada.
    Ci ero vicino, molto vicino, ma sbagliavo l'approccio.
    Riassumendo: l'evento che gestisce la sincronia delle maschere sta nell'evento Su corrente della frmContatti. Ed è qui che dovevo intervenire. OsvaldoLaviosa lo aveva detto:
    5) Vai in visualizzazione struttura maschera (adesso non ricordo più quale) e, all'evento "Su corrente" associa la macro AbilitaAggiungiRecord

    ma io insistevo nel lavorare sugli eventi della frmDocumenti, cioè nella form popup che si apre con il cmdDocumenti.
    Ho sbagliato nel non chiedere a quale frm si riferisse OsvaldoLaviosa, perchè il problema sarebbe stato risolto due giorni fa, ma per lo meno ho imparato qualcosa, anche se di piccola entità.
    A questo punto è bastato inserire in Current:
        Dim Criterio As String
        Criterio = "[ContactID]=" & Me![ContactID]
        If DCount("*", "tlkpDocumeenti", Criterio) = 0 Then
    Et voilà, che il cmdAddNew si abilita/disabilità in funzione della presenza di record nella tblDocumenti.

    Un grazie a tutti per avermi indirizzato sulla strada giusta.
Devi accedere o registrarti per scrivere nel forum
12 risposte