Using Cell reference in SQL query - vba

I am using below VBA command to extract data using a SQL query by using a cell reference as filter.
Public Sub Run()
Dim SQL As String
Dim Connected As Boolean
Dim server_name As String
Dim database_name As String
Dim Allocation As String
Sheets("Perc").Select
Range("A6").Select
Selection.CurrentRegion.Select
Selection.ClearContents
' Our query
SQL = "SELECT Segmentation_ID,MPG,SUM(Segmentation_Percent) AS PERC " & _
"FROM dbo.HFM_ALLOCATION_RATIO " & _
"WHERE Segmentation_ID = " & Sheets("Perc").Range("A1").Value & " " & _
"GROUP BY Segmentation_ID,MPG ORDER BY MPG"
' Connect to the database
server_name = Sheets("General").Range("D1").Value
database_name = Sheets("General").Range("G1").Value
Connected = Connect(server_name, database_name)
If Connected Then
' If connected run query and disconnect
Call Query(SQL)
Call Disconnect
Else
' Couldn't connect
MsgBox "Could Not Connect!"
End If
End Sub
But when I run the macro, it's showing a runtime error
Invalid column name ALO0000274
Here ALO0000274 is the filter I set in A1.
Kindly help to fix this error.

Add quotes to your where clause (you're passing a text value, so you need to include quotes):
SQL = "SELECT Segmentation_ID,MPG,SUM(Segmentation_Percent) AS PERC " & _
"FROM dbo.HFM_ALLOCATION_RATIO " & _
"WHERE Segmentation_ID = '" & Sheets("Perc").Range("A1").Value & "' " & _
"GROUP BY Segmentation_ID,MPG ORDER BY MPG"
(Note the single quotes ' that enclose the value you want to filter)

I don't see where you are adding your single quotes around your string. Have you tried changing your WHERE clause portion of your SQL statement to "WHERE Segmentation_ID = '" & Sheets("Perc").Range("A1").Value & "' "

Related

syntax error (missing operator) in query expression '2020-12-01'

I wrote this code. When I try to activate this sub I always get this problem "syntax error (missing operator) in query expression '2020-12-01'". It's something wrong with Date (data in Polish means date).
Could u help me to fix this ?? I just want to take "Kolejka", "stadion", "Data" from form and add to my table Rozgrywki.
I also attached pictures of this error and picture of my form in access.
Runtime error "3075"
Dialog being composed
Public Sub Dodaj(Kolejka, stadion, Data, DA, DB, Optional wa = 0, Optional wb = 0)
If [wa] = "" Then wa = 0
If [wb] = "" Then wb = 0
DoCmd.SetWarnings False
dodaj_rozgrywka = "" & _
"INSERT INTO Rozgrywki ( IDStadionu, Data, Idkolejki)" & _
"SELECT " & stadion & " AS Wyr1, #" & Data & "# AS Wyr2;, " & Kolejka & " AS Wyr3;"
DoCmd.RunSQL (dodaj_rozgrywka)
Format your date value to a string expression:
"SELECT " & stadion & " AS Wyr1, #" & Format(Data, "yyyy\/mm\/dd") & "# AS Wyr2;, " & Kolejka & " AS Wyr3;"
Or use my CSql function. Even better, learn yourself to use queries with parameters.

Access Run-Time error 2465. Can't find the field '1' referred to in your expression

I need help with this code.
Option Compare Database
Option Explicit
Private Sub BTNSEARCHOnetoOne_Click()
Dim SQL As String
SQL = "SELECT [00_SheetList-Revit-UNION].PACKAGE, [00_SheetList-Revit-UNION].DRAWING, [00_SheetList-Revit-UNION].DISCIPLINE, Hillsboro_OR_xlsx.FileName_Hillsboro_OR, Hillsboro_OR_xlsx.FilePath_Hillsboro_OR FROM Hillsboro_OR_xlsx, WHERE(([00_SheetList-Revit-UNION].PACKAGE) Like '" & Me.TXTKeywordsPackage & "') AND ((Hillsboro_OR_xlsx.FileName_Hillsboro_OR) Like ('*" & ([00_SheetList-Revit-UNION].DRAWING) & "*')"
Me.SubONEtoONEInsideJoin.Form.RecordSource = SQL
Me.SubONEtoONEInsideJoin.Form.Requery
Me.SubONEtoONENullJoin.Form.Requery
End Sub
Private Sub Detail_Click()
End Sub
I narrowed it down to this part of the code.
"...((Hillsboro_OR_xlsx.FileName_Hillsboro_OR) Like ('*" & ([00_SheetList-Revit-UNION].DRAWING) & "*')"
As I can take this part out and it works. Is this just syntax?
Currently, your SQL has a number of syntax issues:
Comma before WHERE clause;
Unclosed parentheses in last WHERE condition;
Unknown alias ([00_SheetList-Revit-UNION]) not referenced in FROM or JOIN clauses. Possibly you meant to cross join this source with Hillsboro_OR_xlsx.
See issues with current code with line breaks for illustration:
SQL = "SELECT [00_SheetList-Revit-UNION].PACKAGE," _
& " [00_SheetList-Revit-UNION].DRAWING," _
& " [00_SheetList-Revit-UNION].DISCIPLINE," _
& " Hillsboro_OR_xlsx.FileName_Hillsboro_OR, " _
& " Hillsboro_OR_xlsx.FilePath_Hillsboro_OR " _
& " FROM Hillsboro_OR_xlsx, " _
& " WHERE(([00_SheetList-Revit-UNION].PACKAGE) " _
& " Like '" & Me.TXTKeywordsPackage & "') " _
& " AND " _
& " ((Hillsboro_OR_xlsx.FileName_Hillsboro_OR) " _
& " Like ('*" & ([00_SheetList-Revit-UNION].DRAWING) & "*')"
These issues can be mitigated with parameterized queries (an industry best practice when writing SQL in application code) which is supported in MS Access using QueryDef Parameters. Below are a few advantages and further below adjustment to your setup.
Saving a stored query instead of a VBA string query allows it is to be optimized by engine and the Access GUI will not allow query to be saved with syntax issues;
Abstract data from code, specifically VBA variables from SQL statement;
Readability and maintainability is enhanced.
SQL (with no VBA)
Save below as a stored Access query, using parameters and table aliases. Also, [00_SheetList-Revit-UNION] is cross joined (comma-separated in FROM clause) as assumed above.
PARAMETERS [PackageParam] Text;
SELECT o.PACKAGE, o.DRAWING, o.DISCIPLINE,
h.FileName_Hillsboro_OR, h.FilePath_Hillsboro_OR
FROM Hillsboro_OR_xlsx h, [00_SheetList-Revit-UNION] o
WHERE ((o.PACKAGE) Like [PackageParam])
AND ((h.FileName_Hillsboro_OR) Like '*' & o.DRAWING & '*');
VBA
Private Sub BTNSEARCHOnetoOne_Click()
Dim qDef As QueryDef
Dim rst As Recordset
' OPEN SAVED QUERY
Set qDef = CurrentDb.QueryDefs("mySavedQuery")
' BIND PARAMETERS
qDef![PackageParam] = "*" & Me.TXTKeywordsPackage & "*"
' BUILD RECORDSET FROM QUERYDEF AND SET TO SUBFORM
Set rst = qDef.OpenRecordset()
Me.SubONEtoONEInsideJoin.Form.Recordset = rst
Me.SubONEtoONENullJoin.Form.Requery
Set qDef = Nothing
End Sub
It looks like that you had something wrong here
you have written
Like '" & Me.TXTKeywordsPackage & "'
but it has to be like this
Like '*" & Me.TXTKeywordsPackage & "*'
you had this part wrong
check this below part
Like ('*" & ([00_SheetList-Revit-UNION].DRAWING) & "*')
Make sure that you are getting the value from textbox. It looks like you are calling table column.
Carefully count your parenthesis.
There should be an additional ) at the very end.

VBA Query that pulls data from both excel table and SQL database

I have been working on this for quite a while and I can't seem to figure it out. I am trying to create a query in excel that combines information from an excel table and database. I can do each of them separately no problem.
Here is the VBA code for the excel query:
Sub ExcelQuery()
'
Range("Table_Query_from_Excel_Files5[[#Headers],[Customer:]]").Select
With Selection.ListObject.QueryTable
.Connection = Array(Array("ODBC;DSN=Excel Files;DBQ=Z:\OEM Office\Trevor Weinrich\Projects\BOM Template 2.0\BOM template 2017-08-16 1.xlsm;DefaultDir=Z:\OEM Office\Trevor Weinrich\Projects\BOM Template 2.0;DriverId=1046;MaxBufferSize=2048;PageTimeout=5;"))
.CommandText = Array( _
"SELECT `BOM$`.`Customer:`" & Chr(13) & "" & Chr(10) & "FROM `BOM$` `BOM$`" & Chr(13) & "" & Chr(10) & "WHERE (`BOM$`.`Customer:` Is Not Null)" _
)
.Refresh BackgroundQuery:=False
End With
'
End Sub
And here is the VBA code for the database query:
Sub DatabaseQuery()
'
With Selection.ListObject.QueryTable
.Connection = _
"ODBC;DSN=OEM;Description=OEM;UID=trevor.weinrich;Trusted_Connection=Yes;APP=Microsoft Office 2016;WSID=DFP-OEM-0913-A;DATABASE=OEM"
.CommandText = Array( _
"SELECT DISTINCT p21_view_item_uom.item_id, p21_view_item_uom.unit_of_measure, p21_view_item_uom.purchasing_unit" & Chr(13) & "" & Chr(10) & "FROM OEM.dbo.p21_view_item_uom p21_view_item_uom" & Chr(13) & "" & Chr(10) & "WHERE (p21_view_item_uom.delete_flag=" _
, "'N')" & Chr(13) & "" & Chr(10) & "ORDER BY p21_view_item_uom.item_id")
.Refresh BackgroundQuery:=False
End With
'
End Sub
I want to join these together because there are about 140,000 line items in the database query, and I only care about the the instances where the "item_id" field from the database matches up with the "Customer:" field.
I just can't figure out how to join the two of them. I would greatly appreciate the help.
Here is the code where I am just trying to pull in a variable that gives me the error after 165 characters:
Sub Update_Item_Tables()
'
' UOM_Update Macro
'
Dim Items As String
Items = Sheets("UOM").Range("K1").Value
Sheets("UOM").Visible = True
Sheets("UOM").Select
Range("Table_Query_from_OEM[[#Headers],[item_id]]").Select
With Selection.ListObject.QueryTable
.Connection = _
"ODBC;DSN=OEM;Description=OEM;UID=trevor.weinrich;Trusted_Connection=Yes;APP=Microsoft Office 2016;WSID=DFP-OEM-0913-A;DATABASE=OEM"
.CommandText = Array( _
"SELECT DISTINCT p21_view_item_uom.item_id, p21_view_item_uom.unit_of_measure, p21_view_item_uom.purchasing_unit" & Chr(13) & "" & Chr(10) & _
"FROM OEM.dbo.p21_view_item_uom p21_view_item_uom" & Chr(13) & "" & Chr(10) & _
"WHERE (p21_view_item_uom.item_id In (" _
, _
"" & Items & ")) AND (p21_view_item_uom.delete_flag='N')" & Chr(13) & "" & Chr(10) & _
"ORDER BY p21_view_item_uom.purchasing_unit DESC" _
)
.Refresh BackgroundQuery:=False
End With
End Sub
Yikes... some of that code is... let's call it unique. But I won't ask questions, lets just deal with the problem you are asking about for now.
The goal is to check your long Items string so you only need one Sql command to grab your data. But the string needs to be in chunks less than 165 characters.
As I mentioned before, this is a sloppy way to do it, but if they have you locked out of your SQL database for development purposes, this approach will work:
You can split your Item string into multiple strings each less than 165 characters. Then you can use OR statements in your SQL to use the IN function with each Item string that has data.
First, in your VBA, you need to:
'Delcare your Variables
Dim SQLText As String
Dim Items2 As String
Dim Items3 As String
Dim boolItemFlag2 As Boolean
Dim boolItemFlag3 As Boolean
Dim i As Integer
' Initialize Variables
boolItemFlag2 = False
boolItemFlag3 = False
Then you can do your processing to build your 'Items' string. I'm assuming it's comma delimited something like this:
Items = "'123456','234567'"
After it's built you can:
' Get your Items list and check for length over 164
If Not IsNull(Len(Items)) Then
If Len(Items) > 164 Then
boolItemFlag2 = True
i = 0
' Find last comma delimiter before the cut off of 164
While (Mid(Items, 164 - i, 1) <> ",")
i = i + 1
Wend
' Set Items2 to everything after the last comma (before pos 164). Then Left Trim away possible spaces.
Items2 = LTrim(Mid(Items, 164 - i + 1, Len(Items) - 164 + i))
' Reset Items to everything up to that comma we found but not including it.
Items = Left(Items, 164 - i - 1)
' Your Item list is now split into 2 different string variables
End If
End If
If Not IsNull(Len(Items2)) Then
If Len(Items2) > 164 Then
boolItemFlag3 = True
' Use the same logic above to split Items2 into the Items3 variable.
' You may need to duplicate again for Items4 etc if your Item List is huge.
' If you'd need beyond Items5, I'd probably go back to the two query approach.
' But it's your choice.
End If
End If
Then, after you have your Item lists split into variables that are each small enough, you can build a unique SQL string (called SQLText) and insert OR statements to include items strings that have data:
' Build your SQL String Here (after you have determined how many item strings you have)
SQLText = "SELECT DISTINCT p21_view_item_uom.item_id, p21_view_item_uom.unit_of_measure, p21_view_item_uom.purchasing_unit" & Chr(13) & "" & Chr(10) & _
"FROM OEM.dbo.p21_view_item_uom p21_view_item_uom" & Chr(13) & "" & Chr(10) & _
"WHERE (p21_view_item_uom.item_id In (" _
& _ ' <-- I changed your comma into an & because I have no clue...
"" & Items & ")"
If boolItemFlag2 Then ' Add this OR statement if Items2 has data
SQLText = SQLText & " OR p21_view_item_uom.item_id In (" & Items2 & ")"
End If
If boolItemFlag3 Then ' Add this OR statement if Items3 has data
SQLText = SQLText & " OR p21_view_item_uom.item_id In (" & Items3 & ")"
End If
' Add more OR statements if you have Item lists beyond 3.
' Now tack on your remaining SQL code:
SQLText = SQLText & ") AND (p21_view_item_uom.delete_flag='N')" & Chr(13) & "" & Chr(10) & _
"ORDER BY p21_view_item_uom.purchasing_unit DESC"
Now the String SQLText will have your complete SQL code that you want to send to the server. You can execute this message box if you want to verify the string is correct:
MsgBox SQLText
You need to make one more modification. When you call the database, you need to put the variable SQLText into the commandtext array (in place of your old code):
' Now you can put your SQLText variable into your ODBC call:
With Selection.ListObject.QueryTable
.Connection = _
"ODBC;DSN=OEM;Description=OEM;UID=trevor.weinrich;Trusted_Connection=Yes;APP=Microsoft Office 2016;WSID=DFP-OEM-0913-A;DATABASE=OEM"
.CommandText = Array(SQLText)
.Refresh BackgroundQuery:=False
End With
Hope that helps :)
Run your Excel query.
Loop through the result set and build a list of OR conditions, such as item_id = 'ABC' Or item_id = 'PQR' and so on.
Instead of using an IN condition, use the (huge) list of OR conditions in a single large string.
Concatenate this list of OR conditions with rest of your query as Criterion for your database query.
While the length of an IN phrase may have a restriction, the length of the complete SQL statement may be higher.
Of course, if the no. of customers going to appear in your query is too large, this will have unexpected issues depending on how large it is.

Microsoft Access passing variables to VB from Form

I built a form with 2 combo boxes, one for Event and one for People. The two queries for the boxes include the Event_id and People_id but are not shown. The idea is to select the event from a drop down then add a person to attend the event. My problem is passing these two ID to the SQL update script.
Below is the VB; I receive a 424 error and calls the SQL as the area.
What's wrong?
Private Sub Command15_Click()
Dim dbs As DAO.Database, sql As String, rCount As Integer
Set dbs = CurrentDb
sql = "INSERT INTO Whos_Going (Event_ID, Who_is_invited) " _
& "VALUES(" & Event_id.Text & ", " & People_id.Text & ")"
dbs.Execute sql, dbFailOnError
rCount = dbs.RecordsAffected
If rCount > 0 Then
MsgBox "Person Added to Event"
'update listbox
conInfo.Requery
End If
End Sub
With VBA you need to construct the valid sql statement. All string literals must be enclosed into ', all dates must be enclosed into #. In addition to that, if your string variable contains an apostrophe it needs to be replaced with ''. The correct syntax will be:
sql = "INSERT INTO Whos_Going (Event_ID, Who_is_invited) " _
& "VALUES('" & Replace(Event_id.Text, "'", "''") & "', '" _
& Replace(People_id.Text, "'", "''") & "')"

MS Access: INSERT INTO statement returning a syntax error

I can't figure out the error. I already tried adding more parentheses but this didn't help. This code checks to see if there is already a query called "InsertFilmZip" and if there isn't one, it creates it with the given statement. For some reason, it's saying that there is a Run-time error 3139: Syntax error in PARAMETER clause but I can't find the error.
Private Sub Command8_Click()
Dim dbsCurrent As Database
Set dbsCurrent = CurrentDb
Dim query As QueryDef
Dim sql As String
Dim item_val As String
item_val = Me.Text314
For Each query In CurrentDb.QueryDefs
If query.Name = "InsertFilmZip" Then
Exit For
End If
Next query
If query Is Nothing Then
sql = "parameters " & "P1 Number" & _
"INSERT INTO [tbl_FilmZipInfo] " & _
"(qty_per_unit) " & _
" VALUES ([P1])" & _
"WHERE (((tbl_FilmZipInfo.qty_per_unit)='" & Me.Text314 & "'))"
Set query = CurrentDb.CreateQueryDef("InsertFilmZip", sql)
End If
query.Parameters("P1").Value = Me.Text317
query.Execute
End Sub
Your SQL doesn't make sense, so try this adjustment:
sql = "parameters P1 Long;" & _
"UPDATE [tbl_FilmZipInfo] " & _
"SET qty_per_unit = [P1] " & _
"WHERE qty_per_unit = " & Me.Text314 & ""