Adding +1 in a auto increment value in SQL using vb - sql

I want to generate an id in my vb program it will get the latest auto incremented number and will add one but my code don't work am I missing some thing or am I doing it wrong? please help me! THANKS!
Here is the code:
OpenServer()
Dim num As Integer
Dim num1 = num + 1
Newdataset("SELECT MAX(IDnum) AS IDnum FROM addnewemployee WHERE IDnum = '" & num & "' ")
txtEmpNumber.Text = "" & num1 & "." & dtpdatehired.Value.ToString("yyyyMMdd") & ""

Your method has several flaws.
First, your SQL statement should be:
SELECT MAX(IDnum) AS IDnum FROM addnewemployee
This will get the highest IDnum from the addnewemployee table. The problem with this is that if a higher record has been created and deleted. Lets say that you get a return value of 55. It is possible a record with an id of 56 has been created and deleted.
The query you really want to use is
SHOW TABLE STATUS WHERE `Name` = 'addnewemployee'
Where will get a column named Auto_increment. Get that value from the dataset, then increment it.
But it is a bad idea to do this.
If you have multiple, dependant insert, you shouild either retrieve the id at the time of insert and store that in a variable. Or better still do everything in one statement or stored procedure.

Related

Find data location based on Primarykey ID

I am very new to access and vba so apologies in advance for glaring conceptual gaps.
Basically I have a button that, when clicked, prompts a user to enter an ID number. The ID entered will correspond to one of my primary keys in a specific table (I have some checks in place to make sure the entered ID is valid).
I need my code to identify the row number of the ID entered and be able to populate a specific column in that row. I know Access does not refer to data locations using rows/cols but that is the best way I thought to describe it.
I am using Index/Seek/NoMatch to make sure the entered ID number is valid and I have been trying to find a way to also use those functions to generate the data location but have not had any luck. Any help would be greatly appreciated.
I think DLookup() function will work for your case. Suppose you have following dataset in table tblEmpInfo where EmpID is primary key field.
If you want to return employee name by entering employee id in a inputbox then use DLookup() like below-
Private Sub cmdDataLookup_Click()
Dim strEmpName As String, InputID As String
InputID = InputBox("Enter employee ID:", "Input ID")
strEmpName = DLookup("EmpName", "tblEmpInfo", "EmpID= '" & InputID & "'")
MsgBox strEmpName
End Sub
If you want to update any name by entering EmpID then use UPDATE SQL statement. Try below.
Private Sub cmdUpdateInfo_Click()
Dim strSQL As String, InputID As String
InputID = InputBox("Enter employee ID:", "Input ID")
strSQL = "UPDATE tblEmpInfo Set EmpName= 'Updated Value' WHERE EmpID= '" & InputID & "'"
CurrentDb.Execute strSQL
End Sub
Note: There is no direct way to get row number and column number of a Field in access but you can apply some trick by VBA to get row and column number of a Field. I will suggest to ask a separate question to get that.

Automatically Increment Number by Group and Entry

I am currently trying to create a number that increases per entry and group in my table via a form.
The form is rather simple it utilizes a ComboBox to select the group from a different table. The generated number should start at 1 and increase for every new entry separately for each selected group.
Code:
My code attempts to create the number BeforeUpdate by searching for the DMax() of the variable for the group selected via ComboBox. Unfortunately, in this current state, the code does not increment the variable called Nummer but it does not throw an Error either.
Private Sub Nummer_BeforeUpdate(Cancel As Integer)
Nummer = Nz(DMax("[Nummer]", "Bau-Tagesbericht", "[Baustelle] = Kombinationsfeld354.Value")) + 1
End Sub
Variables:
Group: Baustelle
Variable that should be incremented: Nummer
Name of the Comobox: Kombinationsfeld354
I appreciate any kind of help, thank you!
You need to concatenate the variable - and set 0 (zero) for Null:
Nummer = Nz(DMax("[Nummer]", "Bau-Tagesbericht", "[Baustelle] = " & Kombinationsfeld354.Value & ""), 0) + 1
If text value, use single quotes:
Nummer = Nz(DMax("[Nummer]", "Bau-Tagesbericht", "[Baustelle] = '" & Kombinationsfeld354.Value & "'"), 0) + 1

Choosing specific dataview values from a SQL statement and assigning them a variable VB

Good morning! I am attempting to create a timelog for a current project, I need to somehow assign a value to the variable 'depart' from a dataview that I've pulled. I'm sorry if this is like another question but I couldn't seem to find something to help my answer. Please note: depart, firstDate, etc. are all declared already.
dataview = dba.Query("SELECT Time, Status FROM Timelog WHERE [Date] = '" & firstDate & "' AND USERNAME LIKE '" & AgentList.SelectedValue & "' ")
For Each rowView AS DataRowView in dataview
DIM row as DataRow = rowView.Row
If dataview.Find("Departed") Then
depart = dataview.Find("time"
End If
Next
I plan on using the DateDiff function to calculate the hours between a departure and return from lunch, and then lunch and arrival.
I have no idea what dba.Query() returns but I assume it is some type of collection, based on the fact you are iterating through it on the next line. Because of that, dataview.find() would NOT be returning a value from a row, but more like the index of the column that has that name.
What you need to do is get the value of the field for the current row of your iteration:
depart = rowView("Time")

SQL statement for combobox row source

I'm trying to define a SQL statement to use as the Row Source for a ComboBox on an MSAccess form. The SQL should select records from a table tblI where a particular table field matches a variant parameter varS set by the user; however, if varS is Null or not present in another table tblS, the SQl should select all records in tblI.
I can code the first parts of this (varS matches or is null):
SELECT tblI.ID, tblI.S FROM tblI WHERE ((tblI.S = varS) OR (varS Is Null)) ORDER BY tblI.ID;
Where I'm struggling is incorporating the final element (varS not present in tblS). I can code a test for the absence of varS in tblS:
Is Null(DLookup("[tbls.ID]","tblS","[tblS.ID]= " & varS))
but I can't work out how to incorporate this in the SQL statement. Should this work?
SELECT tblI.ID, tblI.S FROM tblI WHERE tblI.S = varS OR varS Is Null OR DLookup("[tbls.ID]","tblS","[tblS.ID]= " & varS) Is Null ORDER BY tblI.ID;
When run as a query it returns every record in tblS no matter the value of varS.
Table structure:
tblI contains 2 fields, Autonumber ID and Long S
tblS contains 1 field, Autonumber ID
My own approach to this problem would be something like this:
Private Sub SetComboSource(vID as Variant)
Dim sSQL as String
sSQL = "SELECT tblI.ID, tblI.S " & _
"FROM tblI "
If IsNull(vID) = False Then
If IsNumeric(vID) = True Then
If DCount("ID", "tblS", "ID = " Clng(vID)) > 0 Then
sSQL = sSQL & "WHERE tblI.S = " & CLng(vID)
End If
End If
End If
sSQL = sSQL & " ORDER BY tblI.ID"
Me.cboComboBox.RowSource = sSQL
End Sub
BTW, I recommend you give your tables and fields more descriptive names and then use aliasing in your SQL, especially for table names. I also think it's best to avoid using Variant variables. I usually use Longs for something like this and I take a value less than 1 to mean that the user didn't select anything, or selected ALL, or whatever meaning you want to derive from it. In other words, my ID's are always a number greater than zero and an ID of less than 1 in a variable means that the ID is empty. Which I use as a signal to create a new record, or to return all records, or whatever meaning you want to derive from it in the given context.
The following should work;
SELECT tblI.ID, tblI.S
FROM tblI
WHERE tbl.ID=varS
OR varS NOT IN(SELECT ID from tblS)

SQLDataAdapter filling datatable with primary key produces error and exits sub

Ok so this is going to take some explaining.
The process I am trying to do is grab data from a table function in SQL and then fill a dataset with the returned values.
I then have to run this query twice more to query an alternative number table. Then add to the same table as the previous queries.
This needs to be as fast as possible, so I am currently using an adapter.fill to populate the datasets and then a dataset.merge to put them all into one table.
The problem is the query can return duplicates which waste time and space, because of this I made column 3(part_ID) the primary key to stop duplicates.
When this is run with the .merge it quits at the first instance of a duplication and doesn't continue with the population.
The code below is what I used to fix this, I was just wondering if there is a better more elegant solution.
com = New SqlCommand(sqlPN, myConnect)
adapter.SelectCommand = com
adapter.Fill(temp, "Table(0)")
Dim data As New DataSet
data = temp
temp.Tables(0).Columns(3).Unique = True
firstSet = temp.Tables(0).Rows.Count
temp.AcceptChanges()
If temp.Tables(0).Rows.Count < maxRecords Then
Dim sqlAlt As String = "select Top " & (maxRecords + 10 - temp.Tables(0).Rows.Count) & " * from getAltEnquiry('" & tbSearchFor.Text & "') ORDER BY spn_partnumber"
adapter.SelectCommand.CommandText = sqlAlt
adapter.FillLoadOption = LoadOption.OverwriteChanges
adapter.Fill(temp, "Table(1)")
For i = 0 To temp.Tables(1).Rows.Count - 1
Try
temp.Tables(0).ImportRow(temp.Tables(1).Rows(i))
Catch e As Exception
End Try
Next
End If
If temp.Tables(0).Rows.Count < maxRecords Then
Dim sqlSuPN As String = "select Top " & (maxRecords + 5 - temp.Tables(0).Rows.Count) & " * from getSuPNEnquiry('" & tbSearchFor.Text & "') ORDER BY spn_partnumber"
adapter.SelectCommand.CommandText = sqlSuPN
adapter.Fill(temp, "Table(2)")
For i = 0 To temp.Tables(2).Rows.Count - 1
Try
temp.Tables(0).ImportRow(temp.Tables(2).Rows(i))
Catch e As Exception
End Try
Next
End If</code>
Thanks for any help or advice ^__^
Since you are looping through the records from the additional queries and using the ImportRow, your code will throw an exception if more than one record with the same value in the primary key field is attempted to be inserted. That is the purpose of a primary key when using in this way. If you want to ensure that your table only has unique records, you will need to ensure that the records are distinct before inserting them by checking the new row's part_id value against those already in the table. However, your design isn't necessarily the ideal approach.
Since you mentioned that this needs to be fast, it will probably be best if you could write a stored procedure to return just the rows you need from all tables and do the Fill into the table once.
If that's not possible, you can call adapter.Fill on the same DataTable for each of your data sources. Use the Fill overload that takes just the DataTable to fill and as per the docs, it will merge the data together if more than one record with the same primary key exists. The way you have the Fill method called, it is creating a new DataTable with the name you provide for each time you call Fill. Instead, you want to Fill just one DataTable.
"You can use the Fill method multiple times on the same DataTable. If a primary key exists, incoming rows are merged with matching rows that already exist. If no primary key exists, incoming rows are appended to the DataTable."