I have an Access form with two subforms, both in continuous mode. Since I cannot have a subform inside a continunous form, I had to do it that way (Datasheet is not an option either)
Either way, when I click on my first subform, I change the other subform record source using some rather simple code :
Public Sub MAJFiltre(intIdMembership As Integer)
IdMembershipFiltre = intIdMembership
Me.RecordSource = "SELECT * FROM T_PeriodeMembershipPartipant WHERE IdPeriodeMembreship=" & IdMembershipFiltre
Me.Requery
End Sub
This function is called from the first subform. I did this for another form and it was working fine. For this one, if I use a breakpoint, I can see the recordsource is changed, but nothing happen in the UI. However, if I put a breakpoint in a BeforeInsert event, I can clearly see the recordssource reverting to the original one (with no WHERE clause)
I also notice something unusual : If I save the form code while debugging, all of a sudden, it works. However, as soon as I close the form, it revert back to its "buggy" version.
Does anyway have an idea of what is going on and how I can correct /prevent it ?
Thanks
It sounds similar to a problem we suffer periodically, which relates to subforms linked to a parent form with link master/child ids: If you've (ie Access has done it for you) unintentionally saved a filter value as a property in one of the subforms, (filter by or in a record source), when your code reassigns the record source, this saved value prevents the new record source from being assigned correctly, and ms access then does what it thinks is best - in this case, reverting to the valid (prior) record source.
Check your subforms for unwanted saved values of data-tab properties.
Could the problem be that your field name is misspelled in your query criterion?
IdPeriodeMembreship
If the field in your T_PeriodeMembershipPartipant table is IdPeriodeMembERship instead of IdPeriodeMembREship your query would likely prompt you to enter the parameter value manually when it is run.
If that field does exist in your table but the value you're specifying in your criterion isn't found in that field, it will return no results and the second subform's recordsource will be set to an empty recordset.
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.
Instead of using DoCmd.OpenQuery "qrySearch", , acReadOnly to view the results of a query I'm looking at using a form instead to help with presentation, including a couple of command buttons for things like export to Excel etc.
Note that the query can display a variable number of fields depending on the user's chosen criteria.
To do this I created 2 forms: frmResults and frmSub
frmSub was placed within frmResults by dragging frmSub from the Forms tab into frmResults (opened in Design view).
Under Properties of the frmSub:-
Source Object was changed from frmSub to Query.qrySearch.
The Name set at frmResultsSub
Since the original frmSub is now no longer used, I've deleted it (at least, with my limited Access experience I'm assuming it's safe to do so since there appears no effect on the query getting displayed in frmResults - the form displays nicely and the fields and field numbers vary according to the search criteria.
Question:
If the user performs another search, and frmResults is currently open, in order to update the results I have to close frmResults and Open it again. This does work but I'm thinking it's not the recommended way - is there any way to refresh frmResults while it's still open? I've tried various permutations of
Forms!frmResults!frmResultsSub.Requery / .Refresh
from behind the Search form itself but nothing works.
[ms Access 2003 compliance still required]
EDIT: based on HansUp and Alexander's 1st replies...
Alexander: the .Requery (/frmResults display) takes place close to the end of the VBA behind the Search button on form used to take in the user search criteria (frmSearch, a separate form not detailed above)...
If CurrentProject.AllForms("frmResults").IsLoaded Then
Forms!frmResults!frmResultsSub.Requery
Else: DoCmd.OpenForm "frmResults"
End If
--> it's the Forms!frmResults!frmResultsSub.Requery that is not updating for a new user search on the currently opened frmResults form.
HansUp: replacing the above line
Forms!frmResults!frmResultsSub.Requery
to
Forms!frmResults!frmResultsSub.SourceObject = "Query.qrySearch"
...did the trick, and works well - all new searches on an already open frmResults are updated without having to re-open the form. But I'm confused!...I though I already set SourceObject of the subform to the same value as detailed above (under the subform's properties in design view) - why does Access not honour this setting?
In your example code ...
Forms!frmResults!frmResultsSub.Requery
... frmResultsSub is a subform control which contains a query instead of a form. In other words, its SourceObject property is set to "Query.qrySearch".
In that situation, Requery of the subform control does not recognize changes to the query design.
Setting the subform's SourceObject property to its original value is enough to make Access recognize the query design change ...
Forms!frmResults!frmResultsSub.SourceObject = "Query.qrySearch"
I am completely new to VBA. I have been told to add records to a table by using a form and a Save button and given some very basic instructions. While I have achieved this with inline query, I have been told to follow some strict methods like usage of QueryDef/QueryDefs and .Parameters.
So far I am trying a very basic project, just to grasp the concepts, but I am unable to add any record to an empty table. In case the table is not empty(I manually enter a record), whenever I click the Save button for saving newer records, the number of records added are somehow doubling with each instance. For example, when I Save for the 1st time, 1 record is added, 2nd time 2 records of the same type is added, 3rd time 4 are added and so on.
The table(tbl_test) has 2 fields --> ID(primary key), Source(Long Text) and Reg No (Number).
The query(qry_test) is made with the Append feature and I have been told to add expressions which makes the code like this -
INSERT INTO tbl_test ( Source, [Reg No] )
SELECT [strSource] AS Expr1, [lngRegNo] AS Expr2
FROM tbl_test;
The form has 2 fields for Source(txt_Source) and Reg No(txt_RegNo) which have blank Record Sources (Unbound). The Save button has the following Event Procedure -
Private Sub btn_save_Click()
Dim qdf As QueryDef
Set qdf = CurrentDb.QueryDefs("qry_test")
qdf.Parameters("strSource") = Me.txt_Source
qdf.Parameters("lngRegNo") = Me.txt_RegNo
qdf.Execute
End Sub
I have zero knowledge about VBA and would gladly accept ANY help. It would be great if I get any sort of source code that will explain to all the details about saving records from forms and editing them using these querydef, parameter and recordset stuff.
Welcome to StackOverflow!
If you are using a form to collect data for records that are stored in a table, running a saved append query by QueryDefs to do this is, in my opinion, not the best method.
Whilst an append query does add new records to an existing table, I would tend to use an append query where I've got multiple established records that I want to add to an existing table.
If I'm setting up a data entry form that is designed to collect new data for new records 1-at-a-time, an append query doesn't really suit this purpose.
Instead, there are a number of features built in to the design of MS-Access forms to help collect data and save it to a table. This is because forms are very much intended to be set up so that users can interact with records from a table in a controlled, user-friendly way rather than interact directly with the table object itself.
The first and most important feature of a form in this context is probably the form's record source property. When you create a new form, go in to design view for the form and open the form's property sheet (F4 key). In the "Data" tab of the form's property sheet you'll find the record source property:
The record source essentially connects your form with a set of records, whether those be records in a table object, a query object or an sql query string.
In your case it would be better, in my opinion, to bind your tbl_Test table to your form by referring to it in your form's record source:
It will seem like nothing has happened to your form, but if you now open the "Add Existing Fields" panel (alt + F8), you'll notice that the fields associated with your tbl_Test table are available to you:
Drag them to the detail section of your form...
Then put your form in to Form View:
Essentially what you and your users are seeing is the first blank record in your tbl_Test, but displayed on a form instead.
Entering data in these fields on the form...
...will put that data in to the table we specified in the form's record source...
So hopefully you can see that setting the form's record source property to that of your table, is much cleaner than trying to get an append query to collect data from your form and deliver it your table.
At this point you're probably asking a few questions:
When I have filled in the fields for a record on my form, how do I save that record?
More can be said about this, but for brevity, I'd recommend using a command button for running some vba to save the record; similar to what you've done, but utilising the form's Dirty property instead using an append query:
Here's the click event VBA for my save button example:
Private Sub cmdSave_Click()
If Me.Dirty Then
Me.Dirty = False
End If
End Sub
Me.Dirty is a Boolean (True or False) setting for the form; essentially it is automatically set to True when a user changes something on the form. To save those changes, the Me.Dirty setting will have to be set to False.
Me.Dirty is a bit like the swing gate on a sheep pen. When a shepherd puts a sheep (data) in the pen (form) they will open the gate to the pen. The open gate is like the form's Me.Dirty being set to True. To lock the sheep (data) in, the gate needs to be closed, or in the case of forms, the Me.Dirty property needs to be set to False. The VBA above essentially checks to see if the gate was opened and if it was to close it.
How do I move to a new record in the form once I have saved the current one?
Again, I'd give the user a command button to do this and run some VBA on its click event:
Here's the VBA for moving to a new record:
Private Sub cmdNew_Click()
DoCmd.GoToRecord , , acNewRec
End Sub
Summary
There is a lot more to consider than what I've outlined here, such as:
validating data before it is saved
checking other form events (such as close) to ensure data entry is not lost
navigating to an existing record
But hopefully what I've given you here is at least pointing you in a better direction. Best of luck!
Access is optimized for bound forms. Unbound forms are for special cases only.
Should you prefer unbound forms (could be for many reasons), Access isn't worth the trouble, and you should turn to Visual Studio and WinForms.
In either case, browse for a beginner's tutorial.
If you want to use an unbound for or unbound controls you can create the SQL string in the procedure:
Dim mysql as String
mysql = "INSERT INTO tbl_test ( [source], [reg_No]) VALUES (Me.txt_Source, Me.txt_RegNo)
DoCmd.RunSQL mysql
So in MS Access 2010 I have a main form for viewing client details, and tabbed subform navigation with subforms showing information in different tables for said client. On one page, i have a combobox to select a date for viewing a testing session related to the client. I am trying to get the first combobox value to be selected automatically when the user goes to this tab and/or cycles through other users while viewing this tab. My simple VB code is below:
Private Sub Form_Current()
Me.DateOfScreening.Requery
Me.DateOfScreening.Selected(2) = True
End Sub
The requery command is executing (paging through different clients will update the combobox values, and commenting that line out stops that behavior, so I know this code block is getting executed), but the Selected command appears to not select anything.
I hope I am just missing something obvious
For some reason, setting the selected row index for a combo box has not behaved well for me.
Could you just set the combobox value directly, as in
Me.DateOfScreening = "yourValue"
Also, when referencing the control, you can use either
me.dateofScreening.column(0) 'if 0 is your bound col index
or maybe
me.dateofScreening.itemdata(0)
Also, could you do a debug.print(me.dateofScreening.column(0)) or msgbox (me.dateofScreening.column(0)) and let me know if it says anything.
As in the title I cam across a strange phenomenon. I have a form which contains two subforms. On both subforms I have a button which triggers requery of the relevant subform. If after loading the form, I immediately click on this button (requery the form) I get error "3021: No current record" when I try to save the value of the primary key of the current record in the OnCurrent event to a variable. Strangely enough in the debugger the relevant values are like this:
Form.CurrentRecord=1
Form.RecordSet.Absoluteposition=-1
Form.RecordSet.RecordCount=14
Form.RecordSet.EOF=False
Form.RecordSet.BOF=False
Also note, that when the form is loaded, in the load event it still works correctly and the there I can save the primary key value which is the primary key contained in the first record.
Somewhere between Form_Load and me clicking that requery button the status of the form is getting out of synch. I just recently switched from Access 2003 to 2007 and as far as I can remember this error did not happen before (although I might just not click this button right afer load).
For now I have a workaround, but I'd really like to understand how this can happen.
If this is ADO, check which OLE DB provider is being used e.g. (guessing)
Debug.Print Form.RecordSet.ActiveConnection.Provider
If by chance it is the 3.51 version, see:
INFO: AbsolutePosition Property with JET Databases in ADO
...if you are using the ACE provider, perhaps it's a regression bug?!
You have to place the record pointer on a particular record in the form's Recordset via a MoveFirst or whatever. And the return value appears to be zero-based instead of 1-based.
I can't reproduce the error you're getting returning -1. Are you setting the form's recordset to an ADO recordset? If so, that might explain it -- DAO recordsets never return -1 for any of these values, but I believe that before a .MoveLast an ADO RecordCount returns -1. Perhaps AbsolutePosition does the same in ADO.
What are you trying to accomplish? I don't see any utility in using the form's Recordset object when it's so much easier to assign a recordsource and navigate the RecordsetClone (which is much more closely bound to the form's edit/display buffer than the form's Recordset, particularly when the Recordset has been assigned with an ADO recordset).
I have the exact same problem when I try to go to "Design View". I don't need to click quickly, I can wait an hour and then do that and bang! there is this error.
Note that I only get the error if the sub-form is still empty (i.e. really does not include any records which is the case when I first open the window.) So I always thought that was normal.
The AbsolutePosition is set to -1 when the cursor is not currently pointing to a specific position. Also, this value is zero based (as mentioned by someone else: first row is AbsolutePosition 0). However, this position may be -1 even if you have focus on a specific row in the sub-form. This means it is useless.
What you want to use if you need to know the current cursor position is CurrentRecord. This is a number that starts at 1. I would imagine that if the list is empty, the CurrentRecord may be set to 0 or -1 representing the fact that no row is available.
I used all of these in a function used to calculate a complex total of different columns, here is the page http://linux.m2osw.com/msaccess-sum-focus-recordset-problem