Access - Duplicate Record button creates a blank record - ms-access

I've got a fairly simple database, 5000 records about 60-70 fields, and I created a button to copy the current record and blank out some of the fields (which we called EXPAND).
I recently received a requests to do the same thing without blanking out any fields but it doesn't work. I used the Command Button wizard on my form and chose the Duplicate option, but the new record is completely blank. Additionally, I get an error message when I close the record that talks about "A large amount of data copied to the clipboard". I tried the original button I had made (EXPAND) and it resulted in the same issue. Searching back through old records, I see that it was working as recently as 6/10/2016 (10 days ago).
Has something changed which would prevent this code from executing properly? Is there a new setting/option I need to enable to get it working again? Or is there some alternative method I can use to accomplish the same result?
Here is the (very simple) code the system created to duplicate the record (which doesn't work):
Private Sub cmdDuplicate_Click()
On Error GoTo Err_cmdDuplicate_Click
DoCmd.RunCommand acCmdSelectRecord
DoCmd.RunCommand acCmdCopy
DoCmd.RunCommand acCmdRecordsGoToNew
DoCmd.RunCommand acCmdSelectRecord
DoCmd.RunCommand acCmdPaste
Exit_cmdDuplicate_Click:
Exit Sub
Err_cmdDuplicate_Click:
MsgBox Err.Description
Resume Exit_cmdDuplicate_Click
End Sub

The fastest and simplest way is to use DAO and the RecordsetClone of the form:
Private Sub cmdDuplicate_Click()
Dim rstSource As DAO.Recordset
Dim rstInsert As DAO.Recordset
Dim fld As DAO.Field
If Me.NewRecord = True Then Exit Sub
Set rstInsert = Me.RecordsetClone
Set rstSource = rstInsert.Clone
With rstSource
If .RecordCount > 0 Then
' Go to the current record.
.Bookmark = Me.Bookmark
With rstInsert
.AddNew
For Each fld In rstSource.Fields
With fld
If .Attributes And dbAutoIncrField Then
' Skip Autonumber or GUID field.
ElseIf .Name = "SomeFieldToPreset"
rstInsert.Fields(.Name).Value = SomeValue
ElseIf .Name = "SomeFieldToExclude
' Leave blank
Else
' All other fields.
' Copy field content.
rstInsert.Fields(.Name).Value = .Value
End If
End With
Next
.Update
' Go to the new record and sync form.
.MoveLast
Me.Bookmark = .Bookmark
.Close
End With
End If
.Close
End With
Set rstInsert = Nothing
Set rstSource = Nothing
End Sub

I think the easiest way may to create an append query. Set the criteria field as the ID of the current record. This can be done pretty easily in the query design window.

No error message?
Do you have a Primary Key ID field on the form that doesn't allow you to copy duplicate ID?

Related

MS Access Recordset Moving on Search even if no match found?

This is driving me nuts. I have an access VBA form where I want to allow users to type a document number into a box in order to jump directly to that record.
The underlying table as a field "DocNum", and the number is always sequential. I want the searchbox to display the current Doc Number the user is on, if they type in a different number and hit enter, it should either jump to that record if it exists, or if it doesn't exist, stay on the current record.
I'm trying to accomplish thisby having a hidden textbox bound to "DocNum", and an unbound visible box on top of it. On Form_Current() the unbound box is made to match the underlying field. After, update I run the following code to perform the search.
Private Sub txt_DocNumSearch_AfterUpdate()
Dim rs As Object
Set rs = Me.RecordsetClone
With rs
rs.FindFirst "[DocNum] = " & Str(Me![txt_DocNumSearch])
If rs.NoMatch Then
MsgBox "Record not found."
GoTo Cleanup
Else
Me.Bookmark = rs.Bookmark
Exit Sub
End If
End With
Cleanup:
rs.Close
Set rs = Nothing
Set dbs = Nothing
End Sub
What's driving me insane is that even when it doesn't find a match.... it skips to the next record anyway. No matter what I do... move last, trying to bookmark before I even search, etc... I can't get it to not jump forward. What am I missing?
Try simplifying it:
Private Sub txt_DocNumSearch_AfterUpdate()
Dim rs As DAO.Recordset
Set rs = Me.RecordsetClone
With rs
.FindFirst "[DocNum] = " & Str(Me![txt_DocNumSearch])
If .NoMatch Then
MsgBox "Record not found."
Else
Me.Bookmark = .Bookmark
End If
.Close
End With
End Sub

Duplicate records in Subform to New record

I have a table for my assemblies in a manufacturing process [Shedmodels]. The components are listed in a separate table [ShedModelsComponents]. The primary key in [ShedModels] is [ModelNumber]. There is a field in [ShedModelsComponents] also called [ModelNumber]. Each component is thus assigned to a certain Assembly in table [ShedModels]. Next I have created a form for [ShedModels] with a subform for [ShedModelsComponents] embedded. All the components for the assembly appear like I want. So far, so good. Now many of my assemblies use almost the same components, so I would like to copy or perhaps append all the components from one assembly to a new record in [Shed Models]. I have found this code on MS website.
Private Sub btnDuplicate_Click()
Dim dbs As DAO.Database, Rst As DAO.Recordset
Dim F As Form
' Return Database variable pointing to current database.
Set dbs = CurrentDb
Set Rst = Me.RecordsetClone
On Error GoTo Err_btnDuplicate_Click
' Tag property to be used later by the append query.
Me.Tag = Me![ModelNumber]
' Add new record to end of Recordset object.
With Rst
.AddNew
!ModelNumber = Me!ModelNumber
!ModelDesc = Me!ModelDesc
!ModelSalePrice = Me!ModelSalePrice
.Update ' Save changes.
.Move 0, .LastModified
End With
Me.Bookmark = Rst.Bookmark
' Run the Duplicate Order Details append query which selects all
' detail records that have the OrderID stored in the form's
' Tag property and appends them back to the detail table with
' the OrderID of the duplicated main form record.
DoCmd.SetWarnings False
DoCmd.OpenQuery "Duplicate Shed Models Components"
DoCmd.SetWarnings True
'Requery the subform to display the newly appended records.
Me![Shed_Models_Query].Requery
Exit_btnduplicate_Click:
Exit Sub
Err_btnDuplicate_Click:
MsgBox Error$
Resume Exit_btnduplicate_Click:
End Sub
but it returns the error that this would create duplicate Model numbers, which I don't doubt. How can I copy my assembly with all the components to a new record, but change the Model Number (which would be user entered)?
First, copy the parent record (like you do). But don't let the form move to the new record.
Next, obtain the new PK.
Then, copy the child records using the new PK. This is a skeleton - you would use the RecordsetClone of the subform. See below.
Finally, move the parent form to the new record. The subform will automatically update.
Public Sub CopyRecords()
Dim rstSource As DAO.Recordset
Dim rstInsert As DAO.Recordset
Dim fld As DAO.Field
Dim strSQL As String
Dim lngLoop As Long
Dim lngCount As Long
strSQL = "SELECT * FROM tblStatus WHERE Location = '" & _
"DEFx" & "' Order by Total"
' Change this to the RecordsetClone of the subform.
Set rstInsert = CurrentDb.OpenRecordset(strSQL)
Set rstSource = rstInsert.Clone
With rstSource
lngCount = .RecordCount
For lngLoop = 1 To lngCount
With rstInsert
.AddNew
For Each fld In rstSource.Fields
With fld
If .Attributes And dbAutoIncrField Then
' Skip Autonumber or GUID field.
ElseIf .Name = "ParentID" ' Name of FK.
rstInsert.Fields(.Name).Value = NewID ' The new ID of the parent.
ElseIf .Name = "Total" Then
' Insert some default value.
rstInsert.Fields(.Name).Value = 0
ElseIf .Name = "PROCESSED_IND" Then
' Empty a field.
rstInsert.Fields(.Name).Value = Null
Else
' Copy field content.
rstInsert.Fields(.Name).Value = .Value
End If
End With
Next
.Update
End With
.MoveNext
Next
rstInsert.Close
.Close
End With
Set rstInsert = Nothing
Set rstSource = Nothing
End Sub

Access only filtered values in a MS Access table

Is it possible to get the values from rows in an Access table that are showing after the filter is applied?
Example as requested:
I have a table in which employees fill in project tasks, hours on the project etc.
It is made as a table on a form. The columns has limited choices in Initials, Project number, etc. People like to sort the table by the built in filter function in access tables and queries. I filtered so only the project LT1075 is shown in the example.
How can i get those 4 rows as a recordset or something similar? I need to get the values in all hour fields. I need also to copy only those 4 lines in VBA and do stuff to it (Functions wanted by people). But when i use the DAO, i get all rows in the "Unfiltered" table.
How do i get only the rows visible?
In excel, there is a simple function, something with cells_visible but i cant find a pardon to Access.
Best Regards, Emil.
Edit, tryouts:
Public Sub Test1_Click()
Dim rs As DAO.Recordset
Set rs = Me.RecordsetClone
While Not rs.EOF
' Do calculation stuff on record.
rs.MoveNext
Wend
End Sub
It is put on the "Test 1" button in the figure above.
I get the error: "Runtime error 7951 - You entered an expression that has an invalid reference to the RecordsetClone property"
I have a clue that it does not work because of the Me.* function? Since the table is in some sort of subform. But i see only one form in the Navigation panel. (Hidden are also showed).
You can use the RecordsetClone of the form:
Dim rs As DAO.Recordset
Set rs = Me.RecordsetClone
While Not rs.EOF
' Do calculation stuff on record.
rs.MoveNext
Wend
And you can add records to a recordset:
Public Sub CopyRecords()
Dim rstSource As DAO.Recordset
Dim rstInsert As DAO.Recordset
Dim fld As DAO.Field
Dim strSQL As String
Dim lngLoop As Long
Dim lngCount As Long
strSQL = "SELECT TOP 1 * FROM tblStatus"
Set rstInsert = CurrentDb.OpenRecordset(strSQL)
' rstSource can be any recordset, here the RecordsetClone of the form.
Set rstSource = Me.RecordsetClone
With rstSource
While Not .EOF
With rstInsert
.AddNew
For Each fld In rstSource.Fields
With fld
If .Attributes And dbAutoIncrField Then
' Skip Autonumber or GUID field.
ElseIf .Name = "Total" Then
' Special cases.
' Insert default job code.
rstInsert.Fields(.Name).Value = 0
ElseIf .Name = "PROCESSED_IND" Then
rstInsert.Fields(.Name).Value = vbNullString
Else
' Copy field content.
rstInsert.Fields(.Name).Value = .Value
End If
End With
Next
.Update
End With
.MoveNext
Next
rstInsert.Close
.Close
End With
Set rstInsert = Nothing
Set rstSource = Nothing
End Sub

Microsoft Access Sub Form Write Conflict Troubles

I have a form which contains a subform which displays editable fields linked to one my tables. For a project I'm currently working on, one of the requirements is that I have to track when the last change was made to a record and who did so.
So what I've done is for each editable textbox or combobox within the form and subform I've made it so they have events on their BeforeUpdate and AfterUpdate events.
For example my BeforeUpdate for a textbox:
Private Sub textbox_BeforeUpdate(Cancel As Integer)
If Not isValidUser Then
Cancel = True
Me.textbox.Undo
End If
End Sub
and my AfterUpdate is:
Private Sub textbox_AfterUpdate()
updateRecord Me.textbox.Value, UserNameWindows
End Sub
and updateRecord is:
Public Sub updateRecord(bucNumber As String, updater As String)
Dim Dbs As Object
Dim rst As Object
Dim fldEnumerator As Object
Dim fldColumns As Object
sqlStatement = "SELECT fName " & _
"FROM t_Staff " & _
"WHERE uName='" & updater & "';"
'Getting fullname of user via username
Set rst = CurrentDb.OpenRecordset(sqlStatement)
'Setting fullname to updater variable
updater = rst(0)
'Clean Up
Set rst = Nothing
'Opening Bucket Contents
Set Dbs = CurrentDb
Set rst = Dbs.OpenRecordset("Bucket Contents")
Set fldColumns = rst.Fields
'Scan the records from beginning to each
While Not rst.EOF
'Check the current column
For Each fldEnumerator In rst.Fields
'If the column is named Bucket No
If fldEnumerator.Name = "Bucket No" Then
'If the Bucket No of the current record is the same as bucketNumber
If fldEnumerator.Value = bucNumber Then
'Then change the updated fields by updater and todays date
rst.Edit
rst("Last Updated By").Value = updater
rst("Last Updated On").Value = Date
rst.Update
End If
End If
Next
'Move to the next record and continue the same approach
rst.MoveNext
Wend
'Clean Up
Set rst = Nothing
Set Dbs = Nothing
End Sub
Okay now is the weird thing, this works totally fine when I make a modification to a control within the Main form, however as soon as a try to alter something in the subform it throws up a write conflict.
If I opt to save record it ignores my code for updating who last modified it and when and if I opt to discard the change it runs my code and updates it that it has been changed!
Anyone know what is wrong or of a better way to do this?

Access: Move to next record until EOF

I need to loop through a form by moving to the next record in the recordset.
I am using the Form_Current event to loop thru.
I have used a couple of statements and have different outcomes.
This one sometimes crashes and gives the error message: "You can't go to the specified record."
DoCmd.GoToRecord , , acNext
This one only goes upto 72 records and stops.
DoCmd.RunCommand acCmdRecordsGoToNext
This one only goes upto 129 records and stops.
Me.Recordset.MoveNext
Trying to find an instruction that will go to the next record untill it reaches the End of File.
I am using Access 2010 (Access 2002 -2003 file format mdb) as the front end. The recordsource is a SQL Server 2008 linked View.
To loop from current record to the end:
While Me.CurrentRecord < Me.Recordset.RecordCount
' ... do something to current record
' ...
DoCmd.GoToRecord Record:=acNext
Wend
To check if it is possible to go to next record:
If Me.CurrentRecord < Me.Recordset.RecordCount Then
' ...
End If
If (Not IsNull(Me.id.Value)) Then
DoCmd.GoToRecord , , acNext
End If
Hi,
you need to put this in form activate, and have an id field named id...
this way it passes until it reaches the one without id (AKA new one)...
I have done this in the past, and have always used this:
With Me.RecordsetClone
.MoveFirst
Do Until .EOF
If Me.Dirty Then
Me.Dirty = False
End If
.MoveNext
Me.Bookmark = .Bookmark
Loop
End With
Some people would use the form's Recordset, which doesn't require setting the bookmark (i.e., navigating the form's Recordset navigates the form's edit buffer automatically, so the user sees the move immediately), but I prefer the indirection of the RecordsetClone.
Set rs = me.RecordsetClone
rs.Bookmark = me.Bookmark
Do
rs.movenext
Loop until rs.eof
If you want cmd buttons that loop through the form's records, try adding this code to your cmdNext_Click and cmdPrevious_Click VBA.
I have found it works well and copes with BOF / EOF issues:
On Error Resume Next
DoCmd.GoToRecord , , acNext
On Error Goto 0
On Error Resume Next
DoCmd.GoToRecord , , acPrevious
On Error Goto 0
Good luck! PT
Keeping the code simple is always my advice:
If IsNull(Me.Id) = True Then
DoCmd.GoToRecord , , acNext
Else
DoCmd.GoToRecord , , acLast
End If
Add This Code on Form Close Event whether you add new record or delete, it will recreate the Primary Keys from 1 to Last record.This code will not disturb other columns of table.
Sub updatePrimaryKeysOnFormClose()
Dim i, rcount As Integer
'Declare some object variables
Dim dbLib As Database
Dim rsTable1 As Recordset
'Set dbLib to the current database (i.e. LIBRARY)
Set dbLib = CurrentDb
'Open a recordset object for the Table1 table
Set rsTable1 = dbLib.OpenRecordset("Table1")
rcount = rsTable1.RecordCount
'== Add New Record ============================
For i = 1 To rcount
With rsTable1
rsTable1.Edit
rsTable1.Fields(0) = i
rsTable1.Update
'-- Go to Next Record ---
rsTable1.MoveNext
End With
Next
Set rsTable1 = rsTable1
End Sub