I have an MS Access form, that contains a subform whose recordset is a query that takes quite a while to process and isn't actually needed right away when the parentform is opened, but only after a button on the form is pressed.
Is there a way to implement this with VBA other then completely changing the form with something like Set Me.MySubForm.Form.Recordset = NULL? I've tried Me.MySubForm.Enabled = False but that doesn't work unfortunately.
The easiest way:
Leave the SourceObject property of the subform control empty. Then when the button is pressed, do
Me.MySubForm.SourceObject = "mySubFormName"
This way the subform and its data isn't loaded until needed.
Related
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.
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 am working on an MS Access Form. I am trying to have a Combo Box on the form who's list is narrowed based on information earlier in the form. I have a Query saved in the database that gets the list properly.
The problem I am having is that the query is not called after each update of the form so the Combo Box's list is always what it was when the form was opened.
I have tried to force an update using Me.MyComboBox.Requery in the AfterUpdate event of the previous control but this only requeries the record source of theform, not the row source of the Combo Box.
I have also tried changing the row source property to force a requery but that did not work eithier:
Private Sub PreviusControl_AfterUpdate()
Me.MyComboBox.RowSourceType = "Table/Query"
Me.MyComboBox.RowSource = "qryDynamicComboSource"
End Sub
Thanks in advance!
It looks like everything you're doing is correct. Check your query design if it's actually changing based on your parameters.
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
MS Access 2007, Win 7 32-bits
Is there a way where I can access an open query in datasheet view in access to get the current field value and current field name?
I won't put it into a form since it is a crosstab query and i'd have to generate and get rid of controls dynamically but i'm not fond of messing with forms controls that way with VBA. I know i can put a dynamic column report and bind an event on the controls but I'm asking if there are events or objects that can let me access directly the query.
Perhaps a recordset clone? But I haven't find anything on google.
Of course this is in VBA
Best regards,
It may be possible to work around your requirements. The crosstab is contained by a subform:
Source Object : Query.xtab
The Control Source for the two textboxes is:
Ctrl : =[screen].[activecontrol].[name]
Content: =[screen].[activecontrol]
Which means they show which ever column ans column contents the user selects in the crosstab subform. However, they will also show any other selected control on the form. ClickMe does not change the selected control, so the selected items remain the same in the textboxes.
You can also enter MacDermott's code for getting the current control's index, so the current control selected on the xtab query subform is displayed dynamically
Public Function ControlIndex(ctl as Control) as long
Dim i as Integer
For i=0 to Me.Controls.Count-1
if me.Controls(i) is ctl then
ControlIndex=i
exit for
end if
next
End Function
And finally this can help when changing from one control to another in the same record to keep the textboxes current.