How to ignore the Null values in Insert query in access - sql

I have the Database table where the Table needs to be updated using a form.
However all the fields in the Form need not be mandatory to be filled.
I am Writing the Below VB code for inserting However I get an error stating that there is a syntax error in the statement.As i understand it is because of the Null Values in the Variable. I understand that I need to use DBNull.Value for all the null Values.
Here the Thing is there are too many fields to check if the value is null or not.
any body suggest if there is a way to do a mass check on the values entered to be null?
VBCode:
Dim StrSQL As String
Dim StrSQL1 As String
Dim tktID As Variant
Dim Assi As Variant
Dim reopened As Variant
Dim valid As Variant
Dim Reopenreason As Variant
Dim ReassignmentAG As Variant
Dim RBSCollab As Variant
Dim SMEconf As Variant
Dim Cloabag As Variant
Dim smeName As Variant
Dim Updat As Variant
Dim Closed As Variant
Dim iss As Variant
Dim ana As Variant
Dim res As Variant
Dim rVariant As Variant
' Assigining values
tktID = Ticket_number.Value
reopened = Ticket_Reopened.Value
valid = Valid_Reopen.Value
Assi = Assiginee.Value
Reopenreason = Reopen_reason.Value
ReassignmentAG = Reassignment_AG.Value
RBSCollab = RBS_Collab.Value
SMEconf = CkBxSMEConfirmation.Value
Cloabag = Collabarated_AG.Value
smeName = SME_Name.Value
Updat = Update.Value
Closed = Issue_Closed.Value
iss = Issue.Value
ana = Analysis.Value
res = Resolution.Value
rdate = Resolve_date.Value
'Insert values into the tables
StrSQL = "INSERT INTO Updates (TicketID,Assiginee,ReassignmentAG,RBSCollab,CollabAG,SMEconfirmation,SMEName,Update,IssueClosed,Issue,Analysis,Resolution,ResolveDate,TicketReopened,ValidReopen,ReopenReason) VALUES ('" & tktID & "','" & Assi & "','" & ReassignmentAG & "','" & RBSCollab & "','" & Cloabag & "','" & SMEconf & "','" & smeName & "','" & Updat & "','" & Closed & "','" & iss & "','" & ana & "','" & res & "','" & rdate & "','" & reopened & "','" & valid & "','" & Reopenreason & "' ) "
DoCmd.RunSQL StrSQL
thanks in advance for your help

I, too, setup my first Access database using lots of unbound controls and SQL statements for moving data around. But this is not the way to use Access. You should be using bound forms where the controls automatically know what the constraints are based on the table/columns they are bound to.
This means much less code for you to write (and maintain), future developers can look at your Access app and know what's going on because it will be done in the Access paradigm, and if you place as much logic into your tables/relationships as possible then if someone comes along and links to your ACCDB or opens the backend they could enter data without entering bad data.
So ultimately this is an XY problem. Get rid of all this code (especially DoCmd.RunSQL) and create a bound form. Put your validation logic in foreign keys, validation rules, and/or data macros in the table.

A simple solution to this problem could be just check for element's value before using in the inset query and if element's value is undefined than set with null.
Pass this value to database in the query.

Do this for each field:
tktID = IIF(ISNULL(Ticket_number.Value),"Null","'" & Ticket_number.Value & "'")
Then instead of this:
VALUES ('" & tktID & "',...
Do this
VALUES (" & tktID & ",...
Or if you don't mind replacing nulls with empty strings:
tktID = Nz(Ticket_number.Value)
will do it.
Of course you should at least make sure no single quotes are in the stings, so even better:
tktID = IIF(ISNULL(Ticket_number.Value),"Null","'" & Replace(Ticket_number.Value,"'","''") & "'")

After building the string for INSERT statment
strSql = "INSERT INTO tblmovimentiServizi ( msid, " _
& " msData, msIdDestinazione, msOraInizioServizio, msOraFineServizio, msAndataRitorno, " _
& " msOraVincoloEntrata, msOraVincoloUscita, msidAnagraficaAutomezzi, msServizioEseguito, msNoteCommenti) " _
& " VALUES ('" & rst!newid & "', #" & rst!msData + Me.g1 & "#, '" _
& rst!msIdDestinazione & "', #" _
& rst!msOraInizioServizio & "#, #" _
& rst!msOraFineServizio & "#, '" _
& rst!msAndataRitorno & "', #" _
& rst!msOraVincoloEntrata & "#, #" _
& rst!msOraVincoloUscita & "#, '" _
& rst!msidAnagraficaAutomezzi & "', " _
& eseguito & ", '" _
& rst!msNoteCommenti & "'" _
& ");"
I added
strSql = Replace(strSql, "''", "null")
strSql = Replace(strSql, "##", "null")
and it works.

Related

Comparing multiple combo box (text) values in an Access VBA form to prevent duplicate entries with OR condition

Putting together a query (with SQL statement) button that checks for duplicate combobox entries (within one submission) before they happen.
Trying to comprehend why this works:
ElseIf Me.pc_cbox1 = Me.pc_cbox2 Then
MsgBox "Duplicate Program Code Error"
But this does not:
ElseIf (Me.pc_cbox1 Or Me.pc_cbox2 Or Me.pc_cbox3 Or Me.pc_cbox4 Or Me.pc_cbox5 Or Me.pc_cbox6 Or Me.pc_cbox7 Or Me.pc_cbox8) =
(Me.pc_cbox1 Or Me.pc_cbox2 Or Me.pc_cbox3 Or Me.pc_cbox4 Or Me.pc_cbox5 Or Me.pc_cbox6 Or Me.pc_cbox7 Or Me.pc_cbox8) Then
MsgBox "Duplicate Program Code Error"
Edit #1: Thought I was onto something with this loop:( ...
For intComboBox = 1 To 8
If Controls("pc_cbox" & intComboBox).ListIndex <> intComboBox Then
If Controls("pc_cbox" & intComboBox).Value = Controls("pc_cbox" & intComboBox).Value Then
MsgBox "Duplicate Program Code Error"
End If
End If
Next intComboBox
Edit #2: #HansUp's suggestion works! I am going to dissect this loop for the next hour to better understand the dictionary concept. I am new to VBA (3rd week) and I know this code is mostly spaghetti at this point but I have been forced into learning as I go at work. Here is what I have put together as an add funding (percentages) per program without duplicates. 'Program Code' is part of the primary key for the SQL table and therefore will not accept duplicate entries. I wanted to prevent being able to submit duplicates on the form to nip this issue in the bud.
Private Sub fundAdd_Click()
Dim strSQL As String, queryName As String, qdf1 As QueryDef, dct As Object, i As Long, strValue As String
queryName = "temp6"
If QueryExists(queryName) Then
DoCmd.DeleteObject acQuery, "temp6"
End If
Set dct = CreateObject("Scripting.Dictionary")
For i = 1 To 8
strValue = Nz(Me.Controls("pc_cbox" & i).Value, "NULL")
If dct.Exists(strValue) Then
MsgBox "Duplicate Program Code Error"
Exit For
Else
dct.Add strValue, vbNullString
End If
Next
If Me.percentTotal <> 1 Then
MsgBox "Total not equal to 100%"
Else
strSQL = "INSERT INTO position_funding2(box_id, program_code, percent) VALUES ('" & fundboxid_cbox & "','" & pc_cbox1 & "','" & percent1 & "'), " & _
" ('" & fundboxid_cbox & "','" & pc_cbox2 & "','" & percent2 & "'), ('" & fundboxid_cbox & "','" & pc_cbox3 & "','" & percent3 & "'), " & _
" ('" & fundboxid_cbox & "','" & pc_cbox4 & "','" & percent4 & "'), ('" & fundboxid_cbox & "','" & pc_cbox5 & "','" & percent5 & "'), " & _
" ('" & fundboxid_cbox & "','" & pc_cbox6 & "','" & percent6 & "'), ('" & fundboxid_cbox & "','" & pc_cbox7 & "','" & percent7 & "'), " & _
" ('" & fundboxid_cbox & "','" & pc_cbox8 & "','" & percent8 & "');"
MsgBox (strSQL)
Set qdf1 = CurrentDb.CreateQueryDef("temp6")
qdf1.Connect = "ODBC;Driver=MySQL ODBC 8.0 Unicode Driver;SERVER=sv03rm;UID=*****;PWD=*****;DATABASE=pobe;PORT=3306;DFLT_BIGINT_BIND_STR=1"
qdf1.SQL = strSQL
qdf1.ReturnsRecords = False
DoCmd.OpenQuery "temp6"
Me.List271.Requery
End If
Defaults
End Sub
Use your combo box values as keys of a Dictionary. Before adding each of those combo values, use the Exists method to check whether that value was already stored in the Dictionary. If it does exist, the one you're about to add is a duplicate, so display your MsgBox notice.
You didn't provide any context about where and how you intend to do the comparison. So, for my version, I used a command button's click event.
Private Sub cmdCompare_Click()
Dim dct As Object
Dim i As Long
Dim strValue As String
Set dct = CreateObject("Scripting.Dictionary")
For i = 1 To 8
strValue = Nz(Me.Controls("pc_cbox" & i).Value, "NULL")
If dct.Exists(strValue) Then
MsgBox "Duplicate Program Code Error"
Exit For
Else
dct.Add strValue, vbNullString
End If
Next
End Sub

Access asking me to enter a parameter value

I'm running an SQL query through VB in Microsoft Access for form to add records to a table. However, it keeps asking me to insert parameter value, when they are already present in the form.
Private Sub AddPart_Click()
Dim strSQL As String
strSQL = "INSERT INTO Part VALUES (" & Me.IdPartPrimary.Value & ", " & Me.NamePartPrimary.Value & ", " & Me.BrandPartPrimary.Value & ", " & Me.ModelPartPrimary.Value & ", " & Me.FunctionPartPrimary.Value & ", -1, " & Me.FatherPartPrimary.Value & ", " & Me.ProviderPartPrimary.Value & ", " & Me.AmountPartPrimary.Value & ");"
DoCmd.RunSQL strSQL
End Sub
I already checked for spelling mistakes and there were none. Also, this happens with every field. If I don't insert a parameter value and cancel instead, the record still gets added, only after I close and reopen the table lots of times.
If fields are text type, need text delimiters - apostrophe will serve. I assume comboboxes have a number value from a hidden foreign key column. Value property does not need to be specified as it is the default.
With Me
strSQL = "INSERT INTO Part " & _
" VALUES (" & .IdPartPrimary & ", '" & _
.NamePartPrimary & "', '" & .BrandPartPrimary & "', '" & _
.ModelPartPrimary & "', '" & .FunctionPartPrimary & "', -1, " & _
.FatherPartPrimary & ", " & .ProviderPartPrimary & ", " & .AmountPartPrimary & ")"
End With
AFAIK, Access cannot execute multi-action SQL statements but SQL injection is still possible. If you want to explore use of Parameters in VBA, review How do I use parameters in VBA in the different contexts in Microsoft Access?
Another alternative to avoid SQL injection is to open a recordset, use its AddNew method to create a new record, and set value of each field. DAO.Recordset AddNew

Syntax error when copying data from Excel userform to Access table

When trying to copy data from an Excel userform in to an Access table via SQL I am encountering an error on a field that is a Yes/No type in the database. How can I format the info correctly so that it updates the database?
I have looked at some other examples of copying data into the Yes/No fields in Access, as well as trying my code in a number of different formats, with double quotations, single quotations & as it appears below
Dim oConn As ADODB.Connection
Dim oCm As ADODB.Command
Dim iRecAffected As Integer
If Me.TBField.Visible = False Then
'Update office users
Init1 = Left(Me.TxtName1, 1) & Mid$(Me.TxtName1, InStr(Me.TxtName1, " ") + 1, 1)
Select Case Me.LblFraOffice.Caption
Case Is = "Add User"
Set oConn = New ADODB.Connection
oConn.Open sConn
Set oCm = New ADODB.Command
oCm.ActiveConnection = oConn
If RbUser.Value = True Then
oCm.CommandText = "INSERT Into Users (Name, Username, Initials, Process, FLM, FLM_ID, User, JobRole) " & _
"VALUES ('" & TxtName1.Value & "','" & TxtUname1.Value & "','" & Init1 & "','" & TxtProcess1.Value & "','" & TxtFLM.Value & "','" & TxtFLMID.Value & "', True ,'" & TxtPosition1.Value & "')"
ElseIf RbAdmin.Value = True Then
oCm.CommandText = "INSERT Into Users (Name, Username, Initials, Process, FLM, FLM_ID, JobRole, User) " & _
"VALUES ('" & TxtName1.Value & "','" & TxtUname1.Value & "','" & Init1 & "','" & TxtProcess1.Value & "','" & TxtFLM.Value & "','" & TxtFLMID.Value & "', True ,'" & TxtPosition1.Value & "')"
ElseIf RbManager.Value = True Then
oCm.CommandText = "INSERT Into Users (Name, Username, Initials, Process, FLM, FLM_ID, JobRole, User) " & _
"VALUES ('" & TxtName1.Value & "','" & TxtUname1.Value & "','" & Init1 & "','" & TxtProcess1.Value & "','" & TxtFLM.Value & "','" & TxtFLMID.Value & "', True ,'" & TxtPosition1.Value & "')"
End If
'MsgBox oCm.CommandText
oCm.Execute iRecAffected
oConn.Close
When pressing submit on the userform this should add a newly created user into the database table. If I remove the User field (and the associated true/false) it works. But my users can be users, admins or managers
At present I receive an error message
Run-time error '-2147217900 (80040e14)': Syntax error in INSERT INTO statement
Column name User is the reserved keyword. Can you add square brackets around the keyword to fix the issue:
INSERT Into Users (Name, Username, Initials, Process, FLM, FLM_ID, [User], JobRole)
or you can rename the column name to a non-reserved keyword to sovle this error.

SQL syntax error on vba

I made a SQL statement in the add/update button in the query wizard I changed it back to SQL view to see how the program made me the code and when I copy and paste the same error on the If statement of the btnAdd it throws me a syntax error, but how?
here is the entire code:
Private Sub cmdAdd_Click()
'In the button add we have two options
'1. Insert
'2. Update
If Me.txtID.Tag & "" = "" Then
CurrentDb.Execute "INSERT INTO tblClients ( ClientID, ClientName, Gender, " & _
"City, [Address (Fisical)], [Cellphone/Telephone] ) " & _
"SELECT " & Me.txtID & ",'" & Me.txtName & "','" & Me.cboGender & "', '" & Me.cboCity & "','" & Me.txtAddress & "','" & Me.txtCellphone & "'"
Else
'Otherwise the data will be updated
CurrentDb.Execute "UPDATE tblClients SET tblClients.ClientName = [me]. [txtName], tblClients.Gender = [me].[cboGender], tblClients.City = [me].[cboCity], tblClients.[Address (Fisical)] = [me].[txtAddress], tblClients.[Cellphone/Telephone] = [me].[txtCellphone] "
WHERE (([ClientID]=[Me].[txtID].[Tag]));
End If
cmdClear_Click
tblClients_subform.Form.Requery
End Sub
it highlights me this row in red:
WHERE (([ClientID]=[Me].[txtID].[Tag]));
It appears that the following code is not on the same line
CurrentDb.Execute "UPDATE tblClients SET tblClients.ClientName = [me]. [txtName], tblClients.Gender = [me].[cboGender], tblClients.City = [me].[cboCity], tblClients.[Address (Fisical)] = [me].[txtAddress], tblClients.[Cellphone/Telephone] = [me].[txtCellphone] "
WHERE (([ClientID]=[Me].[txtID].[Tag]))
So you may want to change it to
CurrentDb.Execute "UPDATE tblClients SET tblClients.ClientName = [me]. [txtName], tblClients.Gender = [me].[cboGender], tblClients.City = [me].[cboCity], tblClients.[Address (Fisical)] = [me].[txtAddress], tblClients.[Cellphone/Telephone] = [me].[txtCellphone] " & _
"WHERE (([ClientID]=[Me].[txtID].[Tag]))"
In addition to Cableload's correct answer where the WHERE statement that was on a new code line was not connected to the previous line by the use of an underscore at the end of the first one, there is still a referncing issue.
You are referencing values in a UserForm like that were columns in a table so it is not finding the value you are looking for. To get the value into the SQL statement you need to come out of the literal string, reference the value, and then continue writing the string (not forgetting to enclose the value with '): -
CurrentDb.Execute "UPDATE tblClients SET " & _
"[ClientName] = '" & Me.txtName & "', " & _
"[Gender] = '" & Me.cboGender & "', " & _
"[City] = '" & Me.cboCity & "', " & _
"[Address (Fisical)] = '" & Me.txtAddress & "', " & _
"[Cellphone/Telephone] = '" & Me.txtCellphone & "' " & _
"WHERE [ClientID]=" & Me.txtID.Tag
I have spread it across multiple lines for ease of reading but obviously you can adjust your actual code however needed.
I would also question [ClientID]=" & Me.txtID.Tag, is the ClientID in the in the txtID.value or the txtID.Tag, they are different places. The value property is the value in the text box, the Tag property is more like a area for metadata that you can populate if needed but is not automatically populated by default.
Finally I'd like to refer you back to an answer to a previous question you had, at the bottom of the answer there was a tip about placing the resultant query into a Access Query in SQL view to get better information on the error, that would have helped you here too. To give further assistance on the 'resultant query'.
In debug mode before the while the CurrentDb.Execute is highlighted but before it is run (using F8 to step through each line until you get there, or placing a breakpoint on that line
Open the the Immediate Window if it is not already open (either Ctrl+G to from the menu bar 'View' > 'Immediate Window')
Copy all related code from the line after the CurrentDb.Execute statement, in this case it would be UPDATE ... .Tag
In the immediate window type a question mark and then paste in the rleated code and press enter
The immediate window will return the resultant string for you to try in a Query in SQL view.
Change the SELECT keyword to VALUES in your INSERT statement.
CurrentDb.Execute "INSERT INTO tblClients ( ClientID, ClientName, Gender, " & _
"City, [Address (Fisical)], [Cellphone/Telephone] ) " & _
"VALUES (" & Me.txtID & ",'" & Me.txtName & "','" & Me.cboGender & "', '" & Me.cboCity & "','" & Me.txtAddress & "','" & Me.txtCellphone & "')"
And the UPDATE should be this. The issue here was that you were trying to use Form controls in the SQL, but you needed to evaluate the controls first then concatenate their values to your literal string.
I'm wondering if you really need Me.txtID instead of Me.txtID.Tag
So sway that out if it doesn't work.
CurrentDb.Execute "UPDATE tblClients SET tblClients.ClientName = '" & me.txtName & "', tblClients.Gender = '" & me.cboGender & "', tblClients.City = '" & me.cboCity & "', tblClients.[Address (Fisical)] = '" & me.txtAddress & "', tblClients.[Cellphone/Telephone] = '" & me.txtCellphone & "' WHERE (([ClientID]=" & Me.txtID.Tag & "));"

MS Access runtime error 3464

I am working on a database for my work and i'm trying to insert and update values from tables with sql inside the vb editor
This is my code:
Option Compare Database
Private Sub Übernehmen_Click()
Dim strSQL1 As String
Dim strSQL2 As String
Dim strSQL3 As String
Dim ArtikelNr As Integer
Dim Stück As Integer
Dim Lieferant As String
Dim Bestellnr As Integer
Dim EkPreis As String
Dim Mwst As String
Dim Einkaufsort As String
Dim GhIndex As String
Dim Datum As String
Dim Uhrzeit As String
Dim Lager As String
Dim Beschreibung As String
ArtikelNr = [Forms]![Einkauf]![ArtikelNr].Value
Stück = [Forms]![Einkauf]![Stück].Value
Lieferant = [Forms]![Einkauf]![Lieferant].Value
Bestellnr = [Forms]![Einkauf]![Bestellnr].Value
EkPreis = [Forms]![Einkauf]![EK-Preis].Value
Mwst = [Forms]![Einkauf]![Mwst-Satz].Value
Einkaufsort = [Forms]![Einkauf]![Einkaufsort].Value
GhIndex = [Forms]![Einkauf]![GH-Index].Value
Datum = [Forms]![Einkauf]![Datum].Value
Uhrzeit = [Forms]![Einkauf]![Uhrzeit].Value
Lager = [Forms]![Einkauf]![Lager].Value
strSQL1 = "INSERT INTO Einkäufe (ArtikelNr, Stück, Lieferant, Bestellnr, EKPreis, MwstSatz, Einkaufsort, GHIndex) VALUES (" & ArtikelNr & "," & Stück & ",'" & Lieferant & "','" & Bestellnr & "','" & EkPreis & "','" & Mwst & "','" & Einkaufsort & "','" & GhIndex & "');"
Beschreibung = DLast("EinkaufID", "Einkäufe")
strSQL2 = "INSERT INTO Transaktionen VALUES ('" & ArtikelNr & "','" & Datum & "','" & Lager & "','" & Stück & "','EinkaufID ' + '" & Beschreibung & "' ,'Einkauf',NULL,NULL,'" & Uhrzeit & "');"
strSQL3 = "UPDATE Lagerbestand SET Stück = Stück+" & Stück & " WHERE ArtikelNr = '" & ArtikelNr & "' AND Lager = '" & Lager & "';"
DoCmd.RunSQL strSQL1
DoCmd.RunSQL strSQL2
DoCmd.RunSQL strSQL3
End Sub
After trying to press the button it first adds the two entries and stops at the third one just to throw an error saying "Runtime Error: 3464".
After I press debug it marks the line DoCmd.RunSQL strSQL3.
I would appreciate any answer I get.
Many thanks in advance.
A quick google of "Runtime Error 3464" suggests this is a data type mismatch. You'll typically see this when you try to save a date value in a string field or something like that.
Double check the types passed to your SQL statements match the columns they should be saved to - and apply any necessary conversions if you spot differences.
Also one final heads up...by building your SQL string dynamically you are leaving yourself vulnerable to SQL Injection attacks - you should consider using ADOCommands with parameters.
My error was trying to compare an integer with a string. Even though sql does cast it from an integer to a string if you make a new entry, it does not cast it if you want to compare in a where.