Data type miss match in criteria exxpression access - ms-access

I am going to VBA for deleting data table.
It shows the errors shown in the screenshot.
Please help me to resolve it.
Private Sub cmdxoa_Click()
If Not (Me.frmformsub1.Form.Recordset.EOF And Me.frmformsub1.Form.Recordset.BOF) Then
If MsgBox("Do you wwant to delete ?", vbYesNo) = vbYes Then
CurrentDb.Execute "DELETE from db " & _
" where NOLC = " & Me.frmformsub1.Form.Recordset.Fields("nolc")
Me.frmformsub1.Form.Requery
End If
End If
End Sub

So if NOLC in the table is of type text, your criteria expression has to be:
"where NOLC = '" & Me.frmformsub1.Form.Recordset.Fields("nolc").Value & "'"
As you see you have to surround the value with '.
Remark: .Value isn't necessary, but it enhances the readability and assures that you are interested in the value and not in the object itself (the control in that case).
BUT: You should use parametrized queries instead string concatenation to avoid SQL injection:
How do I use parameters in VBA in the different contexts in Microsoft Access?

Related

Look for duplicate records before adding a record

I clipped this from another post, since it is similar to what I need. Instead of using me.ID, etc, I need to reference a field in another table, specifically [Formdate] in a table named Brief Sheet.
I tried many variations, such as table "Brief Sheet".Formdate but no luck
What would be the proper syntax?
rst.FindFirst "[ID] <> " & Me.ID & _
" AND [TitleText] = '" & Me.TitleText & _
"' AND [UnitCode] = " & Me.UnitCode & _
" AND [AcademicYear] = " & Me.AcademicYear & _
" AND [Titleofchapterjournalarticle] = '" & Me.Titleofchapterjournalarticle & "'"
Use Dlookup. In the snippet you posted, the coder has already instantiated a recordset and is using recordset methods to find a record within it. What you said you want to do is actually a little simpler.
Below is a test procedure to illustrate getting your date value from your table.
You didn't clarify what criteria you would use to select the proper FormDate from the table "Brief Sheet", so I included "ID=3", which will select the FormDate record, whose ID=3. Adjust that as necessary.
Also, if your table name really is "Brief Sheet", and you have the ability to rename it, I highly recommend establishing some naming convention rules for your tables, first not having any spaces. Even Brief_Sheet would make your life easier down the road.
Public Sub Test1()
'dimension a variable to hold the date value
Dim datFormDate As Date
'fill the variable with the value you need to reference
datFormDate = DLookup("FormDate", "Brief Sheet", "ID = 3")
'Print the value to the "immediate" pane (just for testing)
Debug.Print datFormDate
'If you're running this code from within your form module, you can assign
'the value in your variable to a field in your table as such:
me.DateFieldtxtbx = datFormDate
End Sub

filter continuous form using textbox

I need to let users filter a continuous form using values the user enters into a textbox. And the continuous form is also nested within a couple levels of navigation subforms. This sounds easy enough, but all the examples I find on the web use macros instead of vba.
I set up the structure and wrote an AfterUpdate procedure for a textbox txtFilter as follows:
Private Sub txtFilter_AfterUpdate()
Dim filterval As String
filterval = txtFilter.Value
With Forms!Main!NavigationSubform.Form!NavigationSubform.Form
.Filter = "LastName Like " & filterval
.FilterOn = True
End With
End Sub
I have played with different syntax, but none of it seems to work properly. Here is a link to download the relevant parts of the database from a file sharing site: http://jmp.sh/v/HGctZ4Ru74vDAjzN43Wq
Can anyone show me how to alter this so that users can use the textbox to filter the continuous form?
I got it to work using this: .Filter = "LastName Like """ & filterval & """"
Need those annoying String Identifiers even for strings sometimes.
Okay, To get the form to open with no records and then pull up just the records you (or the user) specifies is easiest with a bit of re-work.
(I'd recommend you working with a copy and not your original)
1:On your Continuous Form, remove the Recordsource; we're going to use Late Binding (Kinda)
2:Then delete the code under the txtFilter box, then delete the box itself.
3:Add a comboBox with something like this as the recordsource:
SELECT DISTINCT myTable.LastName FROM myTable ORDER BY myTable.LastName; (This will get you a unique list of last names so knowing how to spell the name will not be necessary, plus it assures at least one match)
4:In the After Update event of that combobox, add code like this:
Dim strSource As String
strSource = "SELECT mt.IntakeNumber, mt.ClientNumber, " & _
"mt.LastName, mt.FirstName, mt.ConsultationDate " & _
" FROM myTable mt " & _
"WHERE (mt.LastName)= '" & Me.cboFilter.Value & "'"
Me.RecordSource = strSource
Me.Requery
Obviously you'll need to change the table and field names as necessary, but hopefully you get the idea.
Option Compare Database
Option Explicit '<- always include this!!!!!
Private Sub txtFilter_AfterUpdate()
Dim strFilter As String
' only set Filter when text box contains something
' to search for ==> don't filter Null, empty string,
' or spaces
If Len(Trim(Me.txtFilter.Value & vbNullString)) > 0 Then
strFilter = "LastName Like '*" & _
Replace(Me.txtFilter.Value, "'", "''") & _
"*'"
' that Replace() prevents the procedure from breaking
' when the user enters a name with an apostrophe
' into the text box (O'Malley)
Debug.Print strFilter ' see what we built, Ctrl+g
Me.Filter = strFilter
Me.FilterOn = True
Else
' what should happen here?
' maybe just switch off the filter ...
Me.FilterOn = False
End If
End Sub

Escaping unwanted characters, mainly single quotes --replace function and implementation

I was just testing my database and I realized that I run into problems wherever a text entry in my database contains a ' character (single quote). My solution for now is that before any .execute operations on a string, I call escape(string, "'", " "'" ").
Summarized example below:
qr = "INSERT INTO tblExample VALUES ( " & "'" & me.testparam & "'" & ");"
qr = Replace(qr, "'", " "'" ")
db.execute qr
'also tried qr = "INSERT INTO tblExample VALUES ( " & "'" & replace(me.testparam,"'"," ") & "'" & ");"
This was what I assumed to be the correct workaround to prevent errors from values such as Tourette's.
There's two problems with this. First of all, it's not working. Second, I have over 50 locations in code throughout my app where I call the statement db.execute qr where qr is a string that could potentially contain a single quote. I need the field in the table to contain the single quote, so I can't just replace it with a space or something similar.
Two part question:
Is there a better solution than going through all of my code calling Replace on every string that is to be executed as a query?
Why is my current implementation failing? - I still get syntax error in query expression even when escaping the single quote to a space.
First examine these 2 lines.
"VALUES ( " & "'" & me.testparam & "'" & ");"
"VALUES ( '" & me.testparam & "');"
Both will produce the exact same string. The difference for me is that my brain comprehends the second version faster.
Now, here is what the comments are telling you to do ... replace each single quote in your source string with two single quotes. I added Debug.Print so you can view the finished string in the Immediate window (go there with Ctrl+g) ... you can then see the actual string rather than trying to imagine what it looks like.
qr = "INSERT INTO tblExample VALUES ( '" & _
Replace(Me.testparam, "'", "''" & "');"
Debug.Print qr
db.Execute qr, dbFailOnError
Since I assumed db is a DAO.Database object variable, I included the dbFailOnError option. You should include an error handler in your code to deal with any problems dbFailOnError exposes.
When you run into trouble with a VBA function in a query, drop to the Immediate window and test your function expression there. This one triggers a compile error, "Expected: list separator or )":
? Replace("Tourette's", "'", " "'" ")
But this one works:
? Replace("Tourette's", "'", "''")
Tourette''s
I mentioned that because it's useful in general, and also because your title starts with "Escaping unwanted characters, mainly single quotes". So if you want to remove/replace other characters, not just single quotes, experiment in the Immediate window until you find a Replace() expression which works. Then use that expression in your query.
For example, if unwanted characters include line breaks ...
MyString = "foo" & vbCrlf & "bar" : ? MyString
foo
bar
? Replace(MyString, Chr(13) & Chr(10), " ")
foo bar
Note: I used Chr(13) & Chr(10) rather than vbCrlf as the find target because the db engine can use the Chr() function but doesn't know about the named constant (vbCrlf).
Your query is failing because you have not said where to insert :
Dim qd As QueryDef
qr = "INSERT INTO tblExample (AText) VALUES ( [avalue] );"
Set qd = CurrentDB.CreateQueryDef("",qr)
qd.Parameters("avalue").Value = me.testparam
qd.Execute dbFailOnError
Another method is to define a quote as constant (Const Quote = """") and use that to build SQL Statements. It is not possible to define a quote as Const Quote = Chr(34) as a constant definition can't be based on a function so one has to use four double quotes in a row. The third quote is what you are saving, the second quote is to excape the third quote and the first and last quote are because the value you are assigning is a string.
You will then be able to build SQL statements such as:
SQL = SELECT * FROM tblSyndromes
WHERE Syndrome = " & Quote & "Tourette's" & Quote & ";"
It will no longer matter that there are single quotes in your data.
I don't use parameters as if I upscale my database to sql server and convert my queries to pass-through queries, I can't use parameters. I rarely upscale but I write all my code with that assumption. Also if your query is not working as expected, how do find out what went wrong. If I have a variable called SQL, then I can always print the SQL statement and run it in a new query to see what it does.

MS-Access 2003 - Expression in a Text Box on a form

just wondering when using an expression on a form in a text box, to return a value from a table, can the expression have multiple tables in the expression to return the value?
the tables are linked and I can return the value in a query, so I figured that Access would be able to do it with this method as well????
=DSum("[tblMain]![Revenue]","tblMain","[tblMain]![Quarter]=3 AND [tblMain]![Region]='NorthEast'" AND [tblOffice]![Location]='NewYork'")
this is the expression that I entered into my text box, without the reference to the 2nd table it works fine, but once I had it, I get the flickering error message in the text box (just as on a report)......
I know this method is probably used more in reports than forms, but I am novice, and trying to come up with a dashboard solution that returns lots of facts quickly per department. I am using this in the "Control Source" field of the data tab of the properties window, not VB. Mainly because I do not know how to get it to work with VB.
Thanks for the help as always!
As far as I know, you cannot refer to more than one table or query in a domain aggregate function. As grazird says, how are these tables related? Let us say it is on tblMain ID, you can build a query called, say, qryMainOffice, the SQL (SQL View, Query Design window) would look something like:
SELECT [tblMain].[Revenue],[tblMain]![Quarter],[tblMain]![Region],
[tblOffice]![Location]
FROM tblMain
INNER JOIN tblOffice
ON tblMain.ID = tblOffice.MainID
DSum would then be (remove line break):
=NZ(DSum("[Revenue]","qryMainOffice",
"[Quarter]=3 AND [Region]='NorthEast' AND [Location]='NewYork'"),"Not found")
You could also use a recordset or query in VBA to return the value.
EDIT re COMMENT
To use the above in VBA, you either need to add parameters or use a string:
''Reference: Microsoft DAO 3.x Object Library
Dim rs As DAO.Recordset
Dim db As Database
Dim strSQL as String
Set db= CurrentDB
strSQL = "SELECT Sum(t.[Revenue]) As TotalNY" _
& "FROM tblMain t " _
& "INNER JOIN tblOffice o " _
& "ON t.ID = o.MainID " _
& "WHERE t.[Quarter]=3 AND t.[Region]='NorthEast' " _
& "AND o.[Location]='NewYork' " _
'' I have use aliases for simplicity, t-tblMain, o-tblOffice
'' If you wish to reference a control, use the value, like so:
'' & " AND [Location]='" & Me.txtCity & "'"
'' Dates should be formated to year, month, day
'' For joins, see http://www.devshed.com/c/a/MySQL/Understanding-SQL-Joins/
Set rs = db.OpenRecordset strSQL
If Not rs.EOF Then
Me.txtAnswer = rs!TotNY
Else
Me.txtAnswer = "N/A"
End If
You can also use different queries to return several results that can be shown with a list box or a subform:
strSQL = "SELECT TOP 5 o.[Location]," _
& "Sum(t.[Revenue]) AS TotRevenue" _
& "FROM tblMain t " _
& "INNER JOIN tblOffice o " _
& "ON t.ID = o.MainID " _
& "WHERE t.[Quarter]=3 AND t.[Region]='NorthEast' " _
& "GROUP BY o.[Location]"
The above would return revenue for quarter 3 for all locations in NorthEast region. If you want the top values of each group, you are looking at a more complicated query, which I will leave for now.
How are these tables related? Can you describe the relationship and any primary/foreign keys?
Also, referencing the table name is not necessary in the first parameter of this function (since it is already taken care of in the second one).
For example, your code could be:
=DSum("Revenue","tblMain","Quarter=3 AND Region='NorthEast'" AND [tblOffice]![Location]='NewYork'")
Just trying to save you some keystrokes and increase its readability. :)

How can I check for null values in Access?

I am new to Access. I have a table full of records. I want to write a function to check if any id is null or empty. If so, I want to update it with xxxxx.
The check for id must be run through all tables in a database.
Can anyone provide some sample code?
I'm not sure if you are going to be able to find all tables in the database with Access SQL. Instead, you might want to write up some VBA to loop through the tables and generate some SQL for each table. Something along the lines of:
update TABLE set FIELD = 'xxxxxx' where ID is null
Check out the Nz() function. It leaves fields unaltered unless they're null, when it replaces them by whatever you specify.
For reasonable numbers and sizes of tables, it can be quicker to just
open them
sort by each field in turn
inspect for null values and replace manually
It's good practice to find out where the nulls are coming from and stop them - give fields default values, use Nz() on inputs. And have your code handle any nulls that slip through the net.
I'm calling it the UpdateFieldWhereNull Function, and shown is a Subroutine which calls it (adapted from http://www.aislebyaisle.com/access/vba_backend_code.htm)
It updates all tables in the DbPath parameter (not tested, handle with care):
Function UpdateFieldWhereNull(DbPath As String, fieldName as String, newFieldValue as String) As Boolean
'This links to all the tables that reside in DbPath,
' whether or not they already reside in this database.
'This works when linking to an Access .mdb file, not to ODBC.
'This keeps the same table name on the front end as on the back end.
Dim rs As Recordset
On Error Resume Next
'get tables in back end database
Set rs = CurrentDb.OpenRecordset("SELECT Name " & _
"FROM MSysObjects IN '" & DbPath & "' " & _
"WHERE Type=1 AND Flags=0")
If Err <> 0 Then Exit Function
'update field in tables
While Not rs.EOF
If DbPath <> Nz(DLookup("Database", "MSysObjects", "Name='" & rs!Name & "' And Type=6")) Then
'UPDATE the field with new value if null
DoCmd.RunSQL "UPDATE " & acTable & " SET [" & fieldName & "] = '" & newFieldValue & "' WHERE [" & fieldName & "] IS NULL"
End If
rs.MoveNext
Wend
rs.Close
UpdateFieldWhereNull = True
End Function
Sub CallUpdateFieldWhereNull()
Dim Result As Boolean
'Sample call:
Result = UpdateFieldWhereNull("C:\Program Files\Microsoft Office\Office\Samples\Northwind.mdb", "ID", "xxxxxx")
Debug.Print Result
End Sub