VBA bad syntax in dlookup function with global variables - vba

I am using 8 similar functions in my code and they all work, but this one is not working:
global_var_13=DLookup("[amount]", "[tabla amortizacion real]","[no contract]= get_global('global_var_10') and [ident]=get_global('global_var_11') and [cuota]= get_global('global_var_12')")
var_10 is a string, var_11, var_12, and var_13 are numeric.
The values are var_10= "GAF-27/2013", var_11=1, var_12=1
global_var_13 is returning NULL
Any thoughts about the syntax?

Try to concatenate the clause elements:
global_var_13 = DLookup("[amount]", "[tabla amortizacion real]", "[no contract] = '" & get_global("global_var_10") & "' and [ident] = " & get_global("global_var_11") & " and [cuota] = " & get_global("global_var_12") & "")

Related

I am trying to lookup if a record already exist in a table

I am trying to see if a record already exist for a patient's permanent address. I tried the folowing code but it's giving me error as Data type mismatch in criteria expression matched . The AddressType is a textbox and ClientCategory is a Number. I have put the code onload event of the mainform:
If Not IsNull(DLookup("ID", "TableAddresses", "ID = '" & Me.PatientID & "' And AddressType = '" & "Permanent" & "' And ClientCategory = '" & Me.ClientCategory & "'")) Then
Me!FrmClienPatientAddressViewsubform.Form!SameAsLocal.Value = True
Else
Me!FrmClienPatientAddressViewsubform.Form!SameAsLocal.Value = False
End If
Something seems wrong here.
ID normally is a unique key, thus this should be the only value needed to look up the record:
If Not IsNull(DLookup("ID", "TableAddresses", "ID = " & Me.PatientID & "")) Then
Me!FrmClienPatientAddressViewsubform.Form!SameAsLocal.Value = True
Else
Me!FrmClienPatientAddressViewsubform.Form!SameAsLocal.Value = False
End If
Generally, the rule is: Strings within apostrophes, Integers without apostrophes.
If Gustavs solution isn't the right one and you need the other parameters, the solution could be:
Me!FrmClienPatientAddressViewsubform.Form!SameAsLocal.Value = _
Not IsNull(DLookup("ID", "TableAddresses", "ID = " & Me.PatientID & _
" And AddressType = 'Permanent' And ClientCategory = " & Me.ClientCategory))

sql where clause variable

I am using VBA and SQL. My VBA looks like
Dim SystemLookup As String
Dim SqlString As String
If IsNull(Me!SystemLookup) Then
Me!SystemLookup = ""
Else
SystemLookup = Me!SystemLookup
End If
SqlString = "SELECT TblField.*, TblOrigin.SystemID" _
& " FROM TblField INNER JOIN TblOrigin ON TblField.OriginID = TblOrigin.OriginID " _
& " WHERE (((TblOrigin.SystemID) = " & systemlookup )) ""
Me.RecordSource = SqlString
End Sub
I have my bracketing on the where clause is wrong but I am not sure how to fix. Any sugguestions (Systemlookup is a variable that is being passed from a form)
You need to put the brackets inside the string, not besides the variable.
Try this:
SqlString = "SELECT TblField.*, TblOrigin.SystemID" _
& " FROM TblField INNER JOIN TblOrigin ON TblField.OriginID = TblOrigin.OriginID " _
& " WHERE (((TblOrigin.SystemID) = " & systemlookup & ")) "
You are missing an ampersand and a double quote and have an extra opening bracket. The brackets are not needed in this simple query.
SqlString = "SELECT TblField.*, TblOrigin.SystemID" _
& " FROM TblField INNER JOIN TblOrigin ON TblField.OriginID = TblOrigin.OriginID " _
& " WHERE TblOrigin.SystemID = " & systemlookup & ";"
You would bracket WHERE clauses when you need to group conditions.
For example if you wanted to know if a product was shipped between two dates or if the product wasn't shipped then you would bracket it.
All three of these examples are valid:
WHERE ([Shipped Date]>=#10/28/2017# AND [Shipped Date]<=#10/30/2017#) OR [Shipped Date] is Null
WHERE ([Shipped Date]>=#10/28/2017# AND [Shipped Date]<=#10/30/2017#) OR ([Shipped Date] is Null)
WHERE (([Shipped Date]>=#10/28/2017# AND [Shipped Date]<=#10/30/2017#) OR ([Shipped Date] is Null))

SQL Variable in Where Clause

Dim varCity As String
varCity = Me.txtDestinationCity
Me.txtDestinationState.RowSource = "SELECT tPreTravelDestinationState FROM [TDestinationType] WHERE" & Me.txtDestinationCity & "= [TDestinationType].[tPreTravelDestinationCity]"
I am trying to select the states for the selected city. There is a drop down box with a list of cities. That box is titled txtDestinationCity.
It says I have an error in my FROM clause.
Thank you
You miss a space and some quotes. How about:
Me.txtDestinationState.RowSource = "SELECT tPreTravelDestinationState FROM [TDestinationType] WHERE '" & Me.txtDestinationCity & "' = [TDestinationType].[tPreTravelDestinationCity]"
Copy that next to your original to see the difference.
And for reasons SQL, PLEASE reverse the comparison. Always mention the column left and the value right:
Me.txtDestinationState.RowSource = "SELECT tPreTravelDestinationState FROM [TDestinationType] WHERE [TDestinationType].[tPreTravelDestinationCity] = '" & Me.txtDestinationCity & "'"
Since the quotes are annoying and easy to miss, i suggest defining a function like this:
Public Function q(ByVal s As String) As String
q = "'" & s & "'"
End Function
and then write the SQL string like that:
Me.txtDestinationState.RowSource = "SELECT tPreTravelDestinationState FROM [TDestinationType] WHERE [TDestinationType].[tPreTravelDestinationCity] = " & q(Me.txtDestinationCity)
This makes sure you ALWAYS get both quotes at the right places and not get confused by double-single-double quote sequences.
If you care about SQL-injection (yes, look that up), please use the minimum
Public Function escapeSQL(sql As String) As String
escapeSQL = Replace(sql, "'", "''")
End Function
and use it in all places where you concatenate user-input to SQL-clauses, like this:
Me.txtDestinationState.RowSource = "SELECT tPreTravelDestinationState FROM [TDestinationType] WHERE [TDestinationType].[tPreTravelDestinationCity] = " & q(escapeSQL(Me.txtDestinationCity))
Lastly, breakt it for readability. I doubt your editor shows 200 characters wide:
Me.txtDestinationState.RowSource = _
"SELECT tPreTravelDestinationState " & _
"FROM [TDestinationType] " & _
"WHERE [TDestinationType].[tPreTravelDestinationCity] = " & q(escapeSQL(Me.txtDestinationCity))
Note the trailing spaces in each line! Without them, the concatenation will not work.
It can be easier to troubleshoot your query construction if you set it to a variable (e.g., strSQL) first. Then you can put a breakpoint and see it right before it executes.
You need a space after WHERE. Change WHERE" to WHERE<space>"
Me.txtDestinationState.RowSource = "SELECT tPreTravelDestinationState FROM [TDestinationType] WHERE " & Me.txtDestinationCity & "= [TDestinationType].[tPreTravelDestinationCity]"

SQL Statement in Access

Ive been trying to get a query I ran in Access to run in VBA but I keep getting errors due to the number of exclamation marks I've been using. The statement I am using is
SQLstat = "SELECT tbl_Date_Check.DateofChecklist, tbl_Tasks.QuestionNumber,tbl_Tasks.Frequency, tbl_Tasks.Questions " _
& "FROM tbl_Tasks, tbl_Date_Check " _
& "WHERE (((tbl_Date_Check.DateofChecklist)=""" & [Forms]![Daily_Checker]![TxtDate] & """) And ((tbl_Tasks.Frequency) = """ & [Forms]![Daily_Checker]![ComFreq]"""))"
Any help would be great thanks
This can possibly be explained by the following SO question: What is the difference between single and double quotes in SQL?
This explains that you need to utilize single quotes '' to surround text in SQL in almost every instance. The fact that you are using double quotes "" may be what is causing the error.
I hope this helps.
-C§
It must read like this for dates:
SQLstat = "SELECT tbl_Date_Check.DateofChecklist, tbl_Tasks.QuestionNumber,tbl_Tasks.Frequency, tbl_Tasks.Questions " _
& "FROM tbl_Tasks, tbl_Date_Check " _
& "WHERE ((tbl_Date_Check.DateofChecklist = #" & Format([Forms]![Daily_Checker]![TxtDate], "yyyy\/mm\/dd") & "#) And (tbl_Tasks.Frequency = " & [Forms]![Daily_Checker]![ComFreq] & "))"

If/Then in SQL Embedded in VBA

I've got a string like this in my Excel VBA:
strSQL = "SELECT * FROM Total WHERE (SimulationID = (" & TextBox1.Text & ") And Test1 = (" & Example & "))"
However, sometimes Test will be 'is null', which makes the query
And Example = is NULL
How can I change it to add an if/then statement or something to make it say
And Example is null
when Example has a value of "is null"?
I would suggest doing the NULL comparison before assembling the SQL statement strSQL.
If you check for the value of Example beforehand, you can alter your strSQL statement accordingly based on that check.
EDIT:
In response to Daniel's first and second comment below, I still would prefer the following over doing it inline:
Dim strSqlTail
strSqlTail = ""
If (Example1 = Null) Then strSqlTail = "AND Example1 IS NULL"
If (Example2 = Null) Then strSqlTail = strSqlTail & "AND Example2 IS NULL"
If (Example3 = Null) Then strSqlTail = strSqlTail & "AND Example3 IS NULL"
...
Note: The strSqlTail can be whatever SQL would make your situation work since I don't quite understand what is being queried from the sample.
You just create a function that puts the equal sign and space before the number if it doesn't equal "is null", and modify the string assignment statement appropriately, like so:
Public Function NullModString(Example As String) As String
If Example <> "is null" Then Example = "= " & Example
NullModString = Example
End Function
strSQL = "SELECT * FROM Total WHERE SimulationID = " & TextBox1.Text & _
"And Test1 " & NullModString(Example)
Note, that I didn't understand why the extra parentheses were in there, but it would be simple to put them back in.
One solution is to coalesce out the null using a Coalesce function (or if using Access, the Nz function) :
trSQL = "SELECT ..." & _
" FROM Total" & _
" WHERE SimulationID = " & TextBox1.Text & " & _
" And Coalesce(Test1,"""") = "" & Example & """
A better way would be to dynamically include or not include the entire And statement based on whether Example had a value or to substitute Test Is Null when Example did not have a value. So something akin to:
Dim testElements() As Variant
Dim vElement As Variant
Redim testElements(6,1)
testElements(0,0) = Example1
testElements(0,1) = "Test1"
testElements(1,0) = Example2
testElements(1,1) = "Test2"
...
Dim elementIndex as Integer
Dim colName As String
Dim elementValue As Variant
For elementIndex = 0 To UBound(testElements)
elementValue = testElement(elementIndex, 0)
colName = testElement(elementIndex, 1)
If Len(Nz(elementValue)) = 0 Then
trSQL = trSQL & " And " & colName & " = """ & Example1 & """
Else
trSQL = trSQL & " And " & colName & " Is Null"
End If
Next
First, don't embed SQL in VBA: hard to maintain, SQL injection, etc. Use a stored proc on the database side (even Access has PROCEDUREs).
Second, use COALESCE (or equivalent logic) to handle your 'empty string equates to NULL' UI logic. You don't say which SQL syntax and you haven't posted schema DLL so we're merely guessing...
SQL Server:
CREATE PROCEDURE GetTotals
#SimulationID INTEGER,
#Test1 VARCHAR(20) = NULL
AS
SELECT *
FROM Total AS T1.
WHERE T1.SimulationID = #SimulationID
AND COALESCE(T1.Test1, '') = COALESCE(#Test1, '');
Access Database Engine (a.k.a. Jet):
CREATE PROCEDURE GetTotals
(
:SimulationID INTEGER,
:Test1 VARCHAR(20) = NULL
)
AS
SELECT *
FROM Total AS T1
WHERE T1.SimulationID = :SimulationID
AND IIF(T1.Test1 IS NULL, '', T1.Test1)
= IIF(:Test1 IS NULL, '', :Test1);
Then execute the proc using your middleware (ADO, DAO, etc) with Parameter objects, using the empty string (or other 'magic' value) for NULL.