Trying to use VBA to write query in Access - vba

I am getting a type mismatch with the following syntax in my Access VBA. I am trying to update my table named "Billing" by seeing if any records have a date that looks at a string value in my "Certs" table like "2012-07-01" corresponding to my form's billYear textbox e.g. 2012 and my billMonth textbox e.g. 07. Is there a better way to write the VBA or see an error - many thanks:
Dim sRecert As String
Dim byear As Integer
Dim bmonth As Integer
byear = Me.billYear
bmonth = Me.billMonth
sRecert = "Update Billing set recertifying = -1 where (select certificationExpireDate from certs where Left((certificationExpireDate),4) = " & byear
& " and Mid((certificationExpireDate),6,2) = " & bmonth & ")"
DoCmd.RunSQL sRecert
I may not have explained it well. I created a real Query called from my form:
DoCmd.OpenQuery "updateRecert"
I set up my SQL below as a test on a real date I’m working with. It is in SQL Server (ODBC linked)
My dbo_certs table and my dbo_billing table share only one joinable field peopleID:
UPDATE dbo_Billing AS a INNER JOIN dbo_certs AS b ON a.peopleid = b.peopleid
SET a.recertifying = -1
WHERE b.certificationExpireDate = '2015-08-31 00:00:00.000';
The above gave a data mismatch error.
My bottom line is I have two text boxes on my form to pass in data preferably into my VBA code:
billMonth which in this case is 8 because it is an integer so that is
a problem
billYear is 2015
so I need to update my dbo_billing table’s ‘recertifying’ field with -1 if the dbo_cert’s field ‘certificationExpireDate’ is '2015-08-31 00:00:00.000' but only if that can be gotten from the form.

Is there a better way to write the VBA or see an Error?
Yes. You need Error Handling
I don't think the issue is in the code, I think it's in the SQL.
To troubleshoot your code, wrap it in an good error handler.
Public Sub MyRoutine()
On Error GoTo EH
'put your code here
GoTo FINISH
EH:
With Err
MsgBox "Error" & vbTab & .Number & vbCrLf _
& "Source" & vbTab & .Source & vbCrLf & vbCrLf _
& .Description
End With
'for use during debugging
Debug.Assert 0
GoTo FINISH
Resume
FINISH:
'any cleanup code here
End Sub
When the msgbox shows the error, make note of the Source. This should help you determine where the error comes from.
The lines following 'for use during debugging are helpful. Here's how to use them:
execution will stop on the Debug.Assert 0 line
drag the yellow arrow (which determines which line to run next) to the Resume line
hit {F8} on the keyboard (or use the menu Debug > Step Into)
This will go to the line where the error occurred. In your case, it will probably be the last line of your code.

Error in SQL... but!! Are you sure that certificationExpireDate is string and all the time equal to yyyy-mm-dd pattern?? It's dangerouse to have relation with "not certain" key like you have. I think this is not a good db design.
But, after all, for your case:
VBA:
sRecert = "UPDATE Billing a inner join certs b " & _
"on format(a.imaginary_date_field, """yyyy-mm-dd""") = b.certificationExpireDate " & _
"set a.recertifying = -1 " & _
"where CInt(Left((b.certificationExpireDate),4)) = " & byear & " and CInt(Mid((b.certificationExpireDate),6,2)) = " & bmonth
QueryDef:
PARAMETERS Forms!your_form!byear Short, Forms!your_form!bmonth Short;
UPDATE Billing a inner join certs b
on format(a.imaginary_date_field, "yyyy-mm-dd") = b.certificationExpireDate
set a.recertifying = -1
where CInt(Left((b.certificationExpireDate),4)) = Forms!your_form!byear and CInt(Mid((b.certificationExpireDate),6,2)) = Forms!your_form!bmonth
UPDATED
mismatch error
You get error probable because you have date/time field, not a string. Date in MS Access queries write with # symbol. WHERE b.certificationExpireDate = #2015-08-31 00:00:00.000#;
In your case:
PARAMETERS Forms!your_form!byear Short, Forms!your_form!bmonth Short;
UPDATE dbo_Billing AS a INNER JOIN dbo_certs AS b ON a.peopleid = b.peopleid
SET a.recertifying = -1
WHERE year(b.certificationExpireDate) = Forms!your_form!byear and Month(b.certificationExpireDate) = Forms!your_form!bmonth;
For more info follow this link

Related

VBA DAO.OpenRecordSet Inconsistent Errors

Running Access 2016
I am attempting to import data from an MS Access .mdb table from Excel. (The proprietary software my client uses only recognizes *.mdb files.) When I run this code when the table is closed, I get the error:
Run-Time Error 3061
Too few parameters - Expected 2
If I run the code when the table is open in Access, HALF the time, I get that error and half the time I get:
Run-Time error '3008'
The table 'Daily_Logs_of_Flows' is already opened exclusively by
another user, or it is already open through the user interface
and cannot be manipulated programmatically.
That seems to indicate that VBA gets past the first error sometimes.
I have checked variable names and have used both single quotations in and number signs (#) before and after monthToImport because of this post on StackOverflow. The error went from
Expected 3
to
Expected 2
Here is the code
Sub importPLCDataFromAccess(monthToImport As Date)
Dim myDbLocation As String
myDbLocation = "K:\Users\WWTP Computer\Documents\POV_Projects\PLC Interface\PLC_Data.mdb"
DIM mySQLCall as String
Set myWorkbook = ActiveWorkbook
Set myDataSheet = myWorkbook.Worksheets("Page 1")
Set myEngine = New DAO.DBEngine
'Set myWorkspace = myEngine.Workspaces(0)
Set myDB = myEngine.OpenDatabase(myDbLocation)
' I deleted the workspace
' Set myDB = myWorkspace.OpenDatabase(myDbLocation)
mySQLCall = "SELECT Time_Stamp, GolfVolume, CreekVolume, InfluentVolume FROM Daily_Logs_of_Flows "
' Limit records to month requested...
mySQLCall = mySQLCall & "WHERE (DATEPART(m,Time_Stamp) = DATEPART(m,#" & monthToImport & "#)) "
' ... during the year requested
mySQLCall = mySQLCall & "AND (DATEPART(yyyy,Time_Stamp) = DATEPART(yyyy,#" & monthToImport & "#)) "
mySQLCall = mySQLCall & "ORDER BY Time_Stamp"
Debug.Print "mySQLCall = " & mySQLCall
Debug.Print "monthToImport: " & monthToImport
'Error occurs on next line where execute query & populate the recordset
Set myRecordSet = myDB.OpenRecordset(mySQLCall, dbOpenSnapshot)
'Copy recordset to spreadsheet
Application.StatusBar = "Writing to spreadsheet..."
Debug.Print "RecordSet Count = " & myRecordSet.recordCount
If myRecordSet.recordCount = 0 Then
MsgBox "No data retrieved from database", vbInformation + vbOKOnly, "No Data"
GoTo SubExit
End If
'....
End Sub
Here is the Debug.Print of SQL statement as currently reads:
mySQLCall = SELECT Time_Stamp, GolfVolume, CreekVolume, InfluentVolume FROM Daily_Logs_of_Flows WHERE (DATEPART(m,Time_Stamp) = DATEPART(m,#6/1/2016#)) AND (DATEPART(yyyy,Time_Stamp) = DATEPART(yyyy,#6/1/2016#)) ORDER BY Time_Stamp
Any thoughts on what I am missing here? Thanks in advance for your help.
The problem is that the DATEPART function needs the first parameter in quotes, otherwise it looks for the field yyyy or m.
For example:
DATEPART("yyyy", #6/1/2016#)
or
DATEPART("m", #6/1/2016#)
In total:
SELECT Time_Stamp, GolfVolume, CreekVolume, InfluentVolume _
FROM Daily_Logs_of_Flows
WHERE (DATEPART("m",Time_Stamp) = DATEPART("m",#6/1/2016#))
AND (DATEPART("yyyy",Time_Stamp) = DATEPART("yyyy",#6/1/2016#))
ORDER BY Time_Stamp
To do this in VBA (in case you don't know, but I'm guessing you do), just double up the quotation marks each time you call the DATEPART function...
For example:
mySQLCall = mySQLCall & "AND (DATEPART(""yyyy"",Time_Stamp)...."
Just to be complete, Run-Time error '3008' is actually the first error....Access won't attempt to run any SQL until it can determine that it has the proper permissions.

Run-time error: The value you entered isn't valid for this field

I am trying to update a record using Subform. When I update the first time it updates properly but when I try to update the same record again I am getting the error:
Run-time error '-2147352567 (80020009)': The value you entered isn't valid for this field
The following is the form.
When I click edit, the information from the selected record is populated into the respective text-boxes. Once I update the information and click update, the record gets successfully updated for the first time.
When I try to update the same record again I get the mentioned error.
Here is the VB script that runs on clicking edit.
Private Sub cmdEdit_Click()
'Check if data exists in the list
If Not (Me.frmschoolsub.Form.Recordset.EOF And Me.frmschoolsub.Form.Recordset.BOF) Then
'get data to text box control
With Me.frmschoolsub.Form.Recordset
Me.Schooltxt = .Fields("School_Name")
Me.Desctxt = .Fields("Description")
Me.Deantxt = .Fields("Dean")
Me.Adeantxt = .Fields("Associate_Dean")
'store id of student in tag
Me.Schooltxt.Tag = .Fields("School_ID")
'change caption of button to update
Me.cmdAdd.Caption = "Update"
Me.cmdEdit.Enabled = False
End With
End If
End Sub
When I click on Debug it highlights the following line.
Me.Schooltxt = .Fields("School_Name")
Can you help me in identifying what is the issue here.
I figured that after the each update, I am losing the position of record. I added the following statement after update and Requery
Me.frmschoolsub.Form.Recordset.MoveFirst
Following is the code snippet.
Else
CurrentDb.Execute "Update School " & _
" SET School_Name ='" & Me.Schooltxt & "'" & _
", Description ='" & Me.Desctxt & "'" & _
", Dean ='" & Me.Deantxt & "'" & _
", Associate_Dean='" & Me.Adeantxt & "'" & _
"where School_ID=" & Me.Schooltxt.Tag
End If
'Clear the Fields
cmdClr_Click
'Refresh the table
frmschoolsub.Form.Requery
Me.frmschoolsub.Form.Recordset.MoveFirst
This fixed the issue.
This error is happening that a form field cannot be referenced to a textbox like you did.
You can do it as below.
With Me.frmschoolsub.Form.Recordset
Me.Schooltxt = Forms![<<if you have main form >>]![frmschoolsub].form![School_Name]

MS access sum results between two dates as text box in form

I issue following query in SQL and works fine
SELECT SUM(goudOpkoop.winst)
FROM goudOpkoop
WHERE goudOpkoop.date
BETWEEN '2015-1-10' AND '2015-1-22'
I would like to have the results in a Form in Textbox 3 (name Text183) when last of two dates, one in Textbox 1 (name Text179) and other in textbox 2 (name Text181) have been picked.
I think I would need to use AfterUpdate code builder for Textbox 2 and issue there the query to eventually show results in Textbox 3.
I have already linked with SQL server.
Information: ODBC;DSN=Essence Test;;TABLE=goudOpkoop
In me not being a professional in VBA I have no clue how to get this working.
Not tested, but should do the trick slightly, unless I made a typo.
Change the format of your 2 dates textboxes in "Short Date", that way you will have a calendar picker and you will ensure that your date have a correct format
Create this sub in your form module :
Private Sub CheckSUM()
Dim RST As Recordset
Dim SQL As String
' Reset the result textbox
Text183.value = ""
' If your 2 date textboxes are not populated, cancel
If Text179.Value = "" or Text181.Value = "" Then Exit Sub
' Prepare the query, with proper formating of the dates
SQL = " SELECT SUM(goudOpkoop.winst) AS mySum " & _
" FROM goudOpkoop " & _
" WHERE goudOpkoop.Date " & _
" BETWEEN '" & Format(Text179.Value, "YYYY-MM-DD") & "' " & _
" AND '" & Format(text181.Value, "YYYY-MM-DD") & "'"
' Execute the query
Set RST = CurrentDb.OpenRecordset(SQL)
' If the query is valid and returned something, we recuperate the value
If Not RST.BOF Then
Text183.Value = RST!mySum
End If
' Cleaning
RST.Close
Set RST = Nothing
End Sub
Then, for your 2 dates textboxes, create an afterupdate event and call the previous sub in them:
Private Sub Text179_AfterUpdate()
CheckSUM
End Sub
Private Sub Text181_AfterUpdate()
CheckSUM
End Sub

#Name? on form after requery in Access 2010

I am using VBA and SQL to re-query my main form based on criteria entered in several controls on a pop up form. As far as I can tell the code is running correctly, the database is re-queried based on the criteria I enter, but 2 of my controls on my main form show as #Name? or blank after re-querying based on the criteria. Anyone know how I can fix this???
The code that runs the re-query is:
Public Sub SuperFilter()
On Error GoTo Err_AdvancedFilter_Click
Dim strSQL As String
Dim strCallNumber As String
Dim strAsgnTech As String
Dim strClientID As String
Dim strCallGroup As String
Dim strPriority As String
Dim strOpenStatus As String
If IsNull(Forms![frmTips&Tricks].txtCallNumber) = False Then
strCallNumber = " (((CallInfo.CallNumber) = forms![frmTips&Tricks].[txtCallNumber])) and "
Else
strCallNumber = ""
End If
If IsNull(Forms![frmTips&Tricks].cboAsgnTech) = False Then
strAsgnTech = " (((CallInfo.AsgnTech) = forms![frmTips&Tricks].[cboasgntech])) and "
Else
strAsgnTech = ""
End If
If IsNull(Forms![frmTips&Tricks].cboClientID) = False Then
strClientID = " (((CallInfo.ClientID) = forms![frmTips&Tricks].[cboClientID])) and "
Else
strClientID = ""
End If
If IsNull(Forms![frmTips&Tricks].cboCallGroup) = False Then
strCallGroup = " (((CallInfo.AsgnGroup) = forms![frmTips&Tricks].[cboCallGroup])) and "
Else
strCallGroup = ""
End If
If IsNull(Forms![frmTips&Tricks].cboPriority) = False Then
strPriority = " (((CallInfo.Severity) = forms![frmTips&Tricks].[cboPriority])) and "
Else
strPriority = ""
End If
If Forms![frmTips&Tricks].optOpenStatus.Value = 1 Then
strOpenStatus = " (((CallInfo.OpenStatus) = True))"
Else
strOpenStatus = " (((CallInfo.OpenStatus) is not null ))"
End If
strSQL = "SELECT CallInfo.CallNumber, CallInfo.ClientID,* " & _
"FROM dbo_HDTechs INNER JOIN ([User] INNER JOIN CallInfo ON User.ClientID = CallInfo.ClientID) ON dbo_HDTechs.TechName = CallInfo.AsgnTech " & _
"WHERE " & strCallNumber & strAsgnTech & strClientID & strCallGroup & strPriority & strOpenStatus & _
"ORDER BY CallInfo.RcvdDate;"
Form.RecordSource = strSQL
Me.cboCallNumber.RowSource = strSQL
Form.Requery
If Me.RecordsetClone.RecordCount = 0 Then
MsgBox "No Records Found: Try Diferent Criteria."
Form.RecordSource = "qryservicerequestentry"
Me.cboCallNumber.RowSource = "qryservicerequestentry"
Exit Sub
End If
Me.cmdSuperFilterOff.Visible = True
Exit Sub
Exit_cmdAdvancedFilter_Click:
Exit Sub
Err_AdvancedFilter_Click:
MsgBox Err.Description
Resume Exit_cmdAdvancedFilter_Click
End Sub
The first control in question is a combo box that displays the Client Name from the CallInfo form (Main Form).
Control Source: ClientID
And when expanded lists all available clients to select from the Users form (User ID is linked between the User form and CallInfo form).
Row Source: SELECT User.ClientID FROM [User];
After the re-query, this combobox will be blank, sometimes showing #Name? if you click on it.
The second control in question is a text box that shows the Client's phone number.
Control Source: PhoneNo
After the Re-query, this text box always displays #Name?
The third control in question is a text box that displays the clients office location.
Control Source: Location
What really baffles me is that THIS text box displays correctly after the re-query. I don't know why it would display the correct data when the Phone Number text box does not, seeing as they are so similar and work with similar data....
To Compare, the The form record source is normally based on:
SELECT CallInfo.CallNumber, CallInfo.ClientID, CallInfo.RcvdTech, CallInfo.RcvdDate, CallInfo.CloseDate, CallInfo.Classroom, CallInfo.Problem, CallInfo.CurrentStatus, CallInfo.Resolution, CallInfo.Severity, CallInfo.OpenStatus, CallInfo.AsgnTech, dbo_HDTechs.Email, CallInfo.FullName, CallInfo.AsgnGroup, User.Location, User.PhoneNo, CallInfo.OpenStatus
FROM dbo_HDTechs INNER JOIN ([User] INNER JOIN CallInfo ON User.ClientID = CallInfo.ClientID) ON dbo_HDTechs.TechName = CallInfo.AsgnTech
WHERE (((CallInfo.OpenStatus)=True))
ORDER BY CallInfo.RcvdDate;
Just going on what you wrote, I may take a slightly different approach (just personal preference).
I would change all of your 'IsNull' tests to also check for 'Empty'. i.e.
If IsNull(Forms![frmTips&Tricks].cboClientID) = False AND ...cliientID <> ""
Just today I had an issue relating to form references in a query WHERE clause, so I changed to:
strClientID = " (((CallInfo.ClientID) = '" & forms![frmTips&Tricks].[cboClientID] & "')) and"
Add a Debug.Print of your generated SQL, then look at it and try to run that SQL manually
Good Luck,
Wayne
Solved by designating the form in the control source like: CallInfo.ClientID
I still don't know why the Client Office displayed Correctly... Anybody have a hint? :)
TE

Access VBA Object Required Error

This has probably been answered before, but in looking, I could not find an answer that suited my situation. I am coding an Access 2003 form button to run an If/Then and do some commands based on that statement when clicked. However I am getting the 'Object Required' error on every click. I am still relatively new to VBA code, so please be gentle.
Here is the code:
Private Sub Button_Click()
On Error GoTo Err_Button_Click
Dim Db As Object
Set Db = CurrentDb
Dim waveset As DAO.Recordset
Set waveset = Db.OpenRecordset("SELECT countervalue FROM dbo_tblSettings")
Dim orderfile As String
orderfile = "\\serverfolder\serverfile.csv"
If Value.waveset > 0 Then
MsgBox "Orders Already Imported; Please Proceed to Next Step", vbOKOnly, "Step Complete"
GoTo Exit_Button_Click
ElseIf Value.waveset = 0 Then
DoCmd.RunSQL "DELETE FROM dbo_tblOrders", True
DoCmd.TransferText acImportDelim, , "dbo_tblOrders", orderfile, True
DoCmd.RunSQL "UPDATE dbo_tblOrders INNER JOIN dbo_MainOrderTable ON dbo_tblOrders.[channel-order-id]=dbo_MainOrderTable.[order-id] " _
& "SET dbo_MainOrderTable.[order-id] = dbo_tblOrders.[order-id], dbo_MainOrderTable.[channel-order-id] = dbo_tblOrders.[channel-order-id], " _
& "dbo_MainOrderTable.[Order-Source] = 'Amazon'" _
& "WHERE dbo_tblOrders.[sales-channel]='Amazon';", True
DoCmd.RunSQL "UPDATE dbo_AmazonOrderTable INNER JOIN dbo_tblOrders ON dbo_AmazonOrderTable.[order-id]=dbo_tblOrders.[channel-order-id] " _
& "SET dbo_AmazonOrderTable.[order-id] = dbo_tblOrders.[order-id], dbo_AmazonOrderTable.[channel-order-id] = dbo_tblOrders.[channel-order-id], " _
& "dbo_AmazonOrderTable.[sales-channel] = 'Amazon' " _
& "WHERE dbo_tblOrders.[sales-channel]='Amazon';", True
DoCmd.RunSQL "UPDATE dbo_tblSettings SET countervaule=1", True
Else
GoTo Exit_Button_Click
End If
Exit_Button_Click:
Exit Sub
Err_Button_Click:
MsgBox Err.Description
Resume Exit_Button_Click
End Sub
-OH! forgot to mention I want to do it this way because the tables are actually linked tables to a SQL server back-end... I've also been trying to figure out how to open the connection to my SQL server and manipulate the tables via the VBA code without having to link them in Access... but that's another post altogether
Any help will be greatly appreciated. Thanks
I think the problem is the line
If Value.waveset > 0 Then
Which should be
waveset.Value > 0 Then
.Value is a property - it comes after the object, but it is not itself an object. Thus, asking for the .waveset property of Value will give an error.
The same thing happens again a few lines later:
ElseIf Value.waveset = 0 Then
The advice that #HansUp gave in his comment is a good one. Write Option Explicit at the top of your module, then hit Debug->Compile. Your code will generate errors. Add statements of the form
Dim waveset
to the top of your function. Only declare variables you intend to use. Any remaining errors are now due to typos or other syntax / logic errors, and will be spotted more easily.
If you are sure you know what type a particular variable will be, it is marginally more efficient to declare as that type; so
Dim ii As Integer
For ii = 0 To 10000
...
is marginally more efficient than
Dim ii
For ii = 0 To 10000
But that's not what your question is about.
Yes, ...If Value.waveset > 0 ... does give an error Object Required
BOTH lines need to be changed, but need to be this syntax ---
If waveset.Fields("countervalue").Value > 0
...
ElseIf waveset.Fields("countervalue").Value = 0 Then