I am at a loss as to why I am getting a run time error message saying that the record set is not updatable for a simple table which I created and sourced in a new form not dependent on anything else. Is it possible the database settings have somehow changed causing me this strange issue. How is this possible?
Some more details would be needed.
Anyway, how are you trying to modify the recordset? Via VBA?
I suggest some things you can try:
Open form properties --> Data tab and check that Allow modifications is set to Yes as far as Allow Additions and so on
1) You are trying to access the record before updating
2) In VBA you didn't invoke the .Edit method before trying to modify the record.
3) The form has a query as record source and the query is not updatable
The case 3) is the most complex of the three. It can be due, for example, to:
- Presence of total clauses like GROUP BY, COUNT, SUM that means that a record represents a set
- A calculated field that can't be updated
- Lack of permission to modify the table / query
Related
I have a two table scenario with a typical parent / child relational setup:
tblGroup - idGroup (autonumber, PK); GroupName (Short Text), Rank (Number)
tblRange - idRange (autonumber, PK), idGroup (FK -> tblGroup.idGroup), RangeName (Short Text), Rank (Number)
What I am doing on the parent (tblGroup) table is using a data macro to add the rank using the BeforeChange event:
IF
IsInsert
SetField - Rank
- DMAX(Rank, [tblGroup])+1
This works nicely and I can happily use a parametized INSERT query to add rows to the table and not have to worry about duplicate ranks and so forth.
What I would like to be able to do but cannot figure out how, is to have a data macro do the same thing for the child (tblRange) table, with the rank being set to the new highest for the parent group the child record belongs to.
If I use the same DMAX approach as I have above I am supposed to be able to set a criteria as a third option, acting like a where clause, to limit the lookup / calculation. How can I refer to the specific idGroup I am working with in tblRange in the macro? I cannot seem to figure out how to reference the new records value for this in the macro.
Something like DMAX(Rank, [tblRange], ???How_to_refer_to_idGroup_Properly???)+1
Any help greatly appreciated
Cheers
The Frog
I figured out a way to do this. Thankyou caffeinated beverages!
The reason for the strange error messages is due to limitations in the Data Macro processing, specifically in the BeforeChange event. The solution is as follows:
Create a query that selects MAX rank (MaxRank) and GROUP BY for the idGroup (ParentID)
The resultant query produces two columns of data: [MaxRank] and [ParentID]
There will be a row for every idGroup with the maximum Rank for each
Create a BeforeChange data macro
Set the following:
IF IsInsert
LookupRecord
Lookup Record In - qryGetMaxRank (or whatever you called your query)
WHERE - [qryGetMaxRank].[ParentID] = [tblRange].[idGroup]
Set Field
Name - [tblRange].[Rank]
Value - [MaxRank] + 1
The BeforeChange event cannot handle parameters for a query, and I am guessing that this applies in some form the to DMAX function here too. The use of a query that does not use any parameters, and then using the LookupRecord WHERE clause to do the filtering provided the single row result needed. The [MaxRank] value from the returned result is then able to be used to set a new value for the field.
Bit of a workaround but it does allow someone to work with the data either through a form or through the datasheet view and not create a problem.
**In answer to if this is a multi-user DB - it is not. It is just me working with it. If / when the solution is scaled up to something requiring multi-user I will likely recreate the BE in SQL Server or MySQL and use stored procedures for all data I/O. Happy to keep Access as the FE and compile into an application (using the runtime for clients), but I am a fair way off from having to do that yet. Very early stages of development at this time.
Cheers to everyone for the pointers. They helped me figure this out. Hopefully this will be of use to someone else in the future.
PS: If you need to use a parametrized query in a data macro it looks like the best bet is with the AfterInsert event or AfterUpdate event as they can support parameters.
I like to use an unbound subform to display the result of an crosstab query. However following code
Me.subFormForecastSummary.Form.RecordSource = "SELECT ....."
results in this error message: "The expression you entered refers to an object that is closed or doesn't exist".
When I use the Source Object in the form designer and specify the select statement, then the code above works fine and I am able to set the property RecordSource.
The issue I am facing is that the select statement is based on a crosstab query and can contain a different number of columns (in my case weeks) depending on the master record. The issue I am facing is that the datasheet only displays the columns as per the original query specified in SourceObject (the data itself is refreshed though). Does anyone know how I can force the columns to be refreshed as well or how I can get overcome the error message?
Thanks
Thanks for the responses thus far. Based on the comments and further research I have decided on following solution:
Created a dummy query returning 1 record with the maximum number of columns. I have named them 001 trough to 100
Still created a subform and bound it to the dummy query
In VBA I then change the recordsource at runtime as required
Also in VBA rename the captions as required
You would think there should be a more elegant solution, but this works for me
I want to preface this by saying I don't have any real programming background, I'm just trying to update an existing database at work.
We have an access database and I want to add an additional Y/N checkbox to an existing form. The form updates a SQL table. Currently the record source is a SQL statement.
I can go to the SQL table, add a new field and make it Yes/No data type. There are other Yes/No fields in the table and the default settings for the new field are identical to the others. I next go and update the linked table through External Data in the ribbon. I can go into the table in Access and see the new field - so far, so good.
Next, go to the form design view and form properties, go to the record source, update the SQL statement to include the new field. (I've also tried this thru query builder, same result.) From here, I start to get the error.
If I go back to form view and change any data in the form and hit the next record button or save button, I get the Write Conflict error. "This record has been changed by another user since you started editing it..." The 'Save Record' button is greyed out. I am the only person accessing the database or SQL server.
I've tried to finish building the new button and linking it to the new field in control source (that went fine), but it didn't make any difference. If I go in to edit the record source and remove the new field, everything works again (but of course, the new field isn't in the control source list, so isn't linked to the check box).
Any ideas? Thanks.
A strong contender for the reason for your problem is the form itself.
Most likely the form is setup with a specific query as the Record Source. Its not to say that that is inherently incorrect, but it makes adding new columns to the source significantly more difficult.
The problem would likely be solved if you just changed the Record Source to reference the table itself, rather than a query, if that is in fact how it is referenced.
If Ms Access tries to pull data from a table using a query through a form it will inherently Pessimistically Lock the table in question, making it unable to be modified. However, you can usually still modify the table through the query itself, but you would need to add the column changes into that query first.
I'm not quite sure if I am making sense here, but something like this (for a table called "Table1"):
In theory, if the form is the problem... then if you closed it and tried to make modifications to the table, then the changes should work when the form is closed.
Someone else fixed it for me, but from what I understand, it was a communication issue between SQL and Access. Something with the setting of the null value in SQL not being set the way that Access could understand.
We had the issue narrowed down. When the new field was added to the table, you couldn't change any info directly in the table, but you could with the form.
If you added the new field to the form's record source, you couldn't edit any info at all.
Thanks for everyone's input.
I'm trying to create a database in Access 2010, and have run into a bit of a problem. I currently have two tables, EarlyStageListResults & ESDailyTotals. Each of these tables has a field named Records, with ESDailyTotals being a summary of multiple entries in EarlyStageListResults. What I need to do is have the Records field in ESDailyTotals be the sum of multiple Records fields in EarlyStageListResults. For example, given the following records in EarlyStageListResults:
Date Records
4/22/16 2000
4/22/16 3000
4/22/16 1500
4/21/16 1200
4/21/16 2700
the records in ESDailyTotals should be:
Date Records
4/22/16 6500
4/21/16 3900
I know this can be calculated later through VBA and a form event, but optimally I'd like to be able to have it update as soon as any of the Records fields in EarlyStageListResults changes. It looks like there may be a way to do this using the Access Macro Editor (not sure of the name, but the tool where you can create a macro through a series of combo boxes rather than through VBA), but I've never gotten an understanding of using that tool, so have always relied on Forms and VBA instead. Basically if there's an event that triggers when a field is updated, and a way to enter VBA code into that event handler like you can with Access Forms, then I can do it with either DLookup or an SQL statement I think, but I don't know how to grab that event handler.
This does all need to be done within Access itself, I can't use an external program to update the records in an Access database file. This is for work, and (officially at least) any custom programs are a big no-no. :)
Thanks in advance everyone!
You're making this way too complicated. You just need one table and a database view (called a query in Access, I think) that is defined as
select Date, sum(Records) as Records from EarlyStageListResults
group by Date
Name the query ESDailyTotals.
i'm wondering if anyone has a solution for an issue i'm currently having with my Access database.
The database has a number of tables. Once a new record is added, i'd like to create a new entry (copying over the account name and phase automatically if it doesnt exist) into another table - saving others having to manually enter it & minimising the risk of incorrect data input.
I've tried an onChange update function, and while this works, it doesn't check if the entry currently exists in the other table, it just adds it.
Any ideas on implementing this?
If you can use VBA, this logic should work.
IF ISNULL(DLOOKUP("FieldName","TableName","WHERE CONDITION")) = True Then
DoCmd.OpenQuery "QUeryNameForAppendRecord"
Else:
DoCmd.OpenQuery "QueryNameForUpdateRecord"
End If
The DLookup is checking to see if the record exists, so substitute the field and table names accordingly. Use the Where condition to specify which record you are looking for and you will need to use it to reference your form controls. See link for further help in syntax/referencing.
DLookup Function