2010-04-13 5 views
5

Ho un modulo principale con un controllo struttura a schede che contiene più sottomaschere. Devo essere sicuro che i dati in una sottomaschera vengano salvati quando l'utente cambia scheda. Il problema è che DoCmd.RunCommand acCmdSaveRecord sembra si applica solo al modulo corrente in modo che non salvi i dati nella sottomaschera.Accesso Ms Salva record nella sottomaschera

Ho provato diversi eventi nella sottomaschera come disattivato, OnLostFocus ecc. Ma non si attivano finché non viene messo a fuoco un altro campo da qualche altra parte.

La soluzione ideale sembra essere quella di mettere qualcosa nell'evento OnChange del controllo struttura a schede per essere sicuri che tutti i dati vengano salvati. Questa è la mia domanda, come faccio a salvare il record in una sottomaschera?

risposta

2

In Access, l'impostazione predefinita è di salvare, quindi, a meno che non si sia fatto qualcosa di abbastanza complicato per impedirlo, spostando lo stato attivo da una sottomaschera si salverà automaticamente il record. È possibile verificare ciò aggiungendo un record, spostandosi dalla sottomaschera e quindi controllando la tabella.

+0

Ho trovato una soluzione. Devo eseguire un codice per aggiornare altri campi quando alcuni dati vengono modificati. Quello che stava succedendo era che non sparava quando doveva ... Grazie per l'input! – Icode4food

+0

Per questo è possibile considerare gli eventi LostFocus dei controlli della sottomaschera. –

1

Non è necessario eseguire alcuna operazione, poiché la sottomaschera viene salvata non appena perde lo stato attivo (quando il controllo Struttura a schede cambia).

Ma come esercizio, ho delineato il codice che avresti scritto se avessi avuto bisogno.

È possibile salvare qualsiasi modulo impostando la proprietà .Dirty su False. Per qualcosa del genere che girerà molto, penso che scriverò un sottotitolo per esaminare le sottomaschere, controllare se sono sporche e salvare quelle sporche. Qualcosa di simile a questo:

Public Sub SaveSubFormsOnTab() 
    Dim pge As Control 
    Dim ctl As Control 

    For Each pge In Me!ctlTab.Pages 
     Debug.Print pge.Name 
     For Each ctl In pge.Controls 
     If ctl.ControlType = acSubform Then 
      If ctl.Form.Dirty Then 
       ctl.Form.Dirty = False 
      End If 
      Debug.Print ctl.Name 
     End If 
     Next ctl 
    Next pge 
    Set ctl = Nothing 
    Set pge = Nothing 
    End Sub 

Ora, che in realtà è abbastanza inefficiente nei casi in cui si hanno un sacco di controlli del controllo di scheda che non sono sottomoduli. Se la tua scheda non ha altro che sottomodifiche, sarà abbastanza efficiente. In entrambi i casi, è molto più efficiente utilizzare una raccolta personalizzata popolata nell'evento OnLoad del modulo e quindi si varca quella raccolta che non include nient'altro che le sottomodifiche del controllo struttura a schede e salva quelle che sono sporche.

Uno di questi è preferibile utilizzare l'evento OnChange della scheda, poiché ogni volta che si aggiunge una scheda con una sottomaschera o si modifica il nome di un controllo di sottomaschera, è necessario modificare l'evento OnChange.

-2

L'impostazione della proprietà dirty su false può forzare Access a salvare i dati nel database, ma ignora l'evento before_update. Ciò significa che se hai utilizzato questo evento per la convalida o per altri scopi, ora puoi avere dati non validi nel tuo database.

+2

Questo non è vero - gli eventi di aggiornamento del FORM sparano (ho appena testato). Tuttavia, gli eventi dei singoli controlli non necessariamente sparano (perché non saranno attivati ​​semplicemente salvando il record). –

0

Avevo un problema simile in cui avevo bisogno di vari codice da eseguire nella sottomaschera e i valori nel modulo principale, basati sui valori nella sottomaschera, da ricalcolare. Ecco cosa ha funzionato alla fine:

Questo è un esempio con un modulo principale denominato "frmCustomers" contenente una sottomaschera "sfmTransaction", che a sua volta ha una sottomaschera chiamata "sfmOrderLine". I moduli hanno un pulsante 'cmdSave' che è visibile solo quando l'utente fa clic sul pulsante 'cmdEdit' (il cui scopo è bloccare tutti i controlli finché l'utente non fa clic sul pulsante di modifica e quindi bloccarli nuovamente quando fa clic salva):

Sul modulo ('frmCustomer') passa all'evento di uscita della sottomaschera e aggiunge 'me.recalc' due volte, in questo modo:

Private Sub sfmTransaction_Exit(Cancel As Integer) 
    If (Not Form_sfmTransaction.NewRecord And Form_sfmTransaction.cmdSave.Visible) Or (Not Form_sfmOrderLine.NewRecord And Form_sfmOrderLine.cmdSave.Visible) Then 
     'To save subforms 
     Me.Recalc 
     Me.Recalc 
    End If 
End Sub 

Nel subform ('sfmTransaction') go subform evento di uscita per la sottomaschera, e aggiungere 'me.recalc' due volte, in questo modo:

Private Sub sfmOrderLine_Exit(Cancel As Integer) 
    If Not Form_sfmOrderLine.NewRecord And Form_sfmOrderLine.cmdSave.Visible Then 
     'To save subform 
     Me.Recalc 
     Me.Recalc 
    End If 
End Sub 

Spero che questo aiuti.