Autonumber value of last inserted row - MS Access / VBA (Value=0) [duplicate] - ms-access

This question already has answers here:
Autonumber value of last inserted row - MS Access / VBA
(5 answers)
Closed 3 years ago.
I need to get the Autonumbered ID of the last record inserted into a table (through INSERT INTO command)
I have seen some methods in the forum that looks to work for most of the community but not in my case:
Autonumber value of last inserted row - MS Access / VBA
Dim miDDBB As DAO.Database
.....
StrSQL = " INSERT INTO DG_tb_Main " ......
Set miDDBB = CurrentDb
miDDBB.Execute (StrSQL)
newRow = miDDBB.OpenRecordset("SELECT ##IDENTITY")(0)
Set db = Nothing
When using this code I always get the 'newRow' value as '0'.
I have checked the SQL expresion and works fine, insterting the new record into the table.
¿What am I doing wrong?
Regards

Study your own reference again.
You have DAO, but use the method for ADO.

Related

Access 2002 VBA: Creating an incremented Item Code

Ok, here's the deal. I have a previously existing SQL Server 2008 database linked to an Access 2002 database via linked tables/views. Up until now, the item code has been a nvarchar type.
I have a SQL query which casts the item codes as Int and an Access 2002 linked query that uses the MAX() function to give me the highest value. It is from this highest value I wish to start incrementing the item codes by 1 every time the "New" record button is selected.
Right now, when "New" is selected, the form is blank, waiting for input. What I want to do is, when "New" is selected, to have the value of the MAX() function query passed to a variable, have 1 added to it, and the resulting value placed in the "Item Code" text box.
It sounds easy enough, but for some reason I can't seem to get it to work. I know Access fairly well, but my VBA is fairly weak.
Sound like it could be done with a custom function.
Dim rs as dao.recordset
Dim db as dao.database
Dim NextInt as string
set db = currentDb
set rs = db.openrecordset(YourMaxQuery,dbOpenSnapshot,dbSeeChanges)
if rs.recordCount >0 THEN
NextInt = Cstr(rs!MaxValue + 1)
END
set rs = nothing
set db = nothing
return NextInt
Call the function in the update statement of your query and it should give you the value you're looking for.
Sorry I took so long to get back to this thread.
Ok, I ended up going with a GlobalSequence in MS SQL Server 2008. Basically just created a table with the max id value as a seed, and matched it with a column that has a bit value to prevent rollbacks and duplicate item codes should a record get deleted. After that, it was pretty easy. :)

Set up Access table to perform multiple records at time

I performed some research how do I need to set up my DB but I need your advice how to.
I have few tables in my db ( db is for incoming material ) in this db are below tables:
Material table
incoming delivery
measurements
supplier
time measurement
Let me explain logic of this db.
When delivery come user will input some data in form (creation of incoming list) where he will basically enter all data necessary to start process of receiving. So once he hit button save record he will create record in tables incoming delivery and time measure.
Until this point everything works perfectly. When next user received this incoming list he got some data where was one hyperlink to file where they put it measurements.
And here come my problem.
I want data to be input in Access rather than to excel (form input looks much more better [yes this is most important reason :) ] ).
So for that I created table called measurements, where I plan input [incoming delivery ID], [material id], [primal key] , and that 41 another columns for measurement(this columns need to be separated cause we have many parts and each got different No. of measurement and user will get information via user form ( opening different form based on material id [this works]).
So after describing its logic I am requesting you people how do i create with 1 record to measurement table each time different numbers of measurements in measurements table for it.
put it even more simple just for case. When user hit button to save the record which creates record in delivery list will also create for example additional 5 records (this number will be based on cell value) in measurement table linked with incoming delivery. (relation is of course set up to one-many)
so in the end when i will create somehow continuous table for data input. User will see form where he got incoming delivery No. some information from other tables and as mentioned 41 items to measure 5 times ( 41 columns and 5 rows )
Hope that my explanation is clear and rly need your help i am screwed :D
Hints:
Use VBA to automate the creation of records. Look for information about DAO and/or ADO and how to use them to insert records (I personally use DAO when I work with Access, it works but it's old).
Do your homework. Before asking a question, it is important that you do your research and that you try to solve the problems by yourself. Try to help yourself before asking others. Please read this article.
Maybe this snippet of code can help you. You'll need to call this method from an event (button_clic or something in your form):
public sub addRecords(id as integer)
dim db as dao.database, rsIn as dao.recordset, rsOut as dao.recordset
dim strSQL as String
dim someValue as integer, i as integer ' Test values
' "Connect" to your current database
set db = currentdb
' Create a recordset with the input data you need (read only)
strSQL = "select * from tbl_inputTable where id=" & id
set rsIn = db.openrecordset(strSQL, dbOpenDynaset, dbReadOnly)
' Create a recordset to your output table
set rsOut = db.openRecorset("tbl_outputTable", dbOpenDynaset, dbAppendOnly)
' Read the data from the input table
with rsIn
.moveFirst
someValue = rsIn![aField]
end with
' Write some test data to your output table
with rsOut
for i = 1 to someValue
.addNew
rsOut![fk_id] = id
rsOut![theValue] = i
.update
next i
end with
' Close every recordset and databases (this does not close your application)
rsIn.close
rsOut.close
db.close
end sub
In your input form, write this in the "On Click" event:
sub button1_click()
call addRecords(txtId.value) ' I am assuming that there's a text box called "txtId"
end sub
This is just a sample of what you can do with DAO. I won't (and maybe nobody else would) write the full code for you: You'll need to fit this to your particular problem.

Object variable error

I've got a subform (RegistrationFsub) based on table Registration. It's purpose is to create a one-to-many relationship between a person and the year(s) they have enrolled in the group.
When a mom enrolls in a new year, I have a command button that is supposed to add a new line to the table Registration with MomID (from the parent form: MomsFsub) and the start date of the current enrollment year (YearStart, from table Year). Since the current enrollment period is represented by the latest date, I want to use the Max() command to retrieve it from YearT. I tried the following code:
Dim db As DAO.Database
Dim sqlSTR As String
Dim IDvar As String
'new code added since question posted
Set db = CurrentDb
Call MsgBox (Max(YearT!YearStart), vbOKonly)
'MsgBox checks value returned for Max(YearStart)
'end new code
IDvar = CStr(MomID)
sqlSTR = "INSERT INTO Registration(YearStart, MomID) SELECT Max(YearStart), "_
& IDvar & " AS expr1 FROM YearT;"
'new: debug statement
Debug.Print sqlSTR
db.Execute sqlSTR
And I got an "Object variable or With block variable not set" error. What am I doing wrong?
Edit: Setting the db to Currentdb fixes the Object variable error, but now returns a "Too few parameters" error. The original table name "Year" has been changed to "YearT," since I only reference it in this one bit of code anyway.
Update
Now that I've fixed RegistrationFsub, it seems that the button also inserts data currently displayed in other controls on the form. So if the 2012 entry has RID = 1 and Leader = True, the above code creates an entry in Registration that also has RID = 1 and Leader = True. How can I keep those other fields blank?
The object variable error is because you didn't Set db to anything before you attempted db.Execute. Do this first ...
Set db = CurrentDb
If you later get an error with Execute, it may be because Year is a reserved word. Enclose that table name in square brackets to avoid confusing the db engine.
sqlSTR = "INSERT INTO Registration(YearStart, MomID) SELECT Max(YearStart), "_
& IDvar & " AS expr1 FROM [Year];"
If you are adding a new record based on the Mom's current new entry, you need to take the current time: Now() and parse the year off of it..
Year(Now())
Looking for Max(YearStart) could be looking for a record that happened 5 years ago..
sqlSTR = "INSERT INTO Registration(YearStart, MomID) SELECT Max(YearStart), "_
& IDvar & " AS expr1 FROM Year;"
I think you need to update the code to two different operations:
sqlSTR = "INSERT INTO Registration(Year(Now()), MomID)"
run your code..
Then do a..
sqlSTR= "SELECT Year(Now()), " & IDvar & " AS expr1 FROM [Year];"
The most relevant answer was deleted before it could be selected, so I shall paste the content here:
The object variable error is because you didn't Set db to anything before you attempted db.Execute. Do this first ...
Set db = CurrentDb
If you later get an error with Execute, it may be because Year is a reserved word. Enclose that table name in square brackets to avoid confusing the db engine.
sqlSTR = "INSERT INTO Registration(YearStart, MomID) SELECT Max(YearStart), "_
& IDvar & " AS expr1 FROM [Year];"
For "too few parameters", add Debug.Print sqlSTR after the sqlSTR = ... line.
But before the Execute command
Run the code and go to the Immediate window (Ctrl+g). Copy the SQL text, create a new query in the query designer, switch to SQL View, and paste in the SQL text. When you run that query, Access will pop up an input box asking you to supply a value for the parameter. That box also include the name of whatever Access thinks is the parameter.
The trouble here is that YearStart had a different field name in table Year.
Many thanks for the clear and helpful answer.

Creating a recordset in Access with VBA

From the title, i know it seems like this has been answered too many times over, but I have a series of incomprehensible problems with it. This is also my first time asking for help through posts, so I might forget to mention some stuff.
Function update_location_id()
Dim rs As DAO.Recordset
Dim db As Database
Dim strSQL As String
Set db = CurrentDb
strSQL = "select id from location"
Set rs = db.OpenRecordset(strSQL)
MsgBox (rs.RecordCount)
End Function
I removed almost all the code from this function just to try to figure out why i couldn't get a record. this code generates a "too few parameters. expected one on the 'set rs = ...' line.
However if i change the select query's id to *, it works fine. However it returns 1. This is somewhat confusing seeing as there are a total of 3 records in the locations table right now.
Just incase its needed the location table looks like
id description
1 "Location 1"
2 "Location 2"
3 "Location 3"
This is causing me to pull my hairs out and i can't really move on with my project if i can't do such a basic database action as...getting information from it.
References: Visual Basic for Applications, Microsoft Access 14.0 Object Library, OLE Automation, Microsoft Office 14.0 Access database engine object, Microsoft Internet Controls.
Typically, the error "too few parameters" comes up when you use a column name that does not exist in the table, so it is interpreted as a parameter.
So, despite your given table data, I'd really check again the table name (location) and the column name (id).
As for the "1", yes, you have to insert
rs.MoveLast
rs.MoveFirst
after opening the recordset to get the correct RecordCount. Before moving to the last one, the recordset does not know how many records it yields (there are some more details to this problem, which I don't remember exactly right now, concerning recordset-type or so).

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.