Store a sql select statement, ran from VBA, in a numeric variable - sql

I'm working on creating a dynamic pass-through query and in order to do so I first need to query my local db and get an ID.
This ID is what I will put into my pass-through query for my WHERE clause of the query.
My string:
getCorpID = "SELECT corpID " & _
"FROM dbo_corp " & _
"WHERE name = " & Forms.frmMain.Combo4.Value
I'm then trying to do something akin to:
CorpID (integer) = docmd.runsql (getCorpID)
I realize, however that docmd runsql doesn't work with select statements, or return a value even. What can I use to run my string
getCorpId
as sql and store the result (It will only be one result, every time.. one number) in my variable CorpID
Thank you.

Consider about using Recordset :
Dim dbs As DAO.Database
Dim rsSQL As DAO.Recordset
Dim getCorpID As String
Dim CorpID
Set dbs = CurrentDb
getCorpID = "SELECT corpID " & _
"FROM dbo_corp " & _
"WHERE name = " & Forms.frmMain.Combo4.Value
Set rsSQL = dbs.OpenRecordset(getCorpID , dbOpenSnapshot)
rsSQL.MoveFirst
CorpID = rsSQL.Fields("corpID")

Related

access vba concatenate single column query into a single line result

I have a new database to help produce documents for order processing.
I have a query set up with only one column of results (Product Codes) determined by the order selected on the main form.
I need to be able to use this information to name my file aka
(Customer) (Product1)+(Product2)+(Product....) (Location)
I have the code to generate the line (Customer) (Product1) (Location) and am trying to get either a concatenate function or a loop function or something to get all the products to line up with a "+" in between each "line".
I have a query (Query1) set up to give me the exact data I need...
SELECT tblREF_Chemical.Abbr
FROM qry_AX_LineItems_DISTINCT INNER JOIN tblREF_Chemical ON
qry_AX_LineItems_DISTINCT.ItemId = tblREF_Chemical.[Item Number]
GROUP BY tblREF_Chemical.Abbr, qry_AX_LineItems_DISTINCT.SALESID,
tblREF_Chemical.[Proper Shipping Name]
HAVING (((qry_AX_LineItems_DISTINCT.SALESID)=[Forms]![frm_SalesOrderEntry]!
[Combo617]) AND ((tblREF_Chemical.[Proper Shipping Name]) Is Not Null));
I have a button set up on my main form to test the data output and then I intend to add the code to my code for DoCmd.Output file name.
So far the only code that has worked is...
Private Sub Command1492_Click()
Dim i As Integer
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim SQL As String
Set db = CurrentDb
SL = [Forms]![frm_SalesOrderEntry]![Combo617]
SQL = "SELECT * FROM ALL_SalesOrderItemsLineDates WHERE
ALL_SalesOrderItemsLineDates.SALESID = '" & SL & "';"
Set rst = db.OpenRecordset(SQL)
For i = 0 To DCount("*", "ALL_SalesOrderItemsLineDates",
"ALL_SalesOrderItemsLineDates.SALESID = '" & [Forms]![frm_SalesOrderEntry]!
[Combo617] & "'") - 1
Debug.Print DLookup("[Abbr]", "[tblREF_Chemical]", "[Item Number]= '" &
rst.Fields("ItemID") & "'")
rst.MoveNext
Next i
rst.Close
End Sub
I can't seem to add additional where statements within this code or use my actual query or the system presents errors at the db.OpenRecordset line of code (Errors 3061 and 3078).
Even ignoring those problems the output is multi-line and I need it to be used in a single string of text for the document name.
UPDATE1:
I am working with the code to use my query directly...
Dim i As Integer
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim SQL As String
Set db = CurrentDb
SL = [Forms]![frm_SalesOrderEntry]![Combo617]
SQL = "SELECT tblREF_Chemical.Abbr "
SQL = SQL & "FROM qry_AX_LineItems_DISTINCT INNER JOIN tblREF_Chemical ON qry_AX_LineItems_DISTINCT.ItemId = tblREF_Chemical.[Item Number] "
SQL = SQL & "GROUP BY tblREF_Chemical.Abbr, qry_AX_LineItems_DISTINCT.SALESID, tblREF_Chemical.[Proper Shipping Name] "
SQL = SQL & "HAVING ((qry_AX_LineItems_DISTINCT.SALESID)='" & SL & "'"
SQL = SQL & "AND ((tblREF_Chemical.[Proper Shipping Name]) Is Not Null)); "
Set rst = db.OpenRecordset(SQL)
Dim s As String
Do While rst(0) Is Not Null
s = s & "+" & rst(0)
rst.MoveNext
Loop
rst.Close
Debug.Print s
Unfortunately I'm now getting a run-time error 3061 - Too few parameters. Expected 1.
I have double checked my spellings and ran the query just to be sure and no matter how many results the query is getting (functioning as expected) I am still getting this error.
UPDATE2:
Through more research I learned that queries can have, for lack of better words, invisible coding. I am updating my code to remove the inner query from my query to simplify the amount of "research" my VBA has to do.
Private Sub Command1492_Click()
Dim i As Integer
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim SQL As String
Set db = CurrentDb
SL = [Forms]![frm_SalesOrderEntry]![Combo617]
SQL = "SELECT tblREF_Chemical.Abbr "
SQL = SQL & "FROM ALL_SalesOrderItemsLineDates INNER JOIN tblREF_Chemical ON ALL_SalesOrderItemsLineDates.ItemId = tblREF_Chemical.[Item Number] "
SQL = SQL & "GROUP BY tblREF_Chemical.Abbr, ALL_SalesOrderItemsLineDates.SALESID, tblREF_Chemical.[Proper Shipping Name]"
SQL = SQL & "HAVING ((ALL_SalesOrderItemsLineDates.SALESID)='" & SL & "'"
SQL = SQL & "AND ((tblREF_Chemical.[Proper Shipping Name]) Is Not Null)); "
Set rst = db.OpenRecordset(SQL)
Dim s As String
Do While rst(0) Is Not Null 'Debug error here!
s = s & "+" & rst(0)
rst.MoveNext
Loop
rst.Close
Debug.Print s
End Sub
Unfortunately I'm still getting a run-time error, but now it is 424 Object required and the debug takes me to the "Do While" line.
I think this is a step forward, but still a little stuck.
Update3:
Since the debug was taking me to the "Do While" line I returned to my functioning code and replaced the loop function with an integer based code.
Thank you #Harassed Dad! Your code was a giant help! Using your idea for a string rather than going straight to a debug.print was genius.
The below replaces my code starting where I was having issues.
Dim s As String
For i = 0 To DCount("*", "ALL_SalesOrderItemsLineDates", "ALL_SalesOrderItemsLineDates.SALESID = '" & SL & "'") - 1
s = s & "+" & rst.Fields("Abbr")
rst.MoveNext
Next i
rst.Close
Debug.Print s
My results are displaying with only one hiccup.
+CHA+DEEA+EEP+MEC+PERC+PM+PROP
There is an extra "+" at the beginning, but I'm sure I can find the solution to this tiny problem.
I hope these notes can help someone in the future. Thank you all for your help!
Private Sub Command1492_Click()
Dim i As Integer
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim SQL As String
Set db = CurrentDb
SL = [Forms]![frm_SalesOrderEntry]![Combo617]
SQL = "SELECT tblREF_Chemical.Abbr "
SQL = SQL & "FROM qry_AX_LineItems_DISTINCT INNER JOIN tblREF_Chemical ON "
SQL = SQL & "qry_AX_LineItems_DISTINCT.ItemId = tblREF_Chemical.[Item Number] "
SQL = SQL & "GROUP BY tblREF_Chemical.Abbr, qry_AX_LineItems_DISTINCT.SALESID, "
SQL = SQL & "tblREF_Chemical.[Proper Shipping Name] "
SQL = SQL & "HAVING (((qry_AX_LineItems_DISTINCT.SALESID)='" & SL & "'" 'edit here
SQL = SQL & "AND ((tblREF_Chemical.[Proper Shipping Name]) Is Not Null)); "
Set rst = db.OpenRecordset(SQL)
Dim s as string
Do While rst(0) is not null
s = s & "+" & rst(0)
rst.MoveNext
Loop
rst.Close
Debug.print s
End Sub
Your main issue is a missing space before the AND in HAVING clause.
For this very reason of readability and maintainability, consider using QueryDefs for parameterized queries (an industry best practice) to run your saved query in VBA for several reasons:
You avoid the need to concatenate or enclose quotes or escape literals by effectively divorcing SQL code from VBA (application layer) code.
MS Access will not allow you to save a query with syntax issues but VBA string queries can have such issues found at runtime.
MS Access's engine compiles and caches saved queries to best execution plan which especially helps for aggregate queries with joins. This is why saved queries are usually more efficient than VBA string queries run on the fly.
SQL (save below as a saved query)
Query now uses table aliases and HAVING conditions are moved to WHERE since no aggregate is being used.
PARAMETERS idparam LONG;
SELECT t.Abbr
FROM qry_AX_LineItems_DISTINCT q
INNER JOIN tblREF_Chemical t ON q.ItemId = t.[Item Number]
WHERE (((q.SALESID) = [idparam])
AND ((t.[Proper Shipping Name]) Is Not Null))
GROUP BY t.Abbr, q.SALESID, t.[Proper Shipping Name];
VBA
Dim db As DAO.Database, qdef AS DAO.QueryDef, rst As DAO.Recordset
Dim SQL As String, s As String
Set db = CurrentDb
' INITIALIZE SAVED QUERY
Set qdef = db.QueryDefs("mySavedQuery")
' BIND PARAMETER
qdef![idparam] = [Forms]![frm_SalesOrderEntry]![Combo617]
' OPEN RECORDSET
Set rst = qdef.OpenRecordset()
Do While rst(0) Is Not Null
s = s & "+" & rst(0)
rst.MoveNext
Loop
rst.Close
Debug.Print s
Set rst = Nothing: Set qdef = Nothing: Set db = Nothing

Access VBA: Cannot combine variable and string in SQL query

I have a list of users (as string variable) and want to use it as the criteria (one user at a time) for my SQL to pick the first item's code. So I put a SQL query as a string to run it later in the code.
I've tried this:
strSQL = "SELECT TOP 1 Item.Code FROM Item WHERE Item.User = '"
strSQL = strSQL & strUserName & "' ORDER BY ID DESC"
If the strUserName = "A-user" for example, I only get this SQL string, according to "Quick Watch...":
SELECT TOP 1 Item.Code FROM Item WHERE Item.User = 'A-user
The part with "' ORDER BY ID DESC" isn't included in the SQL string at all!
And for running the SQL query by using "Set rst = CurrentDb.OpenRecordset(strSQL)", I get this error:
Run-time error '3075':
Syntax error (missing operator) in query expression 'Item.User = "A-user"
How can I fix that?
I don't see how your code triggers that 3075 error. However I would use a parameter query instead. That way you can avoid problems with quoted values in your SQL statement.
Dim qdf As DAO.QueryDef
Dim rs As DAO.Recordset
Dim strSelect As String
Dim strUserName As String
strUserName = "A-user"
strSelect = "SELECT TOP 1 i.Code FROM [Item] AS i WHERE i.User = [which_user] ORDER BY i.ID DESC"
Set qdf = CurrentDb.CreateQueryDef(vbNullString, strSelect)
qdf.Parameters("which_user").Value = strUserName
Set rs = qdf.OpenRecordset
Access sometimes complains about the use of single-quotes. And also add a semi-colon to the end of the statement. Try changing the code to this (where double-quotes are escaped with an extra double-quote:
strSQL = "SELECT TOP 1 Item.Code FROM Item WHERE Item.User = "
strSQL = strSQL & """" & strUserName & """" & " ORDER BY ID DESC;"

Run Time error 3061 Too Few parameters. Expected 6. Unable to update table from listbox

All,
I am running the below SQL and I keep getting error 3061. Thank you all for the wonderful help! I've been trying to teach myself and I am 10 days in and oh my I am in for a treat!
Private Sub b_Update_Click()
Dim db As DAO.Database
Set db = CurrentDb
strSQL = "UPDATE Main" _
& " SET t_Name = Me.txt_Name, t_Date = Me.txt_Date, t_ContactID = Me.txt_Contact, t_Score = Me.txt_Score, t_Comments = Me.txt_Comments" _
& " WHERE RecordID = Me.lbl_RecordID.Caption"
CurrentDb.Execute strSQL
I am not sure but, you can try somethink like that
if you knom the new value to insert in the database try with a syntax like this one
UPDATE table
SET Users.name = 'NewName',
Users.address = 'MyNewAdresse'
WHERE Users.id_User = 10;
Now, if you want to use a form (php)
You have to use this
if(isset($_REQUEST["id_user" ])) {$id_user = $_REQUEST["id_user" ];}
else {$id_user = "" ;}
if(isset($_REQUEST["name" ])) {$name= $_REQUEST["name" ];}
else {$name = "" ;}
if(isset($_REQUEST["address" ])) {$address= $_REQUEST["adress" ];}
else {$adress= "" ;}
if you use mysql
UPDATE table
SET Users.name = '$name',
Users.address = '$adress'
WHERE Users.id_User = 10;
i don't know VBA but I will try to help you
Going on from my comment, you first need to declare strSQL as a string variable.
Where your error expects 6 values and access doesn't know what they are. This is because form objects need to be outside the quotations of the SQL query, otherwise (as in this case) it will think they are variables and obviously undefined. The 6 expected are the 5 form fields plus 'strSQL'.
Private Sub b_Update_Click()
Dim db As DAO.Database
dim strSQL as string
Set db = CurrentDb
strSQL = "UPDATE Main" & _
" SET t_Name = '" & Me.txt_Name & "'," & _
" t_Date =#" & Me.txt_Date & "#," & _
" t_ContactID =" & Me.txt_Contact & "," & _
" t_Score =" & Me.txt_Score & "," & _
" t_Comments = '" & Me.txt_Comments & "'," & _
" WHERE RecordID = '" & Me.lbl_RecordID.Caption & "';"
CurrentDb.Execute strSQL
end sub
Note how I have used double quotes to put the form fields outside of the query string so access knows they aren't variables.
If your field is a string, it needs encapsulating in single quotes like so 'string'. If you have a date field it needs encapsulating in number signs like so #date# and numbers/integers don't need encapsulating.
Look at the code I have done and you can see I have used these single quotes and number signs to encapsulate certain fields. I guessed based on the names of the fields like ID's as numbers. I may have got some wrong so alter where applicable... Or comment and I will correct my answer.

Using a VBA variable in SELECT Sql statement

Is their a way to use a declared VBA variable in a SELECT Sql statement as follows (I have a table called myTable and i want to set the referenced field by passing the declared string myVar) :
e.g passVar("English")
NB: Am using Microsoft Access
Private Function passVar(myVar as string)
Dim db As Database
Dim qdf As DAO.QueryDef
Dim stmnt As String
Set db = CurrentDb()
Set qdf = db.QueryDefs("SelectSubjectQuery")
stmnt = "SELECT [myTable].[myVar] = " &Chr$(34) & myVar & Chr$(34) & _
//other SQL statements go here
qdf.SQL = stmnt
End Function
Each time i run the query a dialog box appears asking for the value of mytable.myvar instead of passing myvar i.e Eglish as the referenced field on myTable.
Yes, build the SQL statement as a string like this:
stmnt = "SELECT " & [myTable] & "." & [myVar] & " = " &Chr$(34) & myVar & Chr$(34) & _
VBA should then fill in the names for MyTable and MyVar when the code is run and the string is built.
stmnt = "SELECT [myTable]." & myVar & _
Got it to working by writing as above (no need for the equals sign as the string is passed through the function). Thanks for the insight #rcfmonarch

Use a ComboBox Value as part of an SQL Query? (MS Access 2010-2013)

I have a Database that we use to create Bills of Materials from Tags in AutoCAD. Because of the nature of this, I need to create 3 separate queries. One for our "Steel", one for our
"Non-Steel", and one for our "Uncut Tubes".
The SQL for the Queries is as follows:
Steel:
SELECT DISTINCTROW Sum([CUT-LENGTH-WEIGHT]) AS [SumOfCUT-LENGTH-WEIGHT], Sum([CUT-SHEET-WEIGHT]) AS [SumOfCUT-SHEET-WEIGHT], Sum([TOTAL-SHEETING-WEIGHT]) AS [SumOfTOTAL-SHEETING-WEIGHT], Sum([TOTAL-ITEM-WEIGHT]) AS [SumOfTOTAL-ITEM-WEIGHT]
FROM [13-1302 Cut-Lengths];
Non-Steel:
SELECT tbl2013BOM.fJobID, Sum(tbl2013BOM.fWeight) AS SumOffWeight
FROM tbl2013BOM
GROUP BY tbl2013BOM.fJobID
HAVING (((tbl2013BOM.fJobID)=23));
Uncut Tubes:
SELECT DISTINCT [13-1302 Cut-Lengths].[TOTAL-LENGTH-WEIGHT], [13-1302 Cut-Lengths].MATERIAL, [13-1302 Cut-Lengths].ORDER
FROM [13-1302 Cut-Lengths]
ORDER BY [13-1302 Cut-Lengths].ORDER;
I have a ComboBox that chooses the Job Number (For Main and Uncut Tubes, e.g. 13-1302) and a Textbox that displays the JobID (For Non-Steel).
Is there a way that I can set up the SQL shown above to look at the ComboBox and TextBox Values, instead of me having to change them by hand?
EDIT
I figured it all out now. (Thank you Elias)
Basically, I cannot use a Field on a table as a RecordSource in SQL, in other words, Combo26 cannot be the Table in an SQL Query. HOWEVER, what CAN be done is to use VBA to inject that value into an SQL Definition, then use that definition as a Recordsource.
I will place the code for my Button below so anyone can use it and reference it:
Private Sub Command27_Click()
Dim dbs As Database
Dim rstSQL As DAO.Recordset
Dim strSQL As String
Dim strSQL2 As String
Dim strSQL3 As String
Dim Field As String
Set dbs = CurrentDb
Field = [Forms]![frmBOM_Combined]![Text26].[Value]
strSQL = "SELECT DISTINCTROW Sum([CUT-LENGTH-WEIGHT]) AS [SumOfCUT-LENGTH-WEIGHT], Sum([TOTAL-SHEETING-WEIGHT]) AS [SumOfTOTAL-SHEETING-WEIGHT], Sum([TOTAL-ITEM-WEIGHT]) AS [SumOfTOTAL-ITEM-WEIGHT] FROM " & "[" & [Forms]![frmBOM_Combined]![Text26].[Value] & "]" & ";"
strSQL2 = "SELECT tbl2013BOM.fJobID, Sum(tbl2013BOM.fWeight) AS SumOffWeight FROM tbl2013BOM GROUP BY tbl2013BOM.fJobID HAVING (((tbl2013BOM.fJobID)= " & [Forms]![frmBOM_Combined]![Combo25].[Value] & "));"
strSQL3 = "SELECT DISTINCT [TOTAL-LENGTH-WEIGHT], [MATERIAL], [ORDER] FROM " & "[" & [Forms]![frmBOM_Combined]![Text26].[Value] & "]" & " ORDER BY [ORDER];"
Debug.Print strSQL
Debug.Print strSQL2
Debug.Print strSQL3
DoCmd.OpenForm ("frmEstWeight")
Forms!frmEstWeight.RecordSource = strSQL
Forms!frmEstWeight.frmTestBomWeight.Form.RecordSource = strSQL2
Forms!frmEstWeight.frmTotalLengthWeight.Form.RecordSource = strSQL3
End Sub
This is working exactly as it should with no errors or anything.
This is within a form correct?
If so, replace the manual values you put in with
REST OF THE QUERY HERE " & Me!Controlname.value & " REST OF THE QUERY HERE
and if you are using something with a control source then just reset the control source value.
me!ControlWithResult.control source = "SELECT tbl2013BOM.fJobID, Sum (tbl2013BOM.fWeight) AS SumOffWeight
FROM tbl2013BOM
GROUP BY tbl2013BOM.fJobID
HAVING (((tbl2013BOM.fJobID)=" & me!controlname.value & "));"
For Non-Steel try:
On the VBA for the popup form
me!Combo25.rowsource = "SELECT tbl2013BOM.fJobID, Sum(tbl2013BOM.fWeight) AS SumOffWeight
FROM tbl2013BOM
GROUP BY tbl2013BOM.fJobID
HAVING (((tbl2013BOM.fJobID)=" & forms!MAINFORMNAME! &"));