Domanda

Ho una forma in MS Access, che ha un'immagine. L'immagine ha un evento Click che si apre un form modale. Il modulo modale ha un OK e il pulsante Cancel. Quando si fa clic sul pulsante OK, un evento si suppone che il fuoco che dice al modulo principale, che è stato cliccato il pulsante. (Questo è quello di simulare la funzionalità di DialogResult in C #). Tuttavia, il codice nel gestore di eventi non si esaurisce mai.

Il modulo modale ha il seguente nelle dichiarazioni generali:

Public Event OnDialogBoxClose(NewRecordID As Long, DialogResult As DialogResults)

e il seguente codice in cui si fa clic sul pulsante OK:

RaiseEvent OnDialogBoxClose(NewHardwareBaseItemID, dlgresBtnOKClicked)

La principale forma ha il seguente nelle dichiarazioni generali:

Dim WithEvents RespondQuickAddClose As Form_qckfrmHardwareBaseItemCreate

e il seguente gestore di eventi:

Private Sub RespondQuickAddClose_OnDialogBoxClose(NewRecordID As Long, DialogResult As DialogResults)

    MsgBox "Responding to closing of the dialog box" 'Never happens
    Me.Requery

End Sub

Qualcuno può spiegare perché il gestore di eventi non viene mai chiamato? Grazie!

Sfondo:

Lo scopo di tutto questo è quello di consentire una finestra di dialogo modale per aggiungere una voce, per poi tornare l'ID della voce di tornare alla maschera principale per impostare il valore dei controlli. Per esempio, immaginate di compilando un modulo di assicurazione, ed è necessario selezionare una marca di macchina questo non c'è. Si fa clic su un'icona che si apre con la finestra di dialogo modale per consentire di aggiungere il marchio automobilistico. Poi, quando si fa clic su OK, si torna al modulo di assicurazione e di selezionare la marca di auto che si appena creato.

Questo segue un esempio che ho trovato qui: http://database.itags.org/ms-access-database/80292/

È stato utile?

Soluzione

Si sta facendo il vostro modo di vita troppo complicata, applicando i concetti da un ambiente di sviluppo diverso per accedere VBA. Mentre VBA fa WithEvents di supporto / RaiseEvent, non c'è ragione per ottenere che complicato qui.

Il solito modo di lavorare con le finestre di dialogo in Access è che invece di chiuderli, li nasconde. In questo modo il codice dopo la forma era aperto a correre, lasciando i valori nel modulo disponibile per l'utilizzo in quel codice.

Il codice di esempio in caso OnOpen di una relazione che apre un modulo per la raccolta dei valori per filtrare il report:

  Private Sub Report_Open(Cancel As Integer)
    DoCmd.OpenForm "dlgDateRange", , , , , acDialog, "ThisYear"
    If IsLoaded("dlgDateRange") Then
       With Forms!dlgDateRange
         If .Tag = "Cancel" Then
            Cancel = True
         Else
            Me.Filter = "[InvoiceDate] Between #" & !txtStart & "# AND #" & !txtEnd & "#"
            Me.FilterOn = True
            Me!lblDateRange.Caption = StrConv(Trim(("from " + varZLStoNull(Format(!txtStart, "mm/dd/yyyy"))) _
                & (" to " + varZLStoNull(Format(!txtEnd, "mm/dd/yyyy")))), vbProperCase)
         End If
       End With
       DoCmd.Close acForm, "dlgDateRange"
    End If
  End Sub

Il modulo di dialogo ha due pulsanti di comando, CONTINUA >> e annullare. Il ANNULLA gruppi di pulsanti tag del form "Annulla" e imposta la proprietà .Visible del form su False. Il pulsante CONTINUA >> non fa altro che impostare la proprietà .Visible del form su False. Cliccando uno di questi pulsanti consente al codice di proseguire sulla linea dopo che il modulo è aperto con l'interruttore acDialog.

La mia filosofia è quella di rendere le finestre di dialogo stupido come possibile. Il codice chiamante deve sapere quello che sta cercando nelle forme (vale a dire, è necessario conoscere i nomi dei controlli che stai leggendo i dati fuori), ma che potrebbe essere ottenuto intorno con l'aggiunta di proprietà del cliente al form. Ma poi bisogna conoscere i nomi delle proprietà, così hai appena spostato la palla.

Ho anche implementato questo genere di cose avvolgendo la forma dailog in un modulo di classe, e poi il contesto è stata chiamata inizializza semplicemente un'istanza della classe e poi tira i valori fuori di esso al momento opportuno. Ma questo è in realtà più complicato che l'approccio di cui sopra.

Altri suggerimenti

beh io non sono d'accordo a

  

"Mentre VBA fa WithEvents di supporto / RaiseEvent, non c'è alcun motivo per   ottenere che complicato qui ".

Ho lavorato su vari VB6 e progetto VBA. Recentemente ho codificato VBA in Excel, dove ho sollevato un evento da WinForm. Poche cose da considerare quando si fa così.

  1. Se si chiama winform non modale in VBA con WithEvents / RaiseEvent. Dovrebbe funzionare normalmente come previsto. Nessun grande soluzione è necessario
  2. Se si chiama winform modale in VBA. WithEvents / raiseevents may     non funzionare secondo il requisito. Una soluzione rapida è quella di trasferire i dati utilizzando le variabili pubbliche dichiarata nel file del modulo.

Sarà necessario utilizzare la soluzione e credo che funzionerà assolutamente bene.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top