How to close a specific form in vb.net? - vb.net

I use this code to close the name Frm_AutoSaleReceipt when I click the button on the other page. But it error like the image.
For Each fua As Form In Application.OpenForms
If fua.Name = "Frm_AutoSaleReceipt" Then
fua.Close()
End If
Next

Without loop all open forms you can find that in this way:
Dim frm As Form = Application.OpenForms.Item("Frm_AutoSaleReceipt")
If frm IsNot Nothing Then frm.Close()

Related

userform.show problems

I am making a word document to fill out a form upon clicking a button. I have made a basic form so far named 'NewSite' I have then made a button to click to open the form with the code:
Private Sub NewSite_Click()
NewSiteUserForm.Show
End Sub
This then pops up the error 'Object Required'
Any help will be appreciated!
edit**
I have figured it out...
I set the name of the form back to its original name of 'UserForm1' for ease of use. The code:
Private Sub NewSite_Click()
Dim Form As Object
Set Form = UserForm1
Form.Show
End Sub
semed to work.
If you named it NewSite, you will have to declare your variable as an object of that type and the initialize it. Do it like this:
Private Sub NewSite_Click()
Dim NewSiteUserForm As NewSite
Set NewSiteUserForm = New NewSite
NewSiteUserForm.Show
End Sub

Can I remove Source Object from all sub forms when closing main form?

I am trying to loop through all the controls on a form that have a tag property of "Page". These particular controls are actually sub forms on a Tab Control on the main form. I do not set the Source Object of these sub forms until the tab is clicked by the user. I want to do a routine to remove all of the Source Objects of these sub form when the main form is closed. This is what I have tried, but it doesn't remove the actual Source Object:
Private Sub TestTag()
Dim c As Control
For Each c In Me.Controls
If c.Tag = "Page" Then
Debug.Print c.Name
c.SourceObject = ""
End If
Next c
End Sub

Find open subform

I have a subform with a button that opens another form.
On the secondary form, the user can select an address.
The selected address should be applied to the calling form.
I pass the window handle when opening the child form.
But when it tries to find the calling form in the Forms collection, it isn't there.
I suspect that is because the calling form is actually a subform.
I don't know where to go from here.
Calling the form, passing the windows handle
OpenCCCustAddr [CustFID], "CCInt", Me.hWnd
In the Form Close event, I try to set the address values on the calling form,
but GetFormByHWND returns null.
Set frm = GetFormByHWND(Me!txtCallingHWND)
// Me!txtCallingHWND here is populated and looks reasonable
frm!BillStreet = strAddr // This blows up since frm is null
frm!HolderZipCode = strZip
frm!AddressUpdated = -1
Set frm = Nothing
Public Function GetFormByHWND(lngHWND As Long) As Form
Dim frm As Form
Dim nm As String
Select Case lngHWND
Case 0
Case Else
For Each frm In Forms
nm = frm.NAME // the name of the parent form shows, but not my calling subform
If frm.hWnd = lngHWND Then
Set GetFormByHWND = frm
Exit For
End If
Next
End Select
End Function
For Each and For I=0 to Count-1 both give the same results. The form just isn't in Forms. It's possible that it is because it is a subform.
I tried searching the subforms, but this blows up when I check ctl.hWnd with "Object doesn't support this property"
Public Function GetFormByHWND(lngHWND As Long) As Form
Dim frm As Form
Dim ctl As Access.Control
Dim nm As String
Select Case lngHWND
Case 0
Case Else
For Each frm In Forms
nm = frm.NAME
If frm.hWnd = lngHWND Then
Set GetFormByHWND = frm
Exit For
End If
Next
Rem If we didn't find the form, check for a subform
If GetFormByHWND Is Nothing Then
For Each frm In Forms
nm = frm.NAME
For Each ctl In frm.Controls
If ctl.Properties("ControlType") = acSubform Then
nm = ctl.NAME
If ctl.hWnd = lngHWND Then // Error: "Object doesn't support this property"
Set GetFormByHWND = ctl
Exit For
End If
End If
Next
Next
End If
End Select
End Function
As #June7 pointed out, my mistake was assuming that the control was the form. Instead is has a form.
So the proper solution is
Rem If we didn't find the form, check for a subform
If GetFormByHWND Is Nothing Then
For Each frm In Forms
For Each ctl In frm.Controls
If ctl.Properties("ControlType") = acSubform Then
If ctl.Form.hWnd = lngHWND Then // note the change here
Set GetFormByHWND = ctl.Form
Exit For
End If
End If
Next
Next
End If
First, it not at all clear why all that code and hwn stuff is required?
We assume that you have a form.
On that form, you have a button, and it launches the 2nd form.
so, in first form, we have this:
' write data to table before launching form
If Me.Dirty = True Then Me.Dirty = False
DoCmd.OpenForm "formB"
Ok, now in formB on-load event, we have this:
Option Compare Database
Option Explicit
Dim frmPrevious As Form
Dim frmPreviousSub As Form
Private Sub Form_Load()
Set frmPrevious = Screen.ActiveForm
Set frmPreviousSub = frmPrevious.MySubFormControl.Form
' do whatever
End Sub
So now we have both a reference to the previous form, and also the sub form.
Say the user selects some address and hits the ok button.
The code then does this:
frmPreviousSub!AddressID = me!ID ' get/set the PK address ID
docmd.Close acForm, me.name
So no need for all that world poverty, grabbing and looping hwnd or any such hand stands.
Just a few nice clean lines of code.
Now, I DO HAVE a recursive loop that will return the form handle ALWAYS as a object reference, and you thus don't even have to hard code the form(s) name.
So, say that main form had 2 sub forms, and on those to sub forms, you have
A Company address, and a ship to address. So, you want to launch form B from EITHER of these two sub forms, and when you select a address, you return that value, and thus two or even potential 3 sub forms could in fact call this way call pop up address selector form.
The way you do this is similar to the above code, but we do NOT need to hard-code the sub form.
The code will now look like this:
Private Sub Form_Load()
Dim f As Form
Set f = Screen.ActiveForm ' pick this up RIGHT away -
' previous active form only valid
' in open/load event
' we have the previous active form, get the sub form.
Set frmPrevous = GetSubForm(f)
End Sub
Note that the sub form can be 3 or even 5 levels deep. This routine is "recursive". It grabs the previous form, then checks if a sub form has focus. If the sub form has focus, then it gets that control, and if that control is a sub form, then it just keeps on going until such time we drill down this rabbit hole and NO MORE drilling down can occur.
This routine should be placed outside of the form and placed in your standard "global" module of routines.
Public Function GetSubForm(f As Form) As Form
Static fs As Form
If f.ActiveControl.Controltype = acSubform Then
GetSubForm f.ActiveControl.Form
Else
Set fs = f
End If
Set GetSubForm = fs
End Function
So note how if it find that a sub form has the focus? Well then it just calls itself again with that form and keeps on drilling down. As a result, it don't matter if the form is 1 or 5 levels deep. The resulting "frmPrevous" will be a valid reference to that sub form, and thus after you select or do something in the supposed popup form? You can set the value of some PK or whatever and then close the form.
There is no hwnd, very clean code, and the recursion trick means that even for nested sub forms more then one deep, your frmPrevious is in fact a reference to the form that launch the form we pop up for the user to select whatever.
If you don't have a common Address ID column? Then our popup form should ASSUME that you always have a public variable defined in the calling form.
Say ReturnAddressID as long
Make sure you dim the value as public, say like this:
Public ReturnAddressID as long
So, now in our popup form, we can do this:
frmPrevious.ReturnAddressID = me!PD
frmPrevous.MyUpdate
(we assume that all forms that call the popup also have a public function names MyUpdate.
Thus, now we have a generalized approach, and 2 or 10 different address forms, even as sub forms can now call the one address picker. As long as any of those forms adopts that public ReturnAddressID and a public function MyUpdate, then we can pass back the values, and MyUpdate will shove/take/set the ReturnAddressID into whatever column and value you use for the Address ID in that sub form.
And of course if there are no sub forms, the routine will just return the top most form that called the pop up form.

Why is my form still in memory

I have the following code opening a form and then doing some stuff.
Sub lag_ny_a3()
Dim frm As ufNyA3
Set frm = New ufNyA3
frm.Show
If Not frm Is Nothing Then
MsgBox("Doing stuff")
Unload frm
End If
End Sub
Then I have the following code in my form
Private Sub cmdAvbryt_Click()
Unload Me
End Sub
However, even if the cmdAvbryt-button is clicked in the form, the first code-snippet enters the if-statement, as if the form is not unloaded. Why is this, and how can I prevent the code in the if-statement to be executed if the cmdAvbryt-button is pushed?
Even though your frm variable isn't Nothing, the form is unloaded. Add a little check before and after the frm.Show:
Debug.Print VBA.UserForms.Count
frm.Show
Debug.Print VBA.UserForms.Count
and you'll see that it is not in the list of loaded forms. If you set the object variable to Nothing it will not do the "Doing stuff"
Actually, frm declared as ufNyA3 will not become Nothing after the userform unloading. Try to use the following IsUserFormLoaded() function to check if the userform is loaded:
Sub lag_ny_a3()
Dim frm As ufNyA3
Set frm = New ufNyA3
frm.Show
If IsUserFormLoaded("ufNyA3") Then
MsgBox ("Doing stuff")
Unload frm
Else
MsgBox ("Unloaded")
End If
End Sub
Function IsUserFormLoaded(UserFormName As String) As Boolean
Dim frm
For Each frm In UserForms
IsUserFormLoaded = LCase(frm.Name) = LCase(UserFormName)
If IsUserFormLoaded Then Exit For
Next
End Function

cannot save data entered in a form that was opened using dao.

let me start by saying that i am new to access vba coding, so bear with me.
i open a form using dao code opened to a new record. however, i cannot seem to be able to save the record no matter what i try.
'opened a Form_MyForm for a new record.
dim frm as new form
set frm = new Form_MyForm
frm.recordset.addnew
frm.visible = true
On the "Form_MyForm" save button, i have the following code
private sub save_click()
me.dirty = (me.dirty = false)
docmd.close acForm, me.name
end sub
everything seems to work ok (including the ID, hwnd, etc) except that nothing gets saved on the table. if i use docmd.openform to open the form, then the code works...
First of all you create two forms, one of the type form, the other of the type of your form.
Anyway, I would recommend using the DoCmd.Openform command.
Normally you would not have to save any data. (On the contrary, if you want to not save the data you would use
If Me.Dirty = True Then
DoCmd.RunCommand acCmdUndo
Exit Sub
End If
If you need to access the form from vba after you opened it, use
Set frm = Application.Forms("My_Form")
And if you want to close the form programmatically again use DoCmd.close