Pass values ​from a subform to a textbox in another access form - vba

I would like to create an invoice in a form, pressing a button from another form with the data. Pressing the button would pass the customer data, dates etc. into different textboxes. But the detail of the purchase, the units, the number of invoices, etc. are in a subform. There is no problem to pass the first item to a textbox in the invoice form. But the issue is that there are several items.
This is my code in the button
Private Sub Boton_Click()
Dim strFrmName As String
strFrmName = "FACTURAR"
DoCmd.OpenForm strFrmName
With Forms(strFrmName)
.RUT_2 = Me.RUT
.REGIS_RECP_2 = Me.registroRecepcion
.NAME_2 = primerNombre & " " & primerApellido & " " & segundoApellido
.BOLETA_2 = Me.BOLETA_INV
.CANT_2 = Me.CANT_INV
'The problems in the subform and thier data...
End With
End Sub
I have tried to pass subform1 to subform2 but nothing works, I have created a vlookup to search on the subform's source table using outside sharing references (placed in the mainform) but it didn't work. Any idea? It's possible?

Related

Can I filter an Access form based on a match criteria using VBA?

I have created a form that acts like a more advanced find dialog box. The user clicks on a button within a form, which opens my search form. This search form filters the original form to only display records that match certain fields from the original record within a certain tolerance.
Is there a way to sort the filtered form to display the closest matches first? I have considered using a couple of helper fields within the form. These helper fields would be equivalent to the absolute value of the difference between my criteria and the data within the record's fields. However, I was unsure of whether there was a better way to approach the problem.
Thank you.
Yes, you can certainly set the forms sort order quite much as easy to set the filter.
You might have say this:
Dim f As String
Dim strWhere As String ' our filter
Dim strSortBy As String ' our sort by
f = "frmFilter" ' name of our filter form.
DoCmd.OpenForm f, , , , , acDialog
If CurrentProject.AllForms(f).IsLoaded = False Then
' user closed the dialog form, so lets cancel
Exit Sub
End If
' setup our form filter.
If IsNull(Forms(f)!CompanyName) = False Then
' user entered company name - filter by that
' match by starting
strWhere = "CompanyName LIKE '" & Forms(f)!Company & "%'"
strSortBy = "CompanyName"
End If
If IsNull(Forms(f)!City) = False Then
' user entered Persons name - filter by that
strWhere = "LastName = '" & Forms(f)!LastName & "'"
strSortBy = "City, LastName"
End If
' ok, done with that form, close it
DoCmd.Close acForm, f
Me.Filter = strWhere
Me.FilterOn = True
Me.OrderBy = strSortBy
Me.OrderByOn = True
For the dialog form to work (allow the code to continue?). The ok button on the dialog form will cause the code above to wait. So, to get "back" to this calling code, the ok button on the dialog form (the filter form) will have:
me.Visible = False
And the cancel button on the filter form will have:
docmd.Close acForm, me.Name
So, we assume that
If user hits ok on filter form - it is a "ok", and the form is STILL open. This allows our above code to use/look at/grab values from that dialog form.
If the user hits cancel in that dialog form, it is closed and once again our above code will run after the user closes that dialog form. So, closing the form means cancel, and setting visible = False means ok. (both actions (close, or visible = False) will flip the dialog form OUT of dialog mode and allow our above code to run after the open dialog form command we have above.
It is then a simple matter to get/grab values from the dialog form , setup our filter, and also setup our "order by"

Is there an easy way to determine what page in a tab is open to read the table in Access?

I have a form with a tab control for payments. There is a separate page for Current, Future and Past payments each tab has a table that has a common field called ID.
I have a button that opens another form with more detailed info on the payment and uses the ID in a query to get the data.
Since each page uses/has the same ID is there an easy way to look up the ID regardless of which page is open?
I tried
ID = Forms!TabBills.Pages(TabBills.Value)![ID].Value
Tab control and its pages are irrelevant when referencing controls that sit on each page. Need to know the subform container name.
Value of tab control is index of page with focus. So use that value with Pages collection to grab Caption of that page. Assuming each tab control page has subform container control with a form as SourceObject and page Caption is same as name of subform container on that page consider:
strSubform = Me.TabBills.Pages(Me.TabBills.Value).Caption
intID = Me(strSubform)!ID
Any variation in naming may need If Then Else or Select Case structure.
Yes there is.
Have a function to look up the ID and call this from your button:
Private Sub YourButton_Click()
MsgBox GetCurrentID()
End Sub
Public Function GetCurrentID() As Long
Dim Control As Control
Dim CurrentID As Long
For Each Control In Me!YourTabControl.Pages(Me!YourTabControl.Value).Controls
If Control.ControlType = acSubform Then
Exit For
End If
Next
If Not Control Is Nothing Then
CurrentID = Nz(Control.Form!ID1.Value)
End If
GetCurrentID = CurrentID
End Function
I would do it with a more dynamic approach.
Helping procedure
This procedure tries to find a sub form control in a page.
If there are more then one sub form controls in a page it returns the first found.
Private Function FindSubformControlInPage(ByVal pageToCheck As Page) As SubForm
Dim item As Control
For Each item In pageToCheck.Controls
If TypeOf item Is SubForm Then
Set FindSubformControlInPage = item
Exit Function
End If
Next
End Function
Usage
Dim currentSubformControl As SubForm
Set currentSubformControl = FindSubformControlInPage(Me.TabBills.Pages(Me.TabBills.Value))
If currentSubformControl Is Nothing Then
MsgBox "No subform control in the current page"
Exit Sub
End If
If currentSubformControl.SourceObject = vbNullString Then
MsgBox "The current subform control doesn't contain a form."
Exit Sub
End If
Dim currentSubform As Form
Set currentSubform = currentSubformControl.Form
MsgBox "Found subform: " & currentSubform.Name
More compact usage
That means you're sure that there always is a sub form control and it contains a form.
Dim currentSubform As Form
Set currentSubform = FindSubformControlInPage(Me.TabBills.Pages(Me.TabBills.Value)).Form
MsgBox "Found subform: " & currentSubform.Name
Get the ID
Finally, having the correct (sub-)form you can access your ID field:
Dim currentID As Long
currentID = currentSubform.Controls("ID").Value

VBA: userform multipage template

I'm making a Userform that would allow the user to changes the bounds on several charts at once. I figured out how everything should look on the first multipage, and now I'm wondering if there's any way I could add 11 pages at once to look just like the first page. My userform appears below.
I am still in the design phase for this. If there's a way to do this in the design that would be great. If there's a way to do in the Initialize sub that would also be great.
Based on your intended usage, you should be using a TabStrip instead of MultiPage being most controls within are the same layout (same amount of controls). MultiPage is intended for categorizing data with different controls on each page.
Consider this simple userform to demostrate the benefit of using TabStrip here:
The left side square is a Picture holder I have not put codes for.
With below code to handle tab changes, certain elements in the userform will change when a different Tab is clicked.
Option Explicit
Private Sub TabStrip1_Change()
Dim TabX As String
With Me.TabStrip1
TabX = .Tabs(.Value).Caption
Debug.Print "ActiveTab:", TabX
End With
Me.Frame1.Caption = "Maximum Bounds (" & TabX & ")"
Me.Frame2.Caption = "Minimum Bounds (" & TabX & ")"
Me.TextBox1.Value = "TextBox2 for " & TabX ' Forgot to change this Value to TextBox1 before the screenshot...
Me.TextBox2.Value = "TextBox2 for " & TabX
End Sub
Upon launching the userform (without setting UserForm_Initialize):
Tab2 clicked:
Tab1 clicked:

In VBA, why does putting a textbox value into a cell trigger a for loop in another userform subroutine?

I created an userform with 2 textboxes, 3 buttons and a listbox with two columns. If I click on an entry in the listbox, the list entry which is selected gets transfered to two different textboxes.
See the code below:
Private Sub NewSourceListBox_Click()
Dim i As Integer
'Show the selected data in the corresponding text boxes
For i = 0 To NewSourceListBox.ListCount - 1
If NewSourceListBox.Selected(i) Then
'Hide the add button and show the change button
NewSourceBtnChange.Top = 168
NewSourceBtnChange.Visible = True
NewSourceBtnAdd.Visible = False
NewSourcesIDTxtBox.Value = NewSourceListBox.List(i, 0)
NewSourcesSourceTxtBox.Value = NewSourceListBox.List(i, 1)
'Pass on the selected item row to another subroutine
selectedItem = i
Exit For
End If
Next i
End Sub
selectedItem is a global variable created in another module, which I need to use in another subroutine. If I change the entries in the text boxes in the userform and click the change button the following code gets executed.
This code:
Private Sub NewSourceBtnChange_Click()
Dim row As Integer
row = 6257 + selectedItem
'Change the selected data in the list box to the corresponding data in the text boxes
Sheets("Datensätze").Range("A" & row).Value = NewSourcesIDTxtBox.Value
Sheets("Datensätze").Range("B" & row).Value = NewSourcesSourceTxtBox.Value
'Another duplicate entry to make vLookup work
Sheets("Datensätze").Range("C" & row).Value = NewSourcesIDTxtBox.Value
Unload Me
'Unload the new entry user form to repopulate the comboboxes
Unload NewEntryUserForm
NewEntryUserForm.Show
End Sub
If I watch this step by step via F8 then the following happens: As soon as I click the "NewSourceBtnChange" button the corresponding subroutine NewSourceBtnChange_Click() starts. When I reach Sheets("Datensätze").Range("A" & row).Value = NewSourcesIDTxtBox.Value the program jumps to the NewSourcesListBox_Click() routine, executes it two times and jumps back to Sheets("Datensätze").Range("B" & row).Value = NewSourcesSourceTxtBox.Value, then executes the NewSourcesListBox_Click() routine for another two times and jumps back again to the last entry Sheets("Datensätze").Range("C" & row).Value = NewSourcesIDTxtBox.Value and executes the rest of the NewSourceBtnChange_Click() routine.
This makes it impossible to get the new data from the text boxes into their destined cells.
Edit:
Just to make it easier to reconstruct the described behavior, I exported the userform and its code and uploaded it.
Here is what your code is going through (just the important parts):
1) While initializing userform, it populates the listbox with:
.RowSource = "Datensätze!A6257:B" & 6257 + Sheets("Datensätze").Range("F2").Value - 1
2) When you click listbox item, you trigger NewSourceListBox_Click code, populate textboxes with selected items and set item index number to selectedItem variable. (which is handled wrong. You need to declare selectedItem as public variable.)
3) Then you click NewSourceBtnChange which triggers NewSourceBtnChange_Click. It sets row number of your selected item:
row = 6257 + selectedItem
Then you change this very cell using:
Sheets("Datensätze").Range("A" & row).Value = NewSourcesIDTxtBox.Value
which you have used to populate your listbox with:
.RowSource = "Datensätze!A6257:B" & 6257 + Sheets("Datensätze").Range("F2").Value - 1
At this moment, listbox is populated again, but this time it has been already selected so it triggers the NewSourceListBox_Click code.
Whenever you change the RowSource range, if the listbox is selected, it will behave like this. So you need to deselect the listbox item to workaround this.
TL;DR:
After:
row = 6257 + selectedItem
Insert:
NewSourceListBox.Selected(NewSourceListBox.ListIndex) = False
Also to be able to get selectedItem value in other subs, you need to declare it as public variable. Outside of subs, on the very top, insert:
Public selectedItem As Long

SubForm won't Requery after MainForm Changes are made

I have an access 2010 database that has a main form 'MainForm' and a subform 'SubForm'. The SubForm is attached to the MainForm as a Subform/Subreport object. The user will select a unique identifier from a dropdown and the subform should use that identifier to pull up employee information on the subform. I have tried any number of ways to avail...
Private Sub Dropdown_Exit(Cancel As Integer)
If IsNull(Me!Dropdown) Or Me!Dropdown= "" Then
' nothing to do due to no one selected
Else
Forms!MainForm!SubForm.Requery
' Forms!SubForm.Requery
' DoCmd.OpenForm "SubForm",,,"[ID]=" & me!SubForm!ID,,acDialog
End If
End Sub
The commented out statements are only some of the things I have tried.
Thanks in advance
You should be able to do this without any code by specifying the LinkMasterField and LinkChildField properties of the subform control on your main form.
It is clear that LinkChildField should be set to ID in the form design mode. It looks like you'll want to set LinkMasterField to Dropdown. You can set the FilterOnEmptyMaster property to Yes to hide all records before the Dropdown is filled, or No to show all records before Dropdown is specified.
EDIT:
If LinkMaster/LinkChild are not appropriate, then code for Dropdown's AfterUpdate event. This fires after a choice is completed via keyboard or mouse. It should look like :
Private Sub Dropdown_AfterUpdate()
If Len(Me!Dropdown & "") = 0 Then
'' handle cleared Dropdown
Else
Subform.Form.Filter = "[ID] = " & Me!Dropdown
Subform.Form.FilterOn = True
End If
End Sub
Changing the filter should update the subform.