Access 2013 VBA Editor Changes Date() to date - ms-access

When I type strDate = Date() it switches to strDate = date, and then the code does not run correctly because it does not know what "date" refers to. This is in a brand new Access 2013 database with only a single form with a button to run the code and a table with only one field to insert the date.
References that are checked for this database are:
Visual Basic For Applications
Microsoft Access 15.0 Object Library
OLE Automation
Microsoft Office 15.0 Access database engine Object Library
Dim strDate As String
strDate = Date()
DoCmd.SetWarnings False
Dim strSQL As String
strSQL = "INSERT INTO Table1 VALUES ('" & strDate & "');"
DoCmd.RunSQL strSQL
DoCmd.SetWarnings True

Since you are inserting a date value into your table, the value should not be enclosed with single quotes, else the data will be interpreted as a string.
Similarly, the Date function will return a date value, hence your variable strDate should be of type Date as opposed to String.
The automatic conversion of Date() to Date is to be expected and will still result in the Date function being evaluated with no arguments; I believe this conversion occurs because the symbol Date also corresponds to a data type.
However, an easier way to achieve this is to simply evaluate the Date function directly in the SQL code, for example:
DoCmd.RunSQL "INSERT INTO Table1 VALUES (Date());"

Related

Getting a date from a datetimepicker into mysql

I have a datetimepicker in my app which end users will use to choose when an item will be deferred to.
If the user picks a date and hits confirm, the date should be dropped into the mysql record for this entry, but I cant seem to get VB to update the DATE value :(
I'm thinking its probably a formatting thing, but I'm not sure how to best overcome this.
He're the code behind the 'confirm' button.
Private Sub ConfirmDefer_Click(sender As Object, e As EventArgs) Handles ConfirmDefer.Click
Dim deferdate As Date = Format(nb_deferdatepicker.Value, "yyyy-MM-dd")
updatesql("newbusiness_dataset", "action_date", deferdate, "id='" & nb_prospectid.Text & "'")
nb_defer_schedule.Visible = False
nb_defer_schedule.Enabled = False
End Sub
The 'UpdateSQL' bit is a function I use to simplify updating the db.
Its output SQL command is as follows:
UPDATE newbusiness_dataset SET action_date='20/02/2016' WHERE id='100001'
Any help appreciated! Thanks in advance
output SQL command is as follows:
UPDATE newbusiness_dataset SET action_date='20/02/2016' WHERE id='100001'
The way your function is updating is likely incorrect. Ticks are not all-purpose SQL variable delimiters. They are used to indicate text: so your method is converting the Date to string, and possibly the same for Id which are typically numeric. Similarly, this code:
Dim deferdate As Date = Format(nb_deferdatepicker.Value, "yyyy-MM-dd")
Using Option Strict On this will not compile. Format is a function returning a string, but the code is assigning the result to a DateTime var. There is simply no reason to try to format a DateTimePicker value, because it already is a date, and the MySQL NET data provider objects know how to pass a NET date to the db.
Given the resulting SQL, I also suspect you are using concatenation to glue bits of string together for the query. This is very dangerous and can lead to SQL injection attacks. It will also fail on names like Charles D'Artagnan or Pete's Plumbing.
SQL Parameters prevent this, allow you to pass typed data to the data provider and result in easy to read and maintain SQL. The general approach would be like this:
Dim rows As Int32
Dim SQL = "UPDATE Table_Name SET colA = #p1, colB = #p2, colC = #p3 WHERE Id = #p4"
Using dbcon As New MySqlConnection(connStr)
Using cmd As New MySqlCommand(SQL, dbcon)
cmd.Parameters.Add("#p1", MySqlDbType.String).Value = myFrm.TextBox1.Text
cmd.Parameters.Add("#p2", MySqlDbType.Int32).Value = intVar
cmd.Parameters.Add("#p3", MySqlDbType.DateTime).Value = DateTime.Now
' the where:
cmd.Parameters.Add("#p4", MySqlDbType.Int32).Value = intVarA
dbcon.Open()
rows = cmd.ExecuteNonQuery()
End Using
End Using
The USING blocks dispose of the things which should be disposed of to free resources
A new connection and command object are created, used and disposed of. Often helpers like to reuse these, but especially with the DBCommand object there is nothing reusable about them.
Since ExecuteNonQuery will report how many rows are affected, rows captures that result.
The magic, such as it is, is here:
cmd.Parameters.Add("#p3", MySqlDbType.Date).Value = datetimeVar
Using parameters you can pass an actual DateTime variable instead of text. You can use myDateTimePicker.Value because the value is a DateTime.
For a Date column, using MySqlDbType.Date the parameter will pass just the Date portion to the database.
MySqlDbType.DateTime will save whatever portion of the DateTime the DB is setup to accept.
The same is true using MySqlDbType.Int32 for the Id: rather than converting to string, you can pass the correct data type.

Use a variable to name a table I am making

I am using VBA macro to make a table. First, I am inputting a date "PeriodEnd", this date filters a base table using a query. Then, I am making a second table and populating that table with (a) the results of the query, and (b) about 30 calculated fields based on the records of the query and other related tables.
My problem is that I am trying to put the PeriodEnd date in the table name and I can't seem to get the Syntax right. I am a VBA beginner, so thanks for the help. My VBA looks like as follows:
....
Dim db as DAO.Database
Dim PeriodEnd as Date
Dim PerStr as String
Set db = CurrentDb()
PeriodEnd = #12/31/2013#
PerStr = Format(PeriodEnd, "yyyy-mm-dd")
db.Execute "CREATE TABLE TblName_" & PerStr _
& " (Field1 as LONG)
I've run this with syntax where the table name is static and I don't get any errors. When I run with the variable table name I get "Run-time error '3290': Syntax error in CREATE TABLE statement."
Also, is there a better way to structure this? The only difference in these table will be the period end date--and the impact that a different period end date has on the underlying calculations I am forming in the VBA (functions not supported within the SQL).
Any advice on whether this should be structured instead as a query or a report (no experience yet with reports)?
You're attempting to create a table whose name includes dashes (because of the date format). You will need to bracket that name.
db.Execute "CREATE TABLE [TblName_" & PerStr _
& "] (Field1 as LONG)"
Also make sure to include the quotation mark at the end of the statement as I did above.
But consider using a variable to hold your CREATE statement. Then you can Debug.Print the variable to inspect the statement you're asking the db engine to execute.
Dim strDdl As String
strDdl = "CREATE TABLE [TblName_" & PerStr & "] (Field1 as LONG)"
Debug.Print strDdl
db.Execute strDdl

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.

Converting in VBA Access

I have a question with my converting in VBA. I made a button in a form and when I press it, it should make an update in my database table, but I get an ERROR:
arithmetic overflow error converting numeric to data type numeric
How can solve this problem? Here is my code:
Private Sub Inserare_Click()
Dim strSQL As String
Dim rst As New ADODB.Recordset
strSQL = "UPDATE dbo.Soferi_test SET number= '" &
Me![subform_soferi].Form!certificat_cipti & _
"',drivers= '" & Me![subform_soferi].Form!categorii_permis & _
"' WHERE IDNO = " & Forms!Forma_redactare_soferi!IDNO
Call AttServ(strSQL, rst)
MsgBox ("Datele au fost introduse cu success")
End Sub
number is a reserved word. Bracket that name in your UPDATE statement so the db engine knows it's supposed to be a field name.
strSQL = "UPDATE dbo.Soferi_test SET [number]= '" &
If that change doesn't resolve the problem, inspect the completed SQL statement. Insert this line after you store the string to strSQL.
Debug.Print strSQL
You can view that output in the Immediate window (go there with Ctrl+g). You can then copy that statement text into SQL View of a new Access query for testing. Add the statement to your question if you can't get it to work properly and tell us whether you get the same or different error message.
It may also help to show us the code from your AttServ procedure which uses strSQL.
I think the problem is in the field type of the table you are trying to update.
Example: If you try to set the value of a small integer field to a long integer, value, Access will throw an error.
Check the type of your fields and set them to the appropriate type.
Other think that can be wrong is the value of the text boxes. Just to be sure, try to convert the values.
Example: Cdbl(Me![subform_soferi].Form!certificat_cipti) will convert the string in your text field to a double value.
Also, I recommend you use the value attribute of your text boxes:
Me![subform_soferi].Form!certificat_cipti.Value
or
CDbl(Me![subform_soferi].Form!certificat_cipti.Value)
Notice that if you use the "conversion" functions (CDbl, CInt, CDate, etc.) an error will be thrown if the conversion fails (for example, trying to convert 12abc to an integer will fail)

Information about syntax of ADO recordset filter queries

I spent much time trying to figure out how to extract date part in ado recordset filter expressions connecting to Jet engine working with an mdb file. The problem is that many things mentioned about access flavor of sql (date function for example) don't work there raising errors. Formatting dates with #mm/dd/yyyy hh:mm:ss# in comparisons works but gives incorrect results. Is there reliable source of information of what kind of expressions work for filters and what functions I can use?
UPDATE
The version used is when I choose Microsoft JET 4.0 OLE DB Provider. Generally one would expect that filter criteria can use the same syntax as the parts of the queries coming after WHERE keyword in SQL queries. My task was to compare date parts of time stamps and I finally decided to use query instead of filtered table, but the following example works when it's the part of the sql query (after WHERE) and raises "The application is using arguments that are of the wrong type, are out of acceptable range, or are in conflict with one another" error when it's the contents of the filter
format(TimeStamp,"yyyy/mm/dd")=format(#04/11/2013#,"yyyy/mm/dd")
So I see there's obvious differences between WHERE and filter syntax, but I could not find detailed explanation what exactly are they.
I'm actually quite surprised that WHERE Format([TimeStamp]... works in an ADO query against the Access Database Engine (ACE), but apparently it does.
I certainly agree that specific details on using some Microsoft features can be difficult to find in Microsoft's documentation. I guess that helps keep sites like Stack Overflow in business. ;)
As for your .Filter question, using Format() in this context does fail, presumably because Format() is a VBA function and is not (always) available to an expression outside of the Access application itself. However, the following test shows that...
rst.Filter = "[TimeStamp] >= #2013/04/11# AND [TimeStamp]<#2013/04/12#"
...does work. (When no time is specified for a DateTime value then midnight - 00:00:00 - is assumed.)
Test data:
ID TimeStamp
1 2013-04-10 21:22:00
2 2013-04-11 02:34:56
3 2013-04-11 04:45:15
Test code:
Sub foo()
Dim con As ADODB.Connection, rst As ADODB.Recordset
Set con = New ADODB.Connection
con.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data source=C:\Users\Gord\Desktop\Database1.accdb;"
Set rst = New ADODB.Recordset
Debug.Print "Test 1: WHERE Format([TimeStamp]..."
rst.Open _
"SELECT * FROM [TimeStampData] " & _
"WHERE Format([TimeStamp], ""yyyy/mm/dd"") = Format(#2013/04/11#, ""yyyy/mm/dd"")", _
con, adOpenKeyset, adLockOptimistic
Debug.Print "Records returned: " & rst.RecordCount
rst.Close
Debug.Print
Debug.Print "Test 2: Filter"
rst.Open "SELECT * FROM [TimeStampData]", con, adOpenKeyset, adLockOptimistic
Debug.Print "Total records: " & rst.RecordCount
rst.Filter = "[TimeStamp] >= #2013/04/11# AND [TimeStamp]<#2013/04/12#"
Debug.Print "Filtered records: " & rst.RecordCount
rst.Close
Set rst = Nothing
con.Close
Set con = Nothing
End Sub
Test results:
Test 1: WHERE Format([TimeStamp]...
Records returned: 2
Test 2: Filter
Total records: 3
Filtered records: 2
A short note on the (VBA) ADO filter syntax (applies also to DAO):
The filter should be specified as: "[Fieldname] = "
Where Fieldname is an existing name of a field in the recordset and can be anything that can be represented by a string. A non-string is allways converted to a string as the filtervalue will be transformed into an explicit SQL WHERE statement (Allways a string).
Valid filters would be:
rst.Filter="[TimeStamp] = #2013/04/12#" '(Mind the hashes as a date is expected. Peculiarly all localised notations are accepted!)
rst.Filter="[TimeStamp] = #" & strDatevalue & "#" 'Where strDatevalue is a datevalue as text.
Hence this will work:
rst.Filter="[TimeStamp] = #" & format(#04/11/2013#,"mm/dd"/yyyy) & "#"
'Mind: Access expects here an American standard date format, i.e. month/day/year
'(In that case you could even leave the hashes away!)
IF