Instanced Forms Disappearing / Drop-down based MsgBox

Dunro

New member
Local time
Today, 10:07
Joined
Oct 22, 2013
Messages
5
Hi!

I'm trying to create a drop-down based Msgbox/Inputbox-like form for general purposes. When I try to modify the events using CreateEventProc / InsertLines, all of my instanced forms close abruptly.

I've tried this with both a form copied by CopyObject as well as with a new form created by CreateForm. Similar result.

The closest thread I found to this is at showthread.php?t=254881

A modified version of my code is below (it does reference the copied form's initialization function...)

Code:
Private Sub cmdReplace_Click()
    Dim pTempFormName As String
    Dim pInstanceNum As String
    Dim mdl As Module, lineNum As Long

    Const cnsModuleName = "cmdReplace_ClickOld"
    Dim testObj As Object
    
    pInstanceNum = Format(Now(), "yyyymmddhhmmss")
    pTempFormName = "TEMP " & pInstanceNum & " Question"
    
    On Error Resume Next
' Attempt to open the form... This should fail.
    Set testObj = CurrentProject.AllForms(pTempFormName)
    If Err.Number = 2467 Then
    ' Creates form, but does not open it yet.
        On Error GoTo Exit_Error
        DoCmd.CopyObject NewName:=pTempFormName, SourceObjectType:=acForm, SourceObjectName:="Form Question"
        DoEvents
        DoCmd.OpenForm formName:=pTempFormName, View:=acDesign, WindowMode:=acHidden
        
    ElseIf Err.Number <> 0 Then
       ' ... debug code for other errors go here eventually.
    Else
        DoCmd.OpenForm formName:=pTempFormName, View:=acDesign, WindowMode:=acHidden
        
    End If

     Set mdl = Forms(pTempFormName).Module
     lineNum = mdl.CreateEventProc(EventName:="Click", objectname:="cmdOK")
     If lineNum > 0 Then
         lineNum = lineNum + 1
         mdl.InsertLines Line:=lineNum, String:="Call pResultGoto.cmdReplace_ClickPT2(documentID:=" & Nz(Me.Controls("txtID").Value, 0) & ",replacementType:=Me.cboAnswer.value)"
         ' mdl.InsertLines Line:=lineNum, String:="Msgbox ""Test.""" ' this code works, but Instanced forms still disappear.

     End If
    
    DoCmd.Close objectType:=acForm, objectname:=pTempFormName, Save:=acSaveYes

    If tempCollection Is Nothing Then: Set tempCollection = New Collection
    DoCmd.OpenForm formName:=pTempFormName

    If childInstanceFrms Is Nothing Then: Set childInstanceFrms = New Collection
    Call Forms(pTempFormName).init(parentInstanceCollection:=childInstanceFrms, visible:=True, question:="Why is this document being replaced?", resultGoTo:=Me)
        
    Forms(pTempFormName).cboAnswer.RowSourceType = "Value List"
    
    Forms(pTempFormName).cboAnswer.AddItem "1;Original uploaded in error."
    Forms(pTempFormName).cboAnswer.AddItem "2;Original draft revised on the same date."
    Forms(pTempFormName).cboAnswer.AddItem "3;Attached document was revised on a different date."

End Sub

When this code is run, the form is created/modified successfully, but all currently instanced forms close abruptly. (Which is half of the application! :banghead:)

Is this due to compilation issues (or something else that should be obvious)?

Any alternatives that would be more user friendly than a msgbox or inputbox?

Thanks in advance.

- Dunro
 
There is an inalienable rule that a design is wrong if it requires anything that cannot be performed in a complied version of the database (mde or accde). Code cannot be modified under these circumstances and hence it is clear that you are doing this the wrong way.

All possible code outcomes should already be in the module and their execution handled through variables and conditional processing (If,Then,Else or Select Case).
 
Can you suggest an alternative method for value-list based user input? I'd rather not be maintaining a(nother) form simply for this one purpose. :)
 
Obviously the outcomes are hard coded and there's an if/else involved down the line, but I know I will need this kind of user input again later and would rather extend from the same base.
 
From what I have seen so far the requirement should be data driven.

Small demo attached.

Chris.
 

Attachments

I am trying to create (or find...) something generic that can be called in place of a msgbox or inputbox. It could certainly be table driven, but I don't want to maintain a different pop-up form for every variation of this function.

The pop-up should obtain the user input and pass it back to the caller for processing. I'm looking for an input method that uses a drop-down list of values rather than Yes/No/Cancel or Text input.

The initial use for said user dialog is as follows, but I could offer other uses that wouldn't fit this model:

I have a continuous subform listing files which are associated with a record. I'm adding a small "replace" button beside each file in the list. Replace happens so rarely that it doesn't make sense to have the "reason" dropdown on the subform itself.

When the user clicks the replace button, a dialog pops up to ask why they wish to replace the document. For 2 of the 3 reasons, the caller would determine that the document can be replaced and the reason number is included as part of that function. The 3rd reason is not permitted, and the caller would provide the user feedback.
 
Thanks everyone for your input.

Finally found the solution I was looking for.

Unfortunately, it requires an API call for Sleep to work, but otherwise, it does what I originally wanted.

Revised code below:

Code:
Private Sub cmdReplace_Click()
    Dim newForm As [Form_Form Question], replacementType As Long
    Dim documentID As Long
    Dim parentForm As Form   


    
    documentID = Nz(Me.Controls("txtID").Value, 0)
    
    If documentID = 0 Then: Err.Raise Number:=99, Description:="DocumentID not passed.  Developer config required."
    
    If TypeOf Me.parent.Form Is [Form_Case Linking FD] Then
        ' The Upload document button/function is unfortunately always on the parent form.
        ' We must know that form already has an upload document function.       
        Set parentForm = Me.parent.Form
    Else
        Err.Raise Number:=99, Description:="This subform doesn't recognize its parent.  Developer config required."
    End If
    
   
    ' start new blank drop down input popup
    Set newForm = new [Form_Form Question]

    ' Customize Dialog before displaying.
    newForm.lblQuestion.Caption = "Why is this document being replaced?"
    
    ' Set up the list of possible responses.  No reason why this can't be based off a table.
    newForm.cboAnswer.RowSourceType = "Value List"
    newForm.cboAnswer.AddItem "1;Original uploaded in error."
    newForm.cboAnswer.AddItem "2;Original draft revised on the same date."
    newForm.cboAnswer.AddItem "3;Attached document was revised on a different date."
    
    ' display form and wait for response
    On Error Resume Next
    replacementType = newForm.ShowModal()
    Set newForm = Nothing ' remove reference to closed form.
    On Error GoTo Exit_Error
    
    If replacementType = 0 Then ' cancelled
        ' do nothing
    ElseIf replacementType = 1 Or replacementType = 2 Then ' user is using correct function.
    
        Call parentForm.UploadDocument(documentID:=documentID)
        ' The Upload document button/function is unfortunately always on the parent form.  We've already verified that parentForm is correct form type.

        
    ElseIf replacementType = 3 Then ' user is attempting to use function incorrectly.
        If MsgBox("This falls under a 'new version' rather than a replacement. Would you like to upload the document anyway?", vbYesNoCancel) = vbYes Then
            Call parentForm.UploadDocument ' Display regular dialog
        Else
            ' cancelled or No.  Do nothing.
        End If
    Else ' something unexpected came back from the popup.
        Err.Raise Number:=99, Description:="User input invalid.  Badly configured popup form."
    
    End If
    
Exit Sub

Exit_Error:
'        Calls ErrorCatcher and various debug
    
End Sub

My template "Form Question" has the following:
Code:
Private m_Result As Long
#If VBA7 Then ' Win API Declarations for 32 and 64 bit versions of Office 2010 and later
  Private Declare PtrSafe Sub Sleep Lib "Kernel32" (ByVal dwMilliseconds As Long)
#Else ' WIN API Declarations for Office 2007
  Private Declare Sub Sleep Lib "Kernel32" (ByVal dwMilliseconds As Long)
#End If
Public Function ShowModal() As Long
    Me.visible = True
    Me.Modal = True
    
    ' Wait until the form becomes hidden (user clicked a button)
    On Error GoTo Forced_Closed
    m_Result = -1
    Do While m_Result = -1
        DoEvents
        Sleep 50
    Loop
    
    ' Return the result
Forced_Closed:
    Me.Modal = False
    ShowModal = m_Result
    
End Function

Private Sub cmdCancel_Click()
    m_Result = 0
End Sub

Private Sub cmdOK_Click()
    m_Result = Me.cboAnswer.Value
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Call cmdCancel_Click
End Sub

This was inspired by an example from the following page: nkadesign.com/2008/ms-access-enhanced-message-box-replacement
 

Users who are viewing this thread

Back
Top Bottom