ACCESS 365 and INSERT INTO not inserting data from FORM - sql

I am updating a small medical database. So far all new products have been added manually / directly to a Products- table. I am creating a form to do that.
Even it is in a way very simple to do, I am facing up a problem that data is inserted correctly only if all fields have something typed in form, if any of the input boxes are left empty no new records are made.
Additionally a simple check for minimum fields is not working. It will step thru all controls correctly but does not stop even a field is left empty and its Tag has *-sign in it.
Insert into includes all fields which a defined in that table there is not any extra field in table except first field is autonumbered ID field. No need to type something in every field each time.
Pr
Private Function CheckAllFields() As Boolean
Dim Ctrl As Control
CheckAllFields = False
'Go through the controls in Form
'If control has tag (*) and it null (no value) then show alert
For Each Ctrl In Me.Controls
MsgBox Ctrl.Name
If Ctrl.Tag = "*" And IsNull(Ctrl) Then
Dim FieldName As String
FieldName = Ctrl.Name
'Show notification if field was not filled and move focus to that field
MsgBox "A required Field has not been filled."
Ctrl.SetFocus
CheckAllFields = True
Exit For
End If
Next Ctrl
MsgBox "Check fileds done"
End Function
Private Sub AddProduct_Click()
Dim strSQL As String
'SQL to insert Product
strSQL = "INSERT INTO Products([Product name],[Product description],[Finnish name],[Finnish description],[Matrix2012], " & _
"[Additional Info], [Unit], [Licence],[Remarks],Narcotic,[Asset], " & _
"[ATC], [Cathegory], [EIC code], [EIC name])" & _
" VALUES ('" & Me.txtProductName & "','" & Me.txtProductDesc & "','" & Me.txtFinnishName & "','" & Me.txtFinnishDesc & "','" & Me.ComboMatrix & "'," & _
"'" & Me.txtAdditionalInfo & "','" & Me.ComboUnit & "','" & Me.CheckLicense & "'," & _
"'" & Me.txtRemarks & "','" & Me.CheckNarcotic & "','" & Me.CheckAsset & "'," & _
"'" & Me.txtATC & "','" & Me.txtCathegory & "','" & Me.txtEICcode & "','" & Me.txtEICName & "')"
'' MsgBox strSQL
'Check the all fields have valid format
If CheckAllFields = False Then
'Execute SQL in database - insert new batch
' MsgBox "Step into Check all fields"
CurrentDb.Execute strSQL
MsgBox "A new product inserted !"
End If
Here is a debug output of my insert into command:
Debug output
Here is another output debug, now the new product is inserted correctly.
Correctly working version

Problem solved. As Craig pointed this way of incuding parameters is prone to fail.
Here is good way to solve this. Did not believe it but after I tried it worked ultimate.
MS access running SQL doesn't insert data, no error
strSQL = "INSERT INTO Products([Product name],[Product description],[Finnish name],[Finnish description],[Matrix2012], " & _
"[Additional Info], [Unit], [Licence],[Remarks],Narcotic,[Asset], " & _
"[ATC], [Cathegory], [EIC code], [EIC name])" & _
" VALUES (ptxtProductName, ptxtProductDesc,ptxtFinnishName,ptxtFinnishDesc,pComboMatrix, ptxtAdditionalInfo,pComboUnit, pCheckLicense, ptxtRemarks, pCheckNarcotic, pCheckAsset, ptxtATC, ptxtCathegory, ptxtEICCode, ptxtEICName);"
Set db = CurrentDb
Set qdf = db.CreateQueryDef(vbNullString, strSQL)
With qdf
.Parameters("ptxtProductName").Value = Me.txtProductName.Value
.Parameters("ptxtProductDesc").Value = Me.txtProductDesc.Value
.Parameters("ptxtFinnishName").Value = Me.txtFinnishName.Value
.Parameters("ptxtFinnishDesc").Value = Me.txtFinnishDesc.Value
.Parameters("pComboMatrix").Value = Me.ComboMatrix.Value
.Parameters("ptxtAdditionalInfo").Value = Me.txtAdditionalInfo.Value
.Parameters("pComboUnit").Value = Me.ComboUnit.Value
.Parameters("pCheckLicense").Value = Me.CheckLicense.Value
.Parameters("ptxtRemarks").Value = Me.txtRemarks.Value
.Parameters("pCheckNarcotic").Value = Me.CheckNarcotic.Value
.Parameters("pCheckAsset").Value = Me.CheckAsset.Value
.Parameters("ptxtATC").Value = Me.txtATC.Value
.Parameters("ptxtCathegory").Value = Me.txtCathegory.Value
.Parameters("ptxtEICCode").Value = Me.txtEICcode.Value
.Parameters("ptxtEICName").Value = Me.txtEICName.Value
.Execute dbFailOnError
End With
Debug.Print db.RecordsAffected
That check for empty fields is mystery, it works in another form so it has to be some sort of reference problem. Anyway to keep things simple this works perfectly:
If txtProductName.Value = "" Or ComboMatrix.Value = "" Or ComboUnit.Value = "" Then
'Show notification if field was not filled and move focus to that field
MsgBox "A required Field has not been filled."

Related

How to handle 0 lines found after a DoCmd.RunSQL(INSERT INTO...)

For starters, I only started yesterday with the attempts of introducing SQL into my VBA code.
I'm trying to use VBA/SQL to Insert Data into a local table, made from a combination of a Database table and form input. I want to know how to trigger a "0 Lines retrieved".
I've already tried looking on several pages on how to handle "0 lines to Insert" when running a DoCmd.RunSQL("INSERT INTO ... SELECT ... FROM ... WHERE ...).
The code itself works when there is data present, so that's not the problem.
The problem itself is when I don't find data, I want to trigger a messagebox that gives instructions on how to handle the current situation.
Sadly, I have not found on how I can trigger this.
sqlTempInsert = "INSERT INTO tblScanInput (Support, EAN, Counted, Product, Description, Launched, Collected) " & _
"SELECT " & lblSupportData.Caption & ", " & txtEANInput.Value & ", "
If txtAmountInput.Visible = True Then
sqlTempInsert = sqlTempInsert & txtAmountInput.Value & ", "
ElseIf txtAmountInput.Visible = False Then
sqlTempInsert = sqlTempInsert & "1, "
End If
sqlTempInsert = sqlTempInsert & "GEPRO.CODPRO, GEPRO.DS1PRO, GESUPDC.UVCSRV, GESUPDC.UVCLIV " & _
"FROM [Database_Table] GESUPDC LEFT OUTER JOIN [Database_Table] GEPRO ON GESUPDC.CODPRO = GEPRO.CODPRO " & _
"WHERE GESUPDC.NUMSUP = " & lblSupportData.Caption & " AND GESUPDC.EDIPRO = '" & txtEANInput.Value & "';"
DoCmd.RunSQL(sqlTempInsert)
Use .Execute and .RecordsAffected.
Dim db As DAO.Database
Dim x As Long
Set db = CurrentDb
db.Execute sqlTempInsert, dbFailOnError
x = db.RecordsAffected
If x = 0 Then
' nothing was inserted
End If
Note: pay attention to Delete 5 Records but RecordsAffected Property is 0

Query to check for duplicates

The following was written to inform a user if they are entering duplicate information.
It never detects the duplicate, but all else around it works.
The values from debug (for formats etc.) are
me.lisAppID = 1
me.dtReviewDate = 10/09/2015
me.txtReviewerName = colin
This is the query
Dim tmpRS As DAO.Recordset
Set tmpRS = CurrentDb.OpenRecordset("SELECT TblReview.ReviewID FROM TblReview Where (TblReview.AppID = " & Me.lisAppID & ") And (TblReview.RevDateTime)= #" & Me.dtReviewDate _
& "# And (TblReview.RevUserID)= '" & Me.txtReviewerName & "'")
If tmpRS.RecordCount > 0 Then
MsgBox "Record is a duplicate, it will not be saved", vbOKOnly
Cancel = 1
Exit Sub
End If
Set tmpRS = Nothing
Here are some things to try.
Explicitly format your date variable when building the sql string:
Set tmpRS = CurrentDb.OpenRecordset("SELECT TblReview.ReviewID FROM TblReview Where (TblReview.AppID = " & Me.lisAppID _
& ") And (TblReview.RevDateTime)= #" & Format(Me.dtReviewDate,"mm/dd/yyyy") _
& "# And (TblReview.RevUserID)= '" & Me.txtReviewerName & "'")
Consider using the optional parameters in the OpenRecordset method. Some types of connection do not actually return a value for the Recordset.RecordCount property. From MSDN:
The RecordCount property doesn't indicate how many records are contained in a dynaset–, snapshot–, or forward–only–type Recordset object until all records have been accessed.

RecordSource in Access SQL

I have a form which allows the user to view all records with the LinkRef field equal to a specified value and also either the Clearance Applying For or Clearance Level a certain value.
LinkRef is a user ID which is pulled in using OpenArgs from the previous form. The code for the form_load I have presently is:
Private Sub Form_Load()
'MsgBox Me.OpenArgs
Me.C_LinKRef = Me.OpenArgs
Me.chbToggleEdit.Value = False
'MsgBox Me.C_LinKRef
Dim mySQL As String
mySQL = _
"Select * " & _
"From TabClearDetail " & _
"Where (C_LinKRef = " & Me.C_LinKRef & ") " & _
"And ([Clearance Applying For] = 'BPSS' " & _
"Or [Clearance Applying For] = 'BPSS (EDF)' " & _
"Or [Clearance Applying For] = 'BPSS (Magn)' " & _
"Or [Clearance Applying For] = 'BPSS (Sella)' " & _
"Or [Clearance Applying For] = 'BPSS Equiv' " & _
"Or C_ClearanceLevel = 'BPSS' " & _
"Or C_ClearanceLevel = 'BPSS (EDF)' " & _
"Or C_ClearanceLevel = 'BPSS (Magn)' " & _
"Or C_ClearanceLevel = 'BPSS (Sella)' " & _
"Or C_ClearanceLevel = 'BPSS Equiv' " & _
"Or C_ClearanceLevel = 'DESTROYED' " & _
"Or C_ClearanceLevel = 'Lapsed' " & _
"Or C_ClearanceLevel = 'NOT_FLWDUP' " & _
"Or C_ClearanceLevel = 'NOT_SPECIFIED' " & _
"Or C_ClearanceLevel = 'Refused' " & _
"Or C_ClearanceLevel = 'Withdrawn');"
Me.RecordSource = mySQL
'MsgBox Me.RecordsetClone.RecordCount
End Sub
mySQL seems to behave as it should when there are matching records. But sometimes there won't be any records because the specified person doesn't have any of these clearance levels and hasn't applied for them, then I would like the form to come up blank or a message to appear saying that there is no matching records.
Presently though if there is no matching records the form will pull in the LinkRef but fill all the other text boxes with values from a completely different record (it seems to be the last record I viewed). Not to sure how to remedy this, I tried to use the RecordsetClone.RecordCount to say if it is equal to 0 then msgbox, but it seems to late to do that as it always seems to find at least 1 entry, as even if there should be 0 it has already populated the textboxes with data from another field so 1 is found.
The LinkRef textbox is populated from OpenArgs. All other textboxes are populated using a query which looks in the TabClearDetail table and pulls the values in. I'm starting to think I'd be better either just using Queries or just using Code, but I wasn't sure how to use OpenArgs in a query and for some things it's so much quicker to make a query than code.
Here is the code for my save dialog I refer to in reply to #Roland post. This code is called in the Form_Close() sub.
Private Sub SaveDialog()
Dim Msg, Style, Title As String
Dim Response As Integer
Msg = "Would you like to save your changes?"
Style = vbYesNoCancel
Title = "Save Changes"
On Error GoTo Err_BackFromAddBPSSButton_Click
Response = MsgBox(Msg, Style, Title)
If Response = vbYes Then
'DoCmd.Close
DoCmd.OpenForm ("Basic Personal Information")
Else
If Response = vbNo Then
Me.Undo
'DoCmd.Close
DoCmd.OpenForm ("Basic Personal Information")
End If
End If
Exit_BackFromAddBPSSButton_Click:
Exit Sub
Err_BackFromAddBPSSButton_Click:
MsgBox Err.Description
Resume Exit_BackFromAddBPSSButton_Click
End Sub
Apologies for the very wordy question, hopefully all the detail is necessary and it makes sense, any suggestions HUGELY appreciated!
Try changing the order of events:
Don't set the TextBox value first. Pass the OpenArgs to the mySql string. With mySql open a recordset in VBA (OpenRecordset) and do a RecordCount. If it is zero then set the Recordsource to SELECT * FROM TabClearDetail WHERE 1=2 . Else set mySQl as the Recordsource (or pass the Recordset). Only then set the TextBox and CheckBox.
Private Sub Form_Load()
Dim i as Integer
i = Me.OpenArgs
Dim mySQL As String
mySQL = _
"Select * " & _
"From TabClearDetail " & _
"Where (C_LinKRef = " & Me.C_LinKRef & ") " & _
"And ([Clearance Applying For] IN ('BPSS','BPSS (EDF)','BPSS (Magn)','BPSS Sella)','BPSS Equiv') " & _
"Or C_ClearanceLevel IN ('BPSS','BPSS (EDF)','BPSS (Magn)','BPSS (Sella)','BPSS Equiv','DESTROYED','Lapsed','NOT_FLWDUP','NOT_SPECIFIED','Refused','Withdrawn'));"
Dim rst as Recordset
Set rst = CurrentDB.OpenRecordset(mySQL)
rst.MoveLast
rst.MoveFirst
If rst.RecordCount = 0 then
Me.RecordSource = "SELECT * FROM TabClearDetail WHERE 1=2"
Me.C_LinKRef = ""
Me.chbToggleEdit.Value = False
Else
Me.RecordSource = mySQL
Me.C_LinKRef = i
Me.chbToggleEdit.Value = False
End If
rst.Close
Set rst = Nothing
End Sub
Sorry, cannot test it here so may be a little buggy. If any problems I will check tomorrow
Using a query and passing [Forms]![BPSS Clearance].[OpenArgs] into that as well as the conditions on C_ClearanceLevel and Clearance Applying For has worked for me. No idea why the code didn't work because in theory it's doing the same thing, but I've got a solution so I'm happy. Thanks for all the suggestions

Update Button not updating

I have been hammering out the issues of this form for about a week now and have almost come to a solution, but I have hit a brick wall. I have a large form with multiple functions, one of the functions is to edit a subform that houses a list of codes and other various pieces of data. When I click the edit button it auto fills the boxes with the selected data. The function works when I click the update button but when I click the save button it does not actually save the data. The code is:
Private Sub cmdEdit_Click()
'check whether there exists data in list
If Not (Me.TableSub.Form.Recordset.EOF And Me.TableSub.Form.Recordset.BOF) Then
'Get data to text box control
With Me.TableSub.Form.Recordset
Me.text_key = .Fields("KW")
Me.txt_code = .Fields("Code")
Me.combo_source = .Fields("Source")
'Store id of student in tag of text id in case id is modified
Me.txt_code.Tag = .Fields("Code")
'Change caption of button add to Update
Me.cmdAdd.Caption = "Update"
'disable button edit
Me.cmdEdit.Enabled = False
End With
End If
End Sub
This is the code for the save or Add button.
Private Sub cmdAdd_Click()
'when we click on button Add there are two options
'1. For insert
'2. For Update
If Me.txt_code.Tag & "" = "" Then
'this is for insert new
'add data to table
CurrentDb.Execute "INSERT INTO KWTable(KW, Source, Code) " & _
" VALUES('" & Me.text_key & "','" & Me.combo_source & "','" & _
Me.txt_code & "')"
Else
'otherwise (Tag of txtID store the id of student to be modified)
CurrentDb.Execute "UPDATE KWTable " & _
" SET KW='" & Me.text_key & "'" & _
", Code='" & Me.txt_code & "'" & _
", Source='" & Me.combo_source & "'" & _
" WHERE KW='" & Me.text_key & "'"
End If
'clear form
cmdClear_Click
'refresh data in list on form
TableSub.Form.Requery
End Sub
You're only copying values to the fields. They're not bound to the subform's recordset in any way. So, to save them, just reverse the process:
With Me.TableSub.Form.Recordset
.Edit
.Fields("KW") = Me.text_key
.Fields("Code") = Me.txt_code
.Fields("Source") = Me.combo_source
.Fields("Code") = Me.txt_code.Tag
.Update
End With
It sounds to me like you are looking at forcing the current bound form's data to save.
If Me.Dirty Then Me.Dirty = False
This statement essentially says "If there is unsaved data on this form/report - save it"
You can also reference your subform
If subform.Form.Dirty Then subform.Form.Dirty = False
It will do the same thing as Fabio's suggestion but I find it a bit more reliable with bound forms than the recordset approach.

Getting Textboxes to Clear after use

I have an access form where I input data into them to be inserted into a table for storage, the code I use is
Private Sub cmd_go_Click()
Dim insertstring As String
insertstring = "INSERT INTO KWTable (KW, Source, Code) VALUES('" & text_key.Value & "','" & combo_source.Value & "','" & txt_code.Value & "');"
DoCmd.RunSQL insertstring
End Sub
And I was wondering if there was a code I could add to this so that once the data has been inserted the text box and the combo box would automatically clear?
Use the properties of the controls. Specifically, try setting the .Text or .Value properties to "":
txtTextBox.Text = ""
Or:
txtTextBox.Value = ""