odd double quotes in VBA interrogation to SQL database - sql

i have this piece of VBA code inside an Access file, but i don't understand how the quotes and double quotes are placed. there are 3 double quotes and not 4, so i don't understand what it should represent. other than that, there is the ";" at the end and i don't know why. can someone help me?
If CurrentDb.OpenRecordset("SELECT count(*) FROM Employees WHERE SerialNumber='" & Environ("Username") & "';").Fields(0) > 0 Then
[Employee].Value = CurrentDb.OpenRecordset("SELECT Initials FROM Employees WHERE SerialNumber='" & Environ("Username") & "';").Fields(0)
Else
[Employee].Value = Environ("Username")
End If

Related

Execute a SQL statement inside VBA Code

I am attempting to execute a SQL query inside of VBA Code. The query works in MS Access and asks the user to input a value for Customer_Name and Part_Number
What I have done is written the VBA Code in outlook so we can run the macro to execute the query from Outlook. The code I have currently works until the very bottom line on the DoCmd.RunSQL portion. I think I have this syntax incorrect. I need to tell it to run the string of SQL listed above:
Public Sub AppendAllTables()
Part_Number = InputBox("Enter Part Number")
Customer_Name = InputBox("Enter Customer Name")
Dim strsqlQuery As String
Dim Y As String
Y = "YES, Exact Match"
Dim P As String
P = "Possible Match - Base 6"
Dim X As String
X = "*"
strsqlQuery = "SELECT Append_All_Tables.Customer,
Append_All_Tables.CustomerCode, Append_All_Tables.PartNumber,
Append_All_Tables.Description, Append_All_Tables.Vehicle, SWITCH" &
Customer_Name & " = Append_All_Tables.PartNumber, " & Y & ", LEFT(" &
Part_Number & ",12) = LEFT(Append_All_Tables.PartNumber,12)," & Y & ",
LEFT(" & Part_Number & ",6) = LEFT(Append_All_Tables.PartNumber,6)," & P
& ") AS Interchangeability FROM Append_All_Tables WHERE" & Customer_Name
& "Like " & X & Customer_Name & X & "AND
LEFT(Append_All_Tables.PartNumber,6) = LEFT(" & Part_Number & ",6);"
Set appAccess = CreateObject("Access.Application")
appAccess.OpenCurrentDatabase "path.accdb"
appAccess.DoCmd.RunSQL "strsqlQuery"
End Sub
Please note, the path has been changed for privacy. The SQL code already works in Access. I am only needing the last line to be evaluated.
If you want to have a datasheet form view show these records you can use
DoCmd.OpenForm
First create a query with the data you want to see, then bind that to your form using the Record Source property, then when you call DoCmd.OpenForm pass in the filter you want.
I'm not following what you're trying to do with SWITCH in your query (is that supposed to be the switch() function? it has no parentheses). But you'll need to adjust that to join to use a Where statement instead.
I agree with a couple of the above posts.
You need to do a Debug.Print of the strsqlQuery variable BEFORE YOU DO ANYTHING! Then evaluate that statement. Does it look right? As Matt says, it doesn't look like you have line continuations, which would make your SQL statement incomplete (and thus, the computer doesn't think its a query at all).
My personal preference is to define the SQL like you have, then create the actual query using that SQL (create query def), and then call that query, because it will now be an actual object in the database. The QUERY can show up as a datasheet without any form requirement, but a pure SQL Statement cannot.
Michael
Remove the quotes.
appAccess.DoCmd.RunSQL "strsqlQuery" to appAccess.DoCmd.RunSQL strsqlQuery

SQL/ACCESS UPDATE

I am trying to update a table in Access using SQL in a VBScript. I have 2 statements that reference 2 tables. The first statement works and the second doesn't. The only difference in the two is a field name, and I cannot figure out what is wrong. I've been working on it for 6 hours now. Could anyone assist?
This works
DB.Execute "UPDATE tblDEBIT20 SET CONTROL = '" & strControl & "' WHERE DEBIT_NUM = '" & strDebit & "'"
This doesn't
DB.Execute "UPDATE tblDEBIT20 SET CURRENTNAME = '" & strCurrent & "' WHERE DEBIT_NUM = '" & strDebit & "'"
The error I get is
No value given for one or more required parameters.
I think the point being made by both Ken and Robert is that you most likely have a name with an apostrophe in it. You can either replace all single quotes (') with something else or try another quote delimiter.
See if this works for you (escaping double quotes when used inside double quotes).
DB.Execute "UPDATE tblDEBIT20 SET CURRENTNAME = """ & strCurrent & """ WHERE DEBIT_NUM = """ & strDebit & """"
A tip for you in future debugging - add a Debug.Print strCurrent before the execute command - then when it fails you can easily see what the issue is - or at least tell us what value it failed on.

MS Access query assistance INSERT

This query keeps telling me I'm missing a semicolon at end of SQL statement, but when I add it, it tells me that there's a character found at the end of the SQL statement, what is wrong here? I'm used to working with SQL Server so this is just plain confusing to me. I'm not sure why Access needs to use a ";" to close the query. I'm just not sure where to include it.
strSQL = "Insert Into [tempCaseMgmt]Values([planID],[EdId],[OrID],[TheDate], [TypeID],[UserID],[TimeStart],[TimeEnd],[Unitsled],[Unitsid],[ClientID], [GenderID])" _
& " Select * from [dbo_tempDetail] where [userid]= " & [Forms]![frmx]! [txtClientID] & ";"
I'm just trying to make this work. The values I'm selecting and inserting are identical.
As suggested by #Martin in one of the comments to his answer, you are mixing up the two forms of INSERT INTO, specifically,
INSERT INTO ... VALUES ...
and
INSERT INTO ... SELECT ...
In my own simplified example this fails with "Run-time error '3137': Missing semicolon (;) at end of SQL statement."
Dim strSQL As String
strSQL = "Insert Into [tempCaseMgmt]Values([planID],[UserID])" _
& " Select * from [dbo_tempDetail] where [userid]=1" & ";"
Dim cdb As DAO.Database
Set cdb = CurrentDb
cdb.Execute strSQL, dbFailOnError
whereas this works
Dim strSQL As String
strSQL = "Insert Into [tempCaseMgmt] ([planID],[UserID])" _
& " Select * from [dbo_tempDetail] where [userid]=1" & ";"
Dim cdb As DAO.Database
Set cdb = CurrentDb
cdb.Execute strSQL, dbFailOnError
Note that the Values keyword has been omitted.
Without looking too deep into it, I would say, you are missing a white space directly in front of your select Statement.
Update:
You missed a second white space in front of the "Values" keyword. Did you copy pasted this query, or did you just wrote it in?
I would say, that you try to use a mixed up statement syntax for the Insert Into Statement. Values is used for single record appending. That means you should have an semicolon after the closing parenthesis. For the interpreter the Select is a completely new Statement. I goes that is not what you want.
Use the multi record syntax for insert into:
"Insert Into [tempCaseMgmt] \n
Select * from [dbo_tempDetail] where [userid]= " & [Forms]![frmx]![txtClientID] & ";"
In this case column naming should be identically
best regards
Martin

Set Text Box equal to Query

I have a query in an Access Db that counts the number of observations that meet a certain criteria as defined by two comboboxes. The query works fine, and I can get the result of the query to display and update live with the comboboxes using subforms, but the subforms are an extremely ugly way to represent a single number.
I would like to use a textbox to display that single number from the query instead of a subreport. I've tried inputting the SQL of the query into the Control Source and the Default Value, but no success.
After reading through the forum it appears I can write a function and then set my control source equal to that function.
Here is my VBA:
Public Function AdultCount()
Dim rs As Recordset
Set rs=CurrentDb.OpenRecordset("Select Count([name]) as [# Vars] from Masterdb where ((masterdb.year=[forms]![Masterform]![NavigationSubform].[form]![year]) and (masterdb.recipient=[forms]![Masterform]![NavigationSubform].[form]![recipient]) and (masterdb.group="adult"))")
AdultVar=rs!Result
rs.Close
Set rs=Nothing
End Function
I get "compile error: Expected:list separator or )"
and it highlights "adult" at the end of my SQL query.
I don't know why this isn't working. Does anyone know why I'm getting this error, and tell me if I'm even doing the right thing to get what I want?
edit:
I now have
Dim strSQL AS String
strSQL = "Select Count([name]) as [# Vars] from Masterdb where [year] = " & Me.NavigationSubform.year.value & " and [recipient] = " & Me.NavigationSubform.recipient.value & " and [group]='adult'"
Set rs=CurrentDb.OpenRecordset(strSQL)
AdultVar=rs![# Vars].Value
rs.Close
Set rs=Nothing
End Function
But the textbox reads "#Name?"
Any ideas?
The double quotes for "adult" are throwing the error because you're closing and reopening a string without telling VB what to do with adult"))"). SQL needs single quotes anyway, so change it to 'adult' and the error will go away.
A second option is to build your string first, like so:
Dim strSQL AS String
strSQL = "Select Count([name]) as [# Vars] from Masterdb where [year] = " & Me.NavigationSubform.year.value & " and [recipient] = " & Me.NavigationSubform.recipient.value & " and [group]='adult'"
Set rs=CurrentDb.OpenRecordset(strSQL)
If you're not familiar with using the Me keyword, do a bit of reading up as it will shorten your code and save you time.

SQL Statement "LIKE" operator doesn't find the cells where only one number exists

I'm reading from an Excel XLS worksheet with no header rows. Some cells in the column have a list of numbers like 12345, 12346, 12347, 12348. Other cells only have one number 12345.
The "LIKE" operator finds the number when there are multiple numbers in a cell, but doesn't find the cells where only one number exists.
SQL = "SELECT * FROM [2010 VIP$] WHERE F9 LIKE '%" & sDealer & "%'"
I tried changing my connection string from:
"Data Source=" & dS & ";Extended Properties=""Excel 8.0;HDR=No"""
To (adding IMEX for mixed data types):
"Data Source=" & dS & ";Extended Properties=""Excel 8.0;HDR=No;IMEX=1"""
But I get an unknown error when IMEX is added. It's my understanding you can't use the F1, F2, F3 field names without HDR=No.
I tried using the first connection string but changed my SQL to:
SQL = "SELECT * FROM [2010 VIP$] WHERE F9 LIKE '%" & sDealer & "%' OR F9='" & sDealer & "'"
But it still doesn't find the cells with only one number.
EDIT: I ended up using a slower method but it works and still checks 1200 rows in like 2 seconds:
Dim cN As New ADODB.Connection
Dim rS As New ADODB.Recordset
Dim SQL As String
Dim dDealer As Double
Dim WS As Worksheet
Dim sDealer As String, sAmount As String
Dim bFound As Boolean
Set WS = ActiveSheet
cN.Provider = "Microsoft.Jet.OLEDB.4.0"
cN.Open "Data Source=" & MostRecentPath & ";" & _
"Extended Properties=""Excel 8.0;IMEX=1"""
For dDealer = 2 To WS.Range("a60000").End(xlUp).Row
sAmount = WS.Range("c" & dDealer).Value
If Len(sAmount) > 0 Then GoTo skipOne
sDealer = Trim(WS.Range("i" & dDealer).Value)
If Len(sDealer) <> 5 Then GoTo skipOne
If IsNumeric(sDealer) = False Then GoTo skipOne
SQL = "SELECT * FROM [2010 VIP$]"
rS.Open SQL, cN, adOpenStatic, adLockOptimistic
bFound = False
Do While rS.EOF = False
If InStr(1, rS.Fields(8).Value, sDealer) > 0 Then
bFound = True
Exit Do
End If
rS.MoveNext
Loop
rS.Close
If bFound = True Then WS.Range("l" & dDealer).Value = "VIP"
DoEvents
skipOne:
Next dDealer
cN.Close
The single-number cells are numeric and won't be found using the string-based like operator. You could try forcing the cells to be text cells by prepending the number with an apostrophe (eg. '12345).
You could also try
SELECT * FROM [2010 VIP$] WHERE F9 LIKE '%" & sDealer & "%' OR F9=" & sDealer & "
(no single quotes in the second part of the where clause)
As well as setting the IMEX option, sort the data in the worksheet to ensure that the first eight rows contain cells that will be interpreted as text - i.e. ones with multiple values like 12345,12346,12347,12348
Quoting from this KB article:
NOTE: Setting IMEX=1 tells the driver
to use Import mode. In this state, the
registry setting ImportMixedTypes=Text
will be noticed. This forces mixed
data to be converted to text. For this
to work reliably, you may also have to
modify the registry setting,
TypeGuessRows=8. The ISAM driver by
default looks at the first eight rows
and from that sampling determines the
datatype. If this eight row sampling
is all numeric, then setting IMEX=1
will not convert the default datatype
to Text; it will remain numeric.
Alternatively, consider normalising your data in the spreadsheet as this is the real problem here
First, I agree with #barrowc: the underlying problem is that your 'lists of numbers' violates first normal form (1NF) and SQL is not designed to query non-scalar data types (i.e. lacks operators to exploit multi-valued data).
Second, you need to get your connection string and registry settings correct for ADO to 'see' the column as text. This article may help with this.
If you must work with the not first normal form (NFNF) data, you will need to handle the comma delimiters.
Here is some standard SQL with test data to demonstrate the point:
WITH Dealers (dealer_ID, delear_list)
AS
(
SELECT dealer_ID, delear_list
FROM (
VALUES (1, '12345,12346,12347,12348'),
(2, '12344,12345,12346'),
(3, '12343,12344,12345'),
(4, '12345'),
(5, '12399,12346,12347,12348'),
(6, '12344,12399,12346'),
(7, '12343,12344,12399'),
(8, '12399')
) AS Dealers (dealer_ID, delear_list)
)
SELECT dealer_ID, delear_list
FROM Dealers
WHERE (',' + delear_list + ',') LIKE ('%,12345,%');
Obviously, you'd need to port this to ACE/Jet dialect code e.g.
WHERE (',' & delear_list & ',') ALIKE ('%,12345,%');
Jet does not use % for pattern matching. It uses * instead. It also does match patterns against numbers, as if they were strings. So I suspect you would be able to return to your pattern matching approach if you changed your SQL string from "SELECT * FROM [2010 VIP$] WHERE F9 LIKE '%" & sDealer & "%'" to "SELECT * FROM [2010 VIP$] WHERE F9 LIKE '*" & sDealer & "*'".