I have a bound userform with lot of fields in it, I use submit button to let user make entries in shared form. But whenever user clicks on submit button it requery whole form. However, there are around 4-5 fields which should not be cleared on submit button, they should retain the value and rest of the fields should get cleared on every submit button click.
Can this be done in access and how ? below is the simple code is use to submit and requery the record.
Private Sub SaveBtn_Click()
RunCommand acCmdSaveRecord
Me.Requery
Me.DataForm.Requery
End Sub
When you have a "Bound Form" in Access, this means that the Access Form is tied to the underlying data source, which is specified by, and stored in, the "Record Source" property for the form. In the "SaveBtn_Click()" method you provided above, this code does the following things:
RunCommand acCmdSaveRecord - Saves the current record in the form.
Me.Requery - Requeries the entire form.
Me.DataForm.Requery - Requeries the subform named "DataForm" on your main form.
So when you "Requery" the entire form (depending on how the "Record Source" and other form property settings are setup), the requery operation in some cases moves the cursor to the new record in the data source (...its the default settings for the drag and drop form designer tools in later versions of Access), and I suspect that is why you see the form being "cleared" when you call "Requery." A couple of items I would point out, just for clarity:
Note 1: "Requery" actually saves the record, so explicitly calling "RunCommand acCmdSaveRecord" should not be necessary if you're going to call "Requery" too.
Note 2: Depending on how the Record Source (and other) form properties are set, Requery in some cases just saves and refreshes the currently selected record, but it doesn't sound like that is how your form is working (based on what you said above), so I'm assuming that is not the case in your form.
Note 3: The subform will also be requeried when you call "Requery" for the main form, so that line of code may also be redundant here. The reason to call "Me.DataForm.Requery" is if you only want to requery the subform and NOT requery the entire main form.
Note 4: The "DataForm" subform (on your main form) will have a separate data source for it's own "Record Source" property, which is separate from the parent (main) form, so it is important to be aware of that fact, depending on which field values you want to save.
So, that said, there are a couple of options I might suggest, depending on exactly how you want your form to behave:
If you want to keep some of the field values and use those for the NEW RECORD when you hit the requery button, you could always save them off in a variable and then set those controls again after requerying from your variables. Just create a seperate variable for each value you want to save, copy the TextBox control values into each of variables respectively, call requery on the form, and then copy those values back into your TextBox controls after you requery. That code would be something like the following (depending on the exact names of your TextBox controls, I used the fictitious name "txtMyTextBox" for this example):
Private Sub SaveBtn_Click()
Dim vValue1 as Variant
vValue1 = txtMyTextBox
Me.Requery
txtMyTextBox = vValue1
End Sub
Or, if you're just trying to create "Default Values" for certain controls, TextBox controls have a "DefaultValue" property you can set to any value you would like to use for the default. Those can be set from the Property Sheet on the right side of the Access window when the form is opened in Design mode or Layout mode and the TextBox control is selected. (Press F4 to open the Property Sheet if it's not already open).
But, if you really want to Requery and then go back to the same record you were previously on, you could try the following code:
Private Sub SaveBtn_Click()
Dim iRecord as Integer
iRecord = Me.CurrentRecord
Me.Requery
DoCmd.GoToRecord , , acGoTo, iRecord
End Sub
Anyway, I hope this all makes sense and you find it helpful. Please let me know if you have any further questions about this answer.
Related
I've been tasked with making updates to an MS Access Database and its forms.
Each form seems to be linked to a query. If I enter data into a text box on the form and then close the form without pressing the Save Record button a new record is still added to the Database which makes no sense to.
Any insight would be great, I'm a programmer but have little experience working with Access Forms and Databases.
Thanks.
Microsoft Access binds forms to data by default, and will automatically save data as soon as you either move between records or close the form you're working on. For the average user, this is actually a good thing because it makes it very difficult to lose data, even if you accidentally close the form after making an edit.
If this functionality isn't what you're looking for, I'd suggest removing the binding from the form, that is, set the Record Source property to blank, then manipulate all the data in code using unbound controls. It's a lot more fiddly, but it gives you a lot more control.
The other option would be to use the form's BeforeUpdate event to ask the user if they want to save their changes before allowing them to go through.
If your main concern is accidentally adding new records, set the Allow Additions property to false, and create new records programmatically.
A sample of a BeforeUpdate event procedure (the same code would work for the BeforeInsert event):
Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim intAns As Integer
intAns = MsgBox("Are you sure you want to save this record?", vbQuestion + vbYesNo, "Save Record")
If intAns = vbNo Then Cancel = 1
End Sub
If you were to use the above method, and the user clicked "No", they would have to then click the ESC key to undo the changes they had entered. Otherwise it would keep showing the dialogue when they moved off the record.
I have a subform with unbound image controls that are being populated through code. I am using this subform to display search results when a SEARCH button is clicked. The problem is that I cannot refresh/requery the subform to reflect the current search status, except when I close and open again the form (subform) as a standalone/popup.
I tried this but failed to requery:
With Me.F_Person_Thumbnails_control
.SourceObject = Forms.F_Person_Thumbnails
End With
I will appreciate any help.
Joseph
Try accessing your unbound subform from the parent form.
' To Requery
me.mySubForm.form.requery
' To set a TextBox
me.mySubForm.form.controls("MyTextBox").value = "Test"
You can also access fields from your subform using the form.parent object, although I personally consider this a messier approach - since you are generating errors if the subform is opened by itself. Using the above approach lets you re-use the subform in other places in your database, with different logic (if required). Accessing parent object:
Me.MyTextBox.Value = Me.Parent.Form.Controls("IDNumber").Value
Is there a way to make Access write values immediately to a table when changing values in a form? Right now, I have to change a value in the form, and then click off the field onto the subform before the value is written to the corresponding table.
Sounds like no big deal, but certain controls require current data to give valid options. If the user doesn't know enough to click into the subform then the data they view could be out-of-date.
The behavior in your requirement are asking for is by default how access functions. In most typical scenarios your master form is going to be the parent table, and as a result before you can add child records to such a relational setup, then the parent record would have to be written and saved to disk.
And the reverse while not a requirement is also the default operation for access.
In other words it's not clear why when the focus moves from your parent form to a sub form, that the parent form's record is not been written to the table.
So something in your setup is incorrect here, or you'll have to expand on the behavior you're witnessing.
By default changing the focus from the main form to a sub form will cause the main form record to be written to the table, and changing the focus from a sub form tool main form as a general rule should also cause a sub form record to be written to the table.
If you are matching a combo box, you can use that as your link master field, that is, the name of the control itself. Your subform should update as soon as you select a ticket with the combo.
Link Master Fields: Combo1
Link Child Fields: Field1
You can force the save of the record when a user moves off a field in the Lost_Focus event.
Private Sub MyField_LostFocus()
DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70
End Sub
I was also facing the same problem, but in another scenario. I am not having sub-form, but a datasheet view of the same table on a split screen, which was not updating immediately after save button. On pressing DUPLICATE button, instead of getting duplicate data of latest record, I was getting pointer shifted to first record, and then the data from the first record was getting duplicated.
By inserting
DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70
before data duplicating code, I am now getting the data updated immediately with record pointer stick to the current record, and the same last record gets duplicated as required.
Sharing the experience.
Thanks ChrisPadgham
Just use this in your form model:
Private Sub {your textbox name her}_AfterUpdate()
Me.Refresh
End Sub
Essentially: in the AfterUpdate event of every desired control execute a acCmdSaveRecord command.
So:
In the design view of the form click on your control.
Menu > Design > Property Sheet (to bring up the property sheet for your control)
Property Sheet > Event [tab] > After Update. Choose "[Event Procedure]". Click on the elipsis "..." to take you through to the Code-Behind-Form VBA dev environment.
Supply your code as follows ...
Private Sub [Control Name]_AfterUpdate()
DoCmd.RunCommand acCmdSaveRecord
End Sub
E.g.
Private Sub cboFinancialYear_AfterUpdate()
DoCmd.RunCommand acCmdSaveRecord
End Sub
Repeat the above for every relevant control on the form.
The acCmdSaveRecord avoids an unecessary visual refresh of the current form, as when using Me.Refresh (which #medjahed mohamed has suggested).
I have a main form that contains two other child subforms. When a textbox value changes on subform (A) I would like to set the value of a textbox on subform (B) equal to the changed textbox on subform (A).
So being completely new to Access I did some googling and it looks like this can accomplish this with some VBA. So on subform (A)'s textbox 'after update' event I have added this VBA.
Private Sub ID_AfterUpdate()
Me.Parent.Forms.formA.textboxDestination.Value = Me.textboxSource.Value
End Sub
I am doing this using the code builder. Then I save and run the form. Nothing happens. No errors.. nothing I am not even sure that piece of code is running. I'm not even sure how one debugs VBA in Access. Can someone help me out?
Thanks!
The after update event for a control fires when the user changes its value. If ID is bound to an autonumber field, the db engine will supply its value when you add a new record. However, since the user didn't make that change, the after update event does not fire.
For general debugging purposes, you can add a Debug.Print or a MsgBox statement.
Debug.Print "my event fired"
MsgBox "my event fired"
View the output from Debug.Print in the Immediate Window of the VB Editor. You can go there from your main Access window with the Ctrl+g keyboard shortcut.
Another technique is to set a break point on a line of your code. Right-click on the code line, then choose Toggle->Breakpoint from the context menu. Or click in the left margin so that a reddish dot appears to mark the breakpoint. Or press the F9 key. Or choose Debug->Toggle Breakpoint from the VB Editor's main menu.
You can also type Stop on a line by itself to trigger break mode. However, you would need to remove it later. Those other breakpoints I mentioned are temporary and don't get saved in the code module.
However you get to break mode, you can then step through the code one line at a time with the F8 key. That will show you which lines are executed. You could also inspect the value of a variable at any time in break mode by typing a question mark, then variable name, and then the Enter key in the Immediate Window:
? MyVariable
Explore the VB Editor's main menu to find additional debugging options. For example, the Watch Window will allow you to monitor the values of selected variables as you step through the code.
You don't have to specify the name of the parent form.
Me.Parent.CONTROLNAME.Value is a kind of working code.
Regards
On the update property of the textbox you are changing, put the following:
[Forms]![frmContainingValueYouWantToChange]![txtTextboxYouWantToChange] = "newValueHere"
Let us know how you get on?
I know it was 6 years ago, but I think the error here was that you were updating value from the formA to the same formA.
Me.Parent.Forms.formA actually igual to Me because you were calling :
subform (A)'s textbox 'after update' event
It should be formB and the word "Form" should be placed after (and the word "Value" isn't mandatory):
Private Sub textboxSource_AfterUpdate()
Me.Parent.formB.Form.textboxDestination.Value = Me.textboxSource.Value
End Sub
You can learn here some more informations how to Refer to Form and Subform properties and controls
Regards
I have made an Access 2007 db. I will be writing some basic vba for the appropriate event of a form so that a modal form is displayed when the original form is opened. This isn't difficult, but that form will have a drop down box of IDs from a particular table. The user will select an ID, but I want the selected ID from this form to go back to the parent form. E.g.:
Car form opened
Event is fired to open a modal form
IDs for a FK to cars has to be selected from a combobox (eg ID of driver - for simplicity, lets assume one car can have many drivers but not vice versa so 1:n only)
There is a button to confirm the selection. On clicking this button, the form closes, and the selected Driver ID is automatically inserted into a DriverID textbox on the car form (probably will be read only).
The last step I am not sure about. How can that be done in VBA?
This is one of the worst Access threads I've ever seen on StackOverflow.com, because every answer is wrong in at least some crucial aspect -- not a single one of them would actually run if you pasted them into VBA in an Access database.
The key principles here:
Open the dialog form modally (with the acDialog arguments)
Don't close it when the value has been confirmed, but instead set it's .Visible property to False.
Then in the calling form, read the value out of the hidden form, and then close it.
Something like this:
DoCmd.OpenForm "dlgPickDriver", , , , , acDialog
If IsLoaded("dlgPickDriver") Then
Me!DriverID = Forms!dlgPickDriver!cmbDriver
DoCmd.Close acForm, "dlgPickDriver"
End If
[IsLoaded is a Microsoft-provided function; I posted it here on StackOverflow recently, but would assume that the vast majority of Access developers writing VBA would have been using it forever]
I would recommend against having code that runs in the dialog form poke the data into the parent form because it's then impossible to use the dialog form in multiple locations. Having the dialog form know as little as possible about the context in which it's called is good programming practice. On the other hand, it's true the calling form needs to know the control name it's getting the value from, but that's a more sensible context than the other way around, in my opinion.
To gain 'access' (get it?!) to controls on separate running forms you can use the following:
Forms("AnOpenFormName").Controls("ControlName") = value
Edit: I used the wrong brackets AMG!
You could write a function that will display the form modally and then return the user selected value as a return value of it (similar to msgbox/inputbox).
EDIT: You could write a function such as following.
Function GetUserSelectedCarID() as string
dim myPopupForm as Form
set myPopupForm = new Form
myPopupForm.Show vbModal
GetUserSelectedCarID = myPopupForm.UserSelectedCar
End Function
UserSelectedCar is a property that stored the user selection on the popup form.
EDIT2: You could also add a property on popup form to see if the user clicked OK or Cancel.
It will return blank from the above function, if user clicked Cancel.
All of the above answers are good. I especially like the third way of wrapping this kind of functionlity into reusable function calls. The only thing I would add is do not CLOSE the modal form...otherwise you cannot get the selected value. Instead do me.visible=false.
So you do somethiing like this.
Public Function GetCArKey as Integer
dim intReturn as integer
docmd.openform "MyModalForm",,,,,,acdialog
'(the click event of the okay button of this form does me.visible=false...clicking Cancel will close the form.)
if isloaded("MyModalForm") then
intReturn=Forms("MyModalForm").Controls("ControlName").Value
end if
GetCarKey=intReturn
End Function
It would seem much easier to me to create a global variable in a module (eg Public gi_Value as Integer) and then set this in the child form. The value can then be read anywhere.