Access Set Unbound Form to Current Record - ms-access

First post so hoping this makes some sense. I’m adding data to tables from unbound text boxes using a command button and the .AddNew method. The form itself is still bound at this point. FYI, I’m using unbound boxes as the UI needed for junction tbls was not an option. I’m able to add the data to the tables without a problem. The issue is that after adding a record, the form’s current record stays on the same record as before the addition but I want it to be on the new record. I’m using “rst.Bookmark = rst.LastModified” to set the cursor to the new record in the table and seems to work as I can return values for the new record ... but this does not affect the form. I’ve tried working with “Requery” and “CurrentRecord” but neither resolves the issue.
In summary, after adding a new record to a table I want the form’s current record to reference this new record. For example, if I am on record 12 in the form and add a new record bringing the total records to 25 -- I want the form to be on record "25 of 25" not on "12 of 25". Can you tell me how to do this? Thanks for your help!
With rst
.AddNew
!Event = Forms!MainForm!Event
!DonorName = Forms!MainForm!DonorName
!EnvNo = Forms!MainForm!EnvNo
.Update
.MoveLast
.MoveFirst
End With
rst.Bookmark = rst.LastModified
''' Record count total - show on form - confirmed/same as Access Navigation display
Forms!MainForm!txtTotalRec.Value = rst.RecordCount
''' Current Record - show on form - confirmed/same as Access Navigation display
lngCurrent = Forms!MainForm.CurrentRecord
Forms!MainForm!txtCurrRec.Value = lngCurrent

as per your trial. simply perform a DoCmd.GoToRecord acActiveDataObject, , acLast after a me.requery to update the recordset.

it should work, because the addnew method does not require movelast action. you can try refreshing the form with set me.recordset = me.recordset

Related

How to fix “Could not update; currently locked” caused by using DAO.Recordset2.Edit while a form is being edited

DAO.Recordset2.Edit is causing a “Could not update; currently locked” error.
I want to save the edited form, update the record and refresh the form.
But all attempts to save the form fail to fix the error. They fail to clear the record lock. Closing the form clears the lock, but that is messy, looking for a better way.
Steps:
typed data into a form.
Clicked a button that triggers:
' saves the form but does not clear the record lock
If Me.Dirty Then
Me.Dirty = False
End If
click another button that triggers adding a photo:
Private Sub EndPhotoTaking_Click()
Dim attachmentField As DAO.Field2
Dim photoItemRecordSet As DAO.Recordset2
With [Forms]![Inspection - All sub sections].Form
Set photoItemRecordSet = .Recordset
End With
Set attachmentField = photoItemRecordSet("Photo")
Set photoItemAttachment = attachmentField.Value
'---- error “Could not update; currently locked” on line below
photoItemRecordSet.Edit
Then I get the error “Could not update; currently locked”.
I am using VBA to add a picture into the record, but it is not working. It does not work if the record has been changed in any way.
It is running the Line of code "Me.Dirty = False", so this saves the record. But then I get the error. I only get the error if I enter data into the from.
The form that I enter data into contains a subform, would that have an impact? I suspect it does because I have another form that does not have a subform and it works just fine with the same code. Is there anything that would cause "Me.Dirty = False" to fail to clear the lock.
I have also tried "DoCmd.Save acForm, formName", but that did not help.
The table is sharepoint list style.
Edit
Added extra code to show origin of photoItemRecordSet.Edit
updated title and description. Added details to say saving the form is not clearing the record lock.
Workaround: close the form. Update the record. Reopen the form.
This works but is less than ideal.
Use the RecordsetClone:
Set photoItemRecordSet = .RecordsetClone
photoItemRecordSet.Bookmark = .Bookmark
I was having a similar problem, the record was saved and a requery didn't help. I was finally able to set the form RecordSource to the recordsource that I originally had it set to again, navigate to the record I was on and then the add photo worked.
I put this code in the Error Handler;
If Err.Number = 3218 Then
rstEmployee.Close
Set rstEmployee = Nothing
Me.RecordSource = "qryPersonnelData"
Set rstEmployee = db.OpenRecordset(strSQL)
DoCmd.SearchForRecord , "", acFirst, "[ID] = " & thisID
Resume
I hope this helps someone.

Access 2010 New Record with Phantom Data

Access 2010 here.
I have a nagging concern with two of my three subforms. The subforms are each bound to their own table with unique information; the main form is also bound to its own table. All three subform tables are in a one-to-one relationship with the main form table. My first subform acts normally in that when there is a new record, all of its bound entry fields are displayed blank. The code in Form_Current():
Private Sub Form_Current()
'Determine what should be displayed'
'Do stuff to prepare the current record for display'
If Me.NewRecord = True Then
Me.Stuff = Null
End If
End Sub
is present for all three subforms and the main form to display older records and to ready the form for data entry by resetting check boxes etc; there is no code to "reset" the entry fields themselves. Unfortunately, the other two subforms retain data from the last entered record and display it as if the user wants to re-enter the same data. The thing is, this data means nothing unless the user explicity enters the data entry field and then leaves it by any means. Simply moving on to the next record without entering the data entry fields doesn't save the phantom pre-entered data (which is expected as the record in the subform was never made as the user never entered data in the subform).
What I am looking for is either a form-specific option to open a clean record by default, or VBA code that can ensure empty data fields on new record. I have tried actively re-querying the subforms when a new record is opened in the main form without success. I have also tried pre-setting values to "" upon entering a new record, which did work to an extent, but seeing as one subform works properly, I am after a solution, not a workaround.
Go into Design View on the subform, and in the subform's properties find the setting called "Data Entry".
Changing that to "Yes" will change the subform's behavior.
From then on all the subform do is be clear and ready accept data for new records. After a record is entered, the subform is cleared and will be ready for another brand new record.
This option is available for any form.
I would update the other two subforms with this setting. Easy, and no VBA necessary!
Continuing Thoughts:
What I found with the "Data Entry" setting set static to "Yes" on a subform is that old-record browsing functionality no longer worked. New records were clean of old data, but now old records also didn't show what had been entered; because the "Data Entry" setting prepares them for new data. What had to be done was actively set the "Data Entry" setting on each subform depending on if the record was "New" or not:
Private Sub Form_Current()
'Determine what should be displayed'
'Do stuff to prepare the current record for display'
If Me.NewRecord = True Then
Me.Stuff = Null
Me!SubFormName0.Form.DataEntry = True
Me!SubFormName1.Form.DataEntry = True
Me!SubFormName2.Form.DataEntry = True
Else
Me.Stuff = DatabaseNumbers
Me!SubFormName0.Form.DataEntry = False
Me!SubFormName1.Form.DataEntry = False
Me!SubFormName2.Form.DataEntry = False
End If
End Sub
Thanks again for the help!

How to directly update a record in a database from a form number (Access 2007)

I have a job-tracking system, and there is a query that returns results of all jobs that are overdue.
I have a form that displays each of these jobs one-by-one, and has two buttons (Job has been completed, and Job not completed). Not completed simply shows the next record.
I cannot find a way to get access to the current record to update it's contents if the "Has been Completed" button is pressed, the closest I can get is the long number which represents the records position in the form.
The VBA to get the index of the record in the form is as follows.
Sub Jobcompleted(frm As Form)
Dim curr_rec_num As Long
curr_rec_num = frm.CurrentRecord
End Sub
This is my first shot at VBA, and after an hour of searching I cannot find anything to solve my problem.
Am I going about this the entirely wrong way? Working in Microsoft Access 2007
Further Info All tables are normalized
Vehicle Table: Contains vehicle_id(pk), as well as rego and model etc
Job Table: Contains job_id(pk), vehicle_id(fk) and other info about what needs to happen, as well as the next occurance date, days between each occurance of the job (all jobs repeat) and other info
Job History Table: Contains job_history_id(pk), job_id(fk), date completed and comments
When the job completed button is pressed, it should create a new entry in the job history table with the current date, any comments and the job id
This is the script I am trying to get working
Private Sub Command29_Click()
Dim strSQL1 As String
Dim strSQL2 As String
Set Rs = CurrentRs
Set db = CurrentDb
strSQL1 = "INSERT INTO completed_jobs(JOB_ID, DATE_COMPLETED, COMMENTS) VALUES " & Rs!job.ID & ", " & Date
db.Execute strSQL1, dbFailOnError
strSQL2 = "UPDATE job SET JOB_NEXT_OCCURANCE = JOB_NEXT_OCCURANCE+JOB_RECURRANCE_RATE WHERE job.ID = Rs!job.ID"
db.Execute strSQL2, dbFailOnError
End Sub
Note: Line Set Rs = CurrentRs is completely incorrect, I believe this is what I need to figure out? This is called on button-press
I am posting an image which shows the form (non-continuous).
#HansUp, I get what you are saying, but I dont quite think it's applicable (I did not provide enough information first time around for you to understand I think)
#sarh I believe this Recordset that you are talking about is what I need, however I cannot figure out how to use it, any hints?
#Matt I am 90% sure I am using a bound form (Like I said, new to Access, been looking at everything people have suggested and learning as I go). There is of course an ID for the job (Just not shown, no need to be visible), but how would I access this to perform an operation on it? SQL I can do, integrating with Access/VBA I am new at
As I understand your situation, your form is data-bound bound (you can get record index), so - your form already located on this record. If you need to update some field of underlying dataset, you can write something like
Me!SomeField = ...
DoCmd.RunCommand acCmdSaveRecord
If your form has control bound to "SomeField", then the form will be updated automatically.
If this will not help, you can look to a couple of another directions:
1) Update records using SQL code. For example, you have ID of record that should be updated in the form data set, so you can write something like:
Call CurrentDB.Execute( _
"UPDATE SomeTable SET SomeField = SomeValue WHERE SomeTableID = " & Me!SomeTableID, dbSeeChanges)
2) You can look at the Bookmark property - both Recordset and Form has this property, it describes the record position. So you can write something like this (not the best example, but can help you to get an idea):
Dim Rs as Recordset
Set Rs = Me.RecordsetClone 'make a reference copy of the form recordset
Rs.Bookmark = Me.Bookmark 'locate this recordset to the form current record
Consider a simpler approach. I doubt you need to be concerned with the form's CurrentRecord property. And I don't see why you should need a command button for "Has been Completed" and another for "Has not been Completed".
Add a "Yes/No" data type field to the table which is used by your form's record source. Set it's default value property to 0, which represents False or No. Call it "completion_status". Create a new form using that record source. Then your form can have a check box control for completion_status.
Newly added records will have False/No as completion_status --- the check box will appear unchecked. The completion_status for other records in the forms can be toggled between Yes (checked) and No (unchecked) using the check box control.

How To Refer To Continuous Subform Contol

I have an Access 2003 form with one subform, set to continuous forms, in a subform control. For one record in the main form, 1 to many records will appear in the sub form. The data displays properly.
The main form is named Widgets and the sub form is named Transactions. There are 5 textbox controls that display the data in the subform. The one in question is ReceiptDate.
What I would like to do is look at the values and determine if there was a receipt for the year 2009, and if so then change the background of that row to yellow so it stands out when the user encounters that condition. Maybe even change the date field's font to boldface..
I tried many ways of referencing the subform's controls. When I have tried Me.Transactions.ReceiptDate I have only received the first record in that subform. I'd like to be able to loop through them and see if the condition is met. I tried Me.Transactions.ReceiptDate(1) and Me.Transactions.ReceiptDate(0) and so forth.
I tried the For Each ctl In Form.Controls route as well. It worked for a few iterations and then I received a run-time error 2455 "You entered an expression that has an invalid reference to the property Form/Report".
I had the subform in "datasheet" mode but thought that was causing me not to be able to read through an array of subform controls. So I changed it to "continuous" mode. I get the same errors for either.
Is there a way to reference specific "rows" in the subform and do something based on a value found? Also, I am performing this in the On Current event as I dont know where else to put the code. The subform loads before the parent form so its possible that these controls arent even fully "there" but then I do get the first row's date when I try it in the Immediate Window.
UPDATE 12.23.2010:
With the gracious help of #Remou I am able to debug.print the ReceiptDate fields from the RecordSet. This is great because now I can evaluate the data and do certain things based on the values.. The #Remou's code helped me put this into the OnCurrent event:
Dim i As Long
Dim frm As Form
Dim rs As DAO.Recordset
' Get the form and its recordset.
Set frm = Me.Form
Set rs = frm.RecordsetClone
' Move to the first record in the recordset.
rs.MoveFirst
' Move to the first selected record.
rs.Move frm.SelTop - 1
' Enumerate the list of selected records presenting the ReceiptDate field
For i = 1 To rs.RecordCount
Debug.Print rs![ReceiptDate]
rs.MoveNext
Next i
So now that I am able to know which row in my subform has a receipt from 2009, I need to be able to highlight the entire row or rows as I come across them in that for loop. How can I reference the actual row? Datasheet view or Continuous Forms view - I have tried both.
Conditional Formatting is great but it only allows me to highlight one particular record and I'd much rather be able to do this via VBA because...... from here I will want to give the use the ability to click on any record in the subform and get the receipt details and potentially print them.
Any ideas?
In this situation, it is best to use conditional formatting.
To refer to a control on a subform, refer to the subform control by name, then the form property to get the form contained, then the control by name:
Me.MySubformControlName.Form.MyControl
See: http://www.mvps.org/access/forms/frm0031.htm
I have finally got it. The frm.SelTop = x will set the selected record and from there I can set the background or font style, etc.. Very cool. A simple test for 2009 and setting the selected record:
Dim i As Long
Dim frm As Form
Dim rs As DAO.Recordset
' Get the form and its recordset.
Set frm = Me.Form
Set rs = frm.RecordsetClone
' Move to the first record in the recordset.
rs.MoveFirst
' Move to the first selected record.
rs.Move 0
' Enumerate the list of selected records presenting
' the CompanyName field in a message box.
For i = 1 To rs.RecordCount
If Year(rs![ReceiptDate]) = 2009 Then
frm.SelTop = i '<-----------------------------
End If
rs.MoveNext
Next i
In order for me to get the email off the bottom of my continuous form, I used this much simpler code (as I avoided the RecordsetClone code)
Me.[email subform].Form.SelTop = Me.[email subform].Form.Count 'selects the last row
str = Me.[email subform].Form.Email 'capture the value of the last row
MsgBox str

Tagging Records in a Continuous Form

In a continuous subform, I display records based on a DISTINCT query. Because it's distinct, each row does not include a record ID.
Does anyone know of a way to add a checkbox (or similar), so that a user can select any of the records, which will then be used to create new records via code?
I prefer to use a subform to a list, as it features lots of column sorting and filtering functions.
MTIA
Depending on what you need to create the records, something like this sample may suit:
Function DisplaySelectedCompanyNames()
Dim i As Long
Dim F As Form
Dim RS As Recordset
'' Get the form and its recordset.
Set F = Forms![Customers1]
Set RS = F.RecordsetClone
'' Move to the first record in the recordset.
RS.MoveFirst
'' Move to the first selected record.
RS.Move F.SelTop - 1
'' Enumerate the list of selected records presenting
'' the CompanyName field in a message box.
For i = 1 To F.SelHeight
MsgBox RS![CompanyName]
RS.MoveNext
Next i
End Function
Further information: http://support.microsoft.com/kb/208502
FYI, I decided to use the Windows ListView OCX control, as it offers the ability to add a checkbox for each row.