How to Requery a Subform which is a Junction Table - vba

Just got a quick question. I have a junction table (Junction_Table with Song_ID and Artist_ID), and I have it as a subform in a form (Song). If I click a button I have set up, it allows me to enter a new artist into the database, by opening the Artist Form in Add-Mode. After I have entered the Artist info, and I close the Artist form, which brings me back to my Song Form, the Junction Table field for Artist_ID has not refreshed with the new Artist that was just entered. How could I refresh (Requery) this field in the Subform. I was thinking I would put some code in the button that closes the Artist form, effectively bringing me back to the Song form. I just don't know what code I should use. I have tried a few things, like this (Which has worked in other cases I needed to requery something):
Private Sub Command16_Click()
DoCmd.Close
DoCmd.OpenForm "Junction_Table"
Forms![Junction_Table]![Artist_ID].Requery
DoCmd.Close
End Sub
My Junction Table has the Master Field of the Song_ID of the Song Table Record, and the child field is the Song_ID of the Junction Table record, which when the subform is selected, autofills the Song_ID combo box with the ID of the current Songs ID, which is really helpful. Not sure if that information was important, but I added it anyway.

Try removing the first docmd.close from your code.
I think you are closing the window before the rest of your code can execute.
Your code would look like this:
Private Sub Command16_Click()
DoCmd.OpenForm "Junction_Table"
Forms![Junction_Table]![Artist_ID].Requery
DoCmd.Close
End Sub

Related

MS Access one form to select table values and use to populate multiple fields on other form?

I have a table called GL_Account and IM_Productline
The table IM_Productline has various fields that need to be populated with a value from the field GL_Account.AccountKey (i.e. IM_ProductLine.InventoryAcctkey and IM_ProductLine.CostOfGoodsSoldAcctKey)
To populate the IM_ProductLine table I made a form "Product Line Maintenance" with all the fields. To populate the field IM_ProductLine.InventoryAcctkey I put a (magnifying glass) button behind the field with the following code:
Private Sub CMD_Select_GL_Account_Click()
Me.Refresh
If IsNull(Select_ProductType) Then
'do nothing
Else
Forms![Product Line Maintenance].InventoryAcctkey = Me.SelectGLAccountKey.Column(0)
Forms![Product Line Maintenance].Refresh
End If
DoCmd.Close
End Sub
So the button opens a form Called "Select GL Account" with a combo box that enable to SELECT GL_Account.AccountKey, GL_Account.Account, GL_Account.AccountDesc
FROM GL_Account; and when the OK button is clicked it writes the value from GL_Account.AccountKey to IM_ProductLine.InventoryAcctkey, closes the form "Select GL Account" and then refreshes the form "Product Line Maintenance" so the account number and description become visible for the user.
This all work fine but here's my question:
Now rather than creating a new form for every account field I need to populate (i.e. "Select Inventory GL Account" select "Cost Of Goods Sold GL Account" etc) I'd prefer to use the form "Select GL Account" to select and populate the 11 different account fields. So behind each xxxAcctkeyfield on form "Product Line Maintenance" is a (magnifying glass) button that when clicked pulls up the form "Select GL Account" and when "OK" is clicked it writes the selected AccountKey to the correct field on form "Product Line Maintenance"?
I'd greatly appreciate anyone's efforts to understand what I am trying to explain and point me in the right direction.
Ok, there is the issue that all 11 fields should not require to be "copied" since you have a relational database (you would ONLY store the row PK ID of that selection in the current report. (a so called FK (foreign key) value). That way, say you want to change the choice? Well then you could pop up that form - search + select the one record with all that information, and then upon return ONLY store the one value.
So, I would give some thoughts to the above - you want to leverage the relational database features. And as a result, you don't need to "copy" all that data. This is not much different then say creating a invoice. I can create the new invoice, but all of the address information, and the customer that this ONE invoice belongs to? Well, that is one column with a FK value that points to the customer. Once I select that one customer, then display of the customer name + address can be say a sub form or some such - but no need exists to "copy" that information. It would also means with near zero code, you could move a invoice between customers!!! - (just change the one fk column with to the new/different customer ID (PK) value.
Now, back to the question at a hand?
You can certainly pop up a form, let the user select, enter, pick and do whatever. And THEN you can have the calling code grab + pick out the values from that form.
The way you do this? It involves a not too wide known trick.
The code that calls the form can simply open that form as a dialog form. This will HALT the calling code, the user does whatever, and when done the calling code will THEN continue. Not only does the calling code continue, but it can get/grab/pull/take any values from that pop up form WIHOUT having to use global vars.
The approach is thus thus:
dim strF as string
strF = "frmPopAskInfo"
docmd.OpenForm strF,,,,,,acDialog
' above code waits for user input
if application.AllForms(strF).IsLoaded = true then
' user did not cancel, get values from form
me!AccountNo = forms(strf)!AccountNumber
etc. etc. etc.
docmd.Close acForm,strF
end if
Now the only other issue? Well, the "ok" button on the popup for DOES NOT close the form, what it does is set visible = False. This will kick the form out of dialog mode.
me.Visible = False
So, if the user hits the cancel buttton (close form) or hits the X upprer right (close form), then the form will NOT be loaded when your calling code continues. But, if they hit OK button, then you don't close the form, but ONLY set visbile = false.
This allows the calling code to continue, you are free to get/grab/take values from that form, and then once done, you close the form.
So a form close in that popup = user canceled the form.
So, a popup form, and even a modal form? They do NOT halt the VBA calling code, but a acDialog form does!
You can thus place 2 or 5 little buttons that pops up this form, the user can pick/choose/select/enter values. When they hit ok, your calling code continues, and you are free to pull values from that form. So while all 3-4 buttons might pop up that form, each individual button launch of the form can have code that follows and updates the given control the pop button was placed beside.

How to launch a Look up form, and return the value from a combo box

Hopefully I can explain what I want to do well enough...here it goes...
I have a data entry form...the user will be entering employeeIDs. Once in normal operation, most people will be entering only their own EmpID, and they should know it, so this won't be a big problem 99% of the time once this DB goes live.
However, I need some temps to enter historical data from paper sheets into the DB. These people will not know anyone else's EmpID. I'd like to set the Student field's OnDblClick event in the subform's datasheet to open a small form with a combo box. The combo box has a list of all Employee Names, and is bound to the EmpID. Once this user enters the name, and selects the person, I have a button they can click to return to the datasheet.
I can use a function to launch the form, no problem there. But how do I return the EmpID to the field in the datasheet that was double clicked?
When user double clicks in the Student field...I want the next form to appear, and then once they type in the name and select the correct person...and then click Found Them!...I need that bound value to return.
I'd love to say I have code to share right now...but the only code I have is to launch the look up form. I'm brain farting on how to pull the value back down.
The way to do this to launch your little dialog form as “acDialog”. This will cause the calling code to WAIT.
And then the “magic” part is when they click on “Found Them” you do NOT close the popup form, but simply set the form’s visible = false. This has the effect of the calling code that popped up this form that halted to continue (the form is kicked out of dialog mode when you do this). So now your calling code continues.
So your code will look like this:
Dim strF As String ' name of popup form
strF = "frmPopUp"
' open form, wait for user selection
DoCmd.OpenForm strF, , , , , acDialog
' if for is NOT open, then assume user hit cancel buttion
' (you should likly have a cancel button on the form - that cancel buttion will
' execute a docmd.close
If CurrentProject.AllForms(strF).IsLoaded = True Then
' grab the value of thee combbo box
strComboBoxValue = Forms(strF)!NameOfComboBox
DoCmd.Close acForm, strF
End If
As noted, the code behind the Found Them button DOES NOT do a close form, but sets forms visible = false (me.Visible = false), and this trick allows the calling code to continue at which point you can examine any value on the form. Remember to then close the form after you grab the value.
It looks like your data table is in a subform so there is a little more work but it does not have to be as complex as the above solution if you don't want it to be. #Andre451 was close but you need the extra step of identifying the form and subform. For the purpose of demonstration let's call the form Attendance and subform Entry then I'll call the second form LookUp. So the code for your double click in the subform field will of course look something like this :
Private Sub Student_DblClick(Cancel As Integer)
DoCmd.OpenForm "LookUp"
End Sub
You really don't need anything else fancy there. For the button on "LookUp" you will put this:
Private Sub Command2_Click()
Forms![Attendance]![Entry].Form![Student] = Forms!Lookup!Student
DoCmd.Close acForm, "LookUp"
End Sub
And that should get you what you want without any overhead or having to leave any ghosts open.

MS Access does not add new Entry

So I have created a Table and a Form, which allows you to Save New Record to the table, by entering some fields.
Everything works fine, except that while clicking "Save New Record" button, the new entry is NOT saved, but it Edits the previous entry!
So no more then 1 record is inside the Primary Table.
Could it be something with Relationships ?
I have two tables:
PrimaryTable
ContactsTable
Both have the same name as Primary Key and are connected via that Key (inside relationships).
If you need more information or some screenshtos, pleaese let me know in comments!
CODE FOR SAVE NEW RECORD:
Private Sub onSaveBtn_Click()
DoCmd.RunCommand acCmdSaveRecord
DoCmd.Close acForm, Me.Name
End Sub
Thanks,
David
Since you created your form through the wizard it is likely a bound form. This means that as you edit information in the form you are editing the records directly. When you open your form if there is already data populated then the command you have included in your button DoCmd.RunCommand acCmdSaveRecord is going to save the information displayed on the form to whatever record was open.
There are a few ways you can deal with this issue. At the bottom of your form you may have navigation buttons and one with a * icon beside it. This indicates create a new record and will clear the form and move it to a blank record when pressed.
You can also add a button on your form with the following code that will do the same thing.
DoCmd.GoToRecord , , acNewRec
Another option you have is to create an unbound form that will allow you to completely control how your users navigate your data.

MS Access Copying value from a form into another form text box

Here's my problem: I have the below code which copies the employee username from FormB and puts it in FrmEmployee when i click on a record in FormB (which is opened through a cmd button on FrmEmployee and lists all employees in the company and their shift pattern).
Private Sub Form_Click()
Forms!FrmEmployeee.Form.Username = Me.Username
End Sub
This works but it will only set the current username field to what is selected on FormB. FormB is in a datasheet view and will hold multiple values for the employee username. So what I want to do is expand the above code somehow so it takes me to the next record on FrmEmployee which means when i select another user from FormB this value will be copied into the next Username record, allowing me to build a list of employees.
From my understanding, what you need actually is to store multiple line/items from your FORM B.
So my suggestion is changing your textbox on FrmEmployee into a ListBox. So everytime you out the cursor on the active record, it add the record into the listbox

How to refresh an access form

I am building an MS Access application in which all the forms are modal. However, after data change in a form, I want to refresh the parent form of this form with newer data. Is there any way to do it. To elaborate further :
Consider there are two forms, Form A and Form B. Both are modal form. From Form A, I initiate Form B, and now Form B has the user attention. But at the close of form B, I want to refresh the Form A. Is there a way to do it?
You can repaint and / or requery:
On the close event of form B:
Forms!FormA.Requery
Is this what you mean?
No, it is like I want to run Form_Load
of Form A,if it is possible
-- Varun Mahajan
The usual way to do this is to put the relevant code in a procedure that can be called by both forms. It is best put the code in a standard module, but you could have it on Form a:
Form B:
Sub RunFormALoad()
Forms!FormA.ToDoOnLoad
End Sub
Form A:
Public Sub Form_Load()
ToDoOnLoad
End Sub
Sub ToDoOnLoad()
txtText = "Hi"
End Sub
"Requery" is indeed what you what you want to run, but you could do that in Form A's "On Got Focus" event. If you have code in your Form_Load, perhaps you can move it to Form_Got_Focus.
I recommend that you use REQUERY the specific combo box whose data you have changed AND that you do it after the Cmd.Close statement. that way, if you were inputing data, that data is also requeried.
DoCmd.Close
Forms![Form_Name]![Combo_Box_Name].Requery
you might also want to point to the recently changed value
Dim id As Integer
id = Me.[Index_Field]
DoCmd.Close
Forms![Form_Name]![Combo_Box_Name].Requery
Forms![Form_Name]![Combo_Box_Name] = id
this example supposes that you opened a form to input data into a secondary table.
let us say you save School_Index and School_Name in a School table and refer to it in a Student table (which contains only the School_Index field). while you are editing a student, you need to associate him with a school that is not in your School table, etc etc
to refresh the form you need to type -
me.refresh
in the button event on click