Solved

Get record written data

Posted on 2016-07-18
7
55 Views
Last Modified: 2016-07-19
I currently use the following VBA code to get the MAX record just after commit:
<BEGIN VBA>    Dim strSQLLot As String
    Dim strSQLFailure As String
    Dim intFailed As Integer
    Dim intCounter As Integer
    Dim dbConn As ADODB.Connection
    Dim recSet As ADODB.Recordset
    Dim intNextFailureId As Integer
    Dim intArray() As Integer
    Dim dbs As DAO.Database
    Dim rsSQL As DAO.Recordset
    Dim intMaxLotId As Integer
    Dim intNewLotID As Integer
'Open the database
        Set dbConn = CurrentProject.Connection
       
        'Write the form's data to the SQL table tblInitialData
        DoCmd.RunCommand acCmdSaveRecord
                               
        'determine MAX Lot ID number
        DoCmd.RunMacro "mcrRunqryMaketblMaxLotID"
        intMaxLotId = DLookup("MaxOfTestLotID", "tblMaxLotID")
       
        'Prompt user with MAX Lot ID Number.
        MsgBox "Lot number " & intMaxLotId & " has been created.", , "ATE DATABASE"
                       
        DoCmd.Close
                       
        'open switchboard and close initial form
        DoCmd.OpenForm "Switchboard"
<END VBA>

I previously tried to get a SELECT statement to run but had no luck.  I would like to use either SCOPE_IDENTITY() or @@IDENTITY but cannot determine the correct VBA to make that run.  Indeed, will it even run in scope based on using the DoCmd.RunCommand acCmdSaveRecord statement instead of an INSERT INTO statement?  I have tried DoCmd.OpenQuery, CurrentDb.Execute, and others that apparently do not allow SELECT statements.

TIA,
Tim
0
Comment
Question by:gibneyt
7 Comments
 
LVL 70

Expert Comment

by:Éric Moreau
ID: 41717734
check "Retrieving Microsoft Access Autonumber Values" from https://msdn.microsoft.com/en-us/library/ks9f57t0.aspx?f=255&MSPPError=-2147217396
0
 
LVL 26

Expert Comment

by:Nick67
ID: 41717792
What you are attempting is a little trickier than you might think.
Dlookup() is a performance pig.
None of the domain lookup functions should EVER be used.
This will find the 'largest' value depending on datatype and sort order
Dim rs As dao.Recordset
Set rs = db.OpenRecordset("SELECT TOP 1 TheFieldOfInterest FROM TheTableOfInterest  ORDER BY  TheFieldOfInterest DESC;", dbOpenDynaset, dbSeeChanges)

TheMaxValue = rs!TheFieldOfInterest

No matter how you do it though, you have to be aware you are in a multi-user setup.
No matter how fast you think you may be, what gets retrieved may be the value from the record just committed -- or from someone else's new addition.

@@IDENTITY is at the SQL Server end of things.
You can get that back to Access -- but not if you are letting the users create the record via a bound form as you appear to be doing (DoCmd.RunCommand acCmdSaveRecord)

If you create the record with DAO, pulling back the identity is fairly simple.

   With rs
        .AddNew
        !MyField = MyValue
        .Update
        .Bookmark = .LastModified
        lngJobID = ![JobID]
    End With

Where my identity field is JobID and a Long (SQL Server bit) value.

But note that this value has NO guarantee of actually being the last record in play.
If you use the value to build a value that's unique (like work order or invoice numbers)  you need to build a check in to ensure that an attempted value is ACTUALLY valid when you go to use it.
0
 
LVL 9

Expert Comment

by:Valliappan AN
ID: 41719130
I would suggest that use MS Access only for single user run and SQL Server for multiple user run, and then using MAX(JobID) as already discuss here, would work in Access, and in SQL Server, you can use SCOPE_IDENTITY() to retrieve the last value.

Hope that helps.
0
NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

 
LVL 35

Accepted Solution

by:
PatHartman earned 500 total points
ID: 41719461
Since you are running the code in a bound form, you don't need to use either the DLooku() or @@Identity query.  Simply reference the identity column in the form's RecordSource.

intMaxLotId = Me.LotID

If you run an append query, then you can't access the identity column and that is when you would need to use the @@Identity query to retrieve it.  So after running the append query or using DAO or ADO to inset a record use:
            Set rsScope = db.OpenRecordset("SELECT @@IDENTITY as NewID")
                       NewProvProcID = rsScope!NewID

Open in new window


As long as you don't have any triggers that will cause inserts into other tables, this will give you the last identity column inserted in this thread.

@Valliappan AN - Access (more specifically Jet and ACE) is not a single user application.  It is multi-user out of the box.

@Nick - when the tables are bound to SQL server, you cannot reference the Identity column this way.  It works with Jet/ACE due to the close connection Access has with them but Access' connection with SQL Server et al is asynchronous and so the insert has to be sent to the server (ie saved) before you can retrieve the new identity value.
0
 
LVL 26

Expert Comment

by:Nick67
ID: 41719653
@PatHartman
I am confused
"you cannot reference the Identity column this way"
Perhaps I did not phrase things as clearly as I would have liked.
Dim rs As dao.Recordset
 Set rs = db.OpenRecordset("SELECT TOP 1 TheFieldOfInterest FROM TheTableOfInterest  ORDER BY  TheFieldOfInterest DESC;", dbOpenDynaset, dbSeeChanges)
 TheMaxValue = rs!TheFieldOfInterest

Open in new window


This will get the largest committed value of [TheTableOfInterest].[TheFieldOfInterest]
When you have an Access backend, Access will put a hold on an autonumber the minute you begin to make a new record dirty, and you can retrieve that.  SQL Server does not behave that way.  The identity value isn't set until the record is committed.
This code creates a new record, commits it and retrieves the identity value of that.
    With rs
         .AddNew
         !MyField = MyValue
         .Update
         .Bookmark = .LastModified
         lngJobID = ![JobID]
     End With

Open in new window


and works swimmingly with a SQL Server backend.
But absolutely, if a SQL Server backend is in play, you cannot retrieve the identity value of a 'dirty and new' record of a form -- which is something that is possible with an Access backend.  Only committing to save the record causes that identity value to be set in a SQL Server backend.

Is that what you meant?
0
 
LVL 35

Expert Comment

by:PatHartman
ID: 41719657
Sorry, I read the code wrong.  It looked like the reference was inside the .addnew rather than outside it.
0
 

Author Closing Comment

by:gibneyt
ID: 41719769
@PatHartman,

Nice!  Accessing the form's RecordSource in this instance does appear to be the shortest and sweetest means to an end.

Many thanks.
0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

It’s been over a month into 2017, and there is already a sophisticated Gmail phishing email making it rounds. New techniques and tactics, have given hackers a way to authentically impersonate your contacts.How it Works The attack works by targeti…
Preparing an email is something we should all take special care with – especially when the email is for somebody you may not know very well. The pressures of everyday working life stacked with a hectic office environment can make this a real challen…
Viewers will learn how the fundamental information of how to create a table.
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question