How to get values from select statement into a variable? - sql

I want to store the result from select statement into a variable that I can use to show in a message.
Dim rst As DAO.Recordset
Dim result As String
Dim strSQL As String
strSQL = "SELECT Key_Old FROM Pivot_Old where Pivot_Old.Count = " & 1 & ""
Set rst = CurrentDb.OpenRecordset(strSQL)
result = rst!result
rst.Close
MsgBox ("String is " & result)
I want the result from the select statement to display in a msgbox.

result = rst!result
This notation is magical shorthand for this:
result = rst.Fields("result").Value
And your query doesn't have any result field. So either you change the query to alias Key_Old to result:
strSQL = "SELECT Key_Old As result FROM Pivot_Old where Pivot_Old.Count = " & 1 & ""
...
result = rst.Fields("result").Value
Or, you change how you're referring to that field:
strSQL = "SELECT Key_Old FROM Pivot_Old where Pivot_Old.Count = " & 1 & ""
...
result = rst.Fields("Key_Old").Value
Rule of thumb, prefer explicit code over magical shorthand notation =)

You could also do:
strSQL = "SELECT Key_Old FROM Pivot_Old where Pivot_Old.Count = " & 1 & ""
Set rst = CurrentDb.OpenRecordset(strSQL)
result = rst(0).Value
rst.Close
MsgBox ("String is " & result)
or keep it really simple:
result = Nz(DLookup("Key_Old", "Pivot_Old", "[Count] = " & 1 & ""))
MsgBox "String is " & result

Related

VBA RecordSet function takes too much time to update record using RecordCount

I have one table and one query. Both have the same data field but table COLUMN names are equal to query's ROW name. I update table from query's row data using the following code successfully but it takes too much time to update as there are more than 50 columns name in the table for each employee-
Set rst1 = CurrentDb.OpenRecordset("SELECT * FROM tblPayRollDataTEMP")
Set rst2 = CurrentDb.OpenRecordset("SELECT * FROM qryEmpVerifySalary ")
Do Until rst1.EOF
rst2.MoveFirst
Do Until rst2.EOF
For l = 0 To rst1.Fields.count - 1
If rst1!EmpID = rst2!EmpID And rst1.Fields(l).Name = rst2!Head And rst1!PayBillID = TempVars!BillID Then
With rst1
rst1.Edit
rst1.Fields(l).Value = rst2!Amount
rst1!totDeductions = DSum("Amount", "qryEmpVerifySalary", "[PayHeadType] = 'Deductions' AND [EmpID] = " & rst2!EmpID & "") + DLookup("NPS", "qryEmpPayEarning", "[EmpID] = " & rst2!EmpID & "")
rst1!totRecoveries = DSum("Amount", "qryEmpVerifySalary", "[PayHeadType] = 'Recoveries' AND [EmpID] = " & rst2!EmpID & "")
rst1!NetPayable = rst1!totEarnings - (Nz(rst1!totDeductions, 0) + Nz(rst1!totRecoveries, 0))
rst1.Update
End With
End If
Next
rst2.MoveNext
Loop
rst1.MoveNext
Loop
Set rst1 = Nothing
Set rst2 = Nothing
How to improve the performance of the code?
You should use a query to update your records. This would be the fastest solution. Normally one would match the EmpID and drag and drop the fields into the update query or use an expression. If you have to group before or other complex stuff split it in more querys (two or three). It doesnt matter thou, because in the end you just execute one update query.
For your code, you can replace the domainaggregate functions. DLookup(), DSum(), etc... these are worst for performance. A simple select statement runs way faster than DLookup(). Here are a few replacements:
Function DCount(Expression As String, Domain As String, Optional Criteria) As Variant
Dim strSQL As String
strSQL = "SELECT COUNT(" & Expression & ") FROM " & Domain
'Other Replacements:
'DLookup: strSQL = "SELECT " & Expression & " FROM " & Domain
'DMax: strSQL = "SELECT MAX(" & Expression & ") FROM " & Domain
'DMin: strSQL = "SELECT SUM(" & Expression & ") FROM " & Domain
'DFirst: strSQL = "SELECT FIRST(" & Expression & ") FROM " & Domain
'DLast: strSQL = "SELECT LAST(" & Expression & ") FROM " & Domain
'DSum: strSQL = "SELECT SUM(" & Expression & ") FROM " & Domain
'DAvg: strSQL = "SELECT AVG(" & Expression & ") FROM " & Domain
If Not IsMissing(Criteria) Then strSQL = strSQL & " WHERE " & Criteria
DCount = DBEngine(0)(0).OpenRecordset(strSQL, dbOpenForwardOnly)(0)
End Function

Difficulty using SELECT statement in VBA

I'm trying to set command buttons to enter data into a table. If the record already exists I want the button to update it, and if it does not the button needs to create it. Here's a sample of what the table looks like
ID scenarioID reductionID Impact Variable Variable Impact
1 1 1 Safety 4
2 1 1 Environmental 2
3 1 1 Financial 1
In order to accurately locate records, it needs to search for the specific impact variable paired with the scenarioID. I'm trying to use a select statement, but DoCmd.RunSQL doesn't work for select statements, and I'm not sure how else to do it.
Here's the code. I left DoCmd.SQL in front of the select statement for lack of anything else to place there for now.
Private Sub Var1R1_Click() 'Stores appropriate values in tImpact upon click
'Declaring database and setting recordset
Dim db As Database
Dim rs As Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("tImpact")
'Declaring Variable as Scenario Choice combobox value
Dim Sc As Integer
Sc = Schoice.Value
'Stores impact variable
Dim impvar1 As String
'Desired impact variable for column 1
impvar1 = DLookup("impactVariable", "tImpactVars", "ID = 1")
DoCmd.RunSQL "SELECT * FROM tImpact WHERE [Impact Variable] = " & impvar1 & " AND scenarioID = " & Sc
If rs.EOF Then
DoCmd.RunSQL "INSERT INTO tImpact(scenarioID, [Impact Variable], [Variable Impact])" & "VALUES (" & Sc & ", " & impvar1 & ", 1)"
MsgBox "Record Added", vbOKOnly
Else
db.Execute "UPDATE tImpact SET [Variable Impact] = 1 WHERE [Impact Variable] = " & impvar1 & " AND scenarioID = " & Sc
MsgBox "Record Updated", vbOKOnly
End If
End Sub
If anyone can tell me how to get that SELECT statement to run, or another way of doing this, that would be great.
Any help is greatly appreciated!
You can use a recordset. In this case a recordset is better, since you only execute the SQL one time, if it returns a record, you "edit" and if not then you "add" with the SAME reocrdset. This approach is FAR less code, and the values you set into the reocrdset does not require messy quotes or delimiters etc.
eg:
scenaridID = 1 ' set this to any number
impvar1 = "Safety" ' set this to any string
updateTo = "Financial"
strSQL = "select * from tImpact where [Impact Variable] = '" & impvar1 & "'" & _
" AND scenaridID = " & scenaridID
Set rst = CurrentDb.OpenRecordset(strSQL)
With rst
If .RecordCount = 0 Then
' add the reocrd
.AddNew
Else
.Edit
End If
!scenaridID = scenarid
![Impact Variable] = impvar1
![Variable Impact] = 1
.Update
End With
rst.Close
So you can use the same code for the update and the edit. It just a question if you add or edit.
Use OpenRecordset and retrieve the ID for the record if it exists.
Private Sub Command0_Click()
Dim aLookup(1 To 3) As String
Dim aAction(1 To 3) As String
Dim rs As Recordset
Dim db As Database
'Replace these two constants with where you get the information on your form
Const sIMPVAR As String = "Financial"
Const lSCENID As Long = 1
'Build the SQL to find the ID if it exists
aLookup(1) = "SELECT ID FROM tImpact"
aLookup(2) = "WHERE ScenarioID = " & lSCENID
aLookup(3) = "AND ImpactVariable = """ & sIMPVAR & """"
'Run the sql to find the id
Set db = CurrentDb
Set rs = db.OpenRecordset(Join(aLookup, Space(1)))
If rs.BOF And rs.EOF Then 'it doesn't exist, so build the insert statement
aAction(1) = "INSERT INTO tImpact"
aAction(2) = "(ScenarioID, ImpactVariable, VariableImpact)"
aAction(3) = "VALUES (" & lSCENID & ", '" & sIMPVAR & "', 1)"
Else 'it does exist, so build the update statement
aAction(1) = "UPDATE tImpact"
aAction(2) = "SET VariableImpact = 1"
aAction(3) = "WHERE ID = " & rs.Fields(0).Value
End If
'Run the action query
db.Execute Join(aAction, Space(1))
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub

VBA Teradata SQL

For some reason it's returning run-time error 3021 , SQL string is working ok when trying in Terada SQLAssistant.
Can someone give me hint what I'm doing wrong ?
Value in cell equal to John Doe
Dim ConcatSQL As String
ConcatSQL = Sheets("LogIn").Cells(8, 3).Value
QueryA = "select * from database.table WHERE Name = " & ConcatSQL & "
cmdSQLData.CommandText = QueryA
cmdSQLData.CommandType = adCmdText
cmdSQLData.CommandTimeout = 0
MsgBox (QueryA)
Set rs = cmdSQLData.Execute()
Row = 1
rs.MoveFirst ' it's falling here
Do While (rs.EOF = False And rs.BOF = False)
One possible reason for the error is that field Name is a reserved word in Teradata, so you should use "Name" (using double quotes) instead
QueryA = "select * from database.table WHERE " & Chr(34) & "Name" & Chr(34) & " = " & ConcatSQL
Could you try this:
On Error Resume Next
Set rs = cmdSQLData.Execute()
If Err.Number<>0 Then
MsgBox(Err.Description)
End If
And post the output? Also can you post the output of QueryA.

Field name confusion

rs2.FindFirst "[aniin] ='" & strTemp & "'"
aniin being an alias from the SQL within the function.
also tried ...
rs2.FindFirst (niin = newdata)
is my attempt to isolate the field name niin from the record value in the form from the one in the strSQL2. All my attempts have failed. I am trying to make sure that what the user typed in does match the list from the SQL string.
Private Function IsPartOfAEL(newdata) As Boolean
On Error GoTo ErrTrap
Dim db2 As DAO.Database
Dim rs2 As DAO.Recordset
Dim strTemp As String
strSQL2 = "SELECT tbl_ael_parts.master_ael_id, tbl_master_niin.niin as aniin " & vbCrLf & _
"FROM tbl_master_niin INNER JOIN tbl_ael_parts ON tbl_master_niin.master_niin_id = tbl_ael_parts.master_niin_id " & vbCrLf & _
"WHERE (((tbl_ael_parts.master_ael_id)= " & Forms!frm_qry_niin_local!master_ael_id & "));"
Set db2 = CurrentDb
Set rs2 = db2.OpenRecordset(strSQL2)
strTemp = newdata
If rs2.RecordCount <> 0 Then
rs2.FindFirst "[aniin] ='" & strTemp & "'"
If rs2.NoMatch Then
IsPartOfAEL = False
Else
IsPartOfAEL = True
End If
Else
MsgBox "Query Returned Zero Records", vbCritical
Exit Function
End If
rs.Close
Set rs2 = Nothing
Set db2 = Nothing
ExitHere:
Exit Function
ErrTrap:
MsgBox Err.description
Resume ExitHere
End Function
First: You should never include a constant like vbCrLf when building a query string. The query parser doesn't care if there's a linefeed, and in fact this can sometimes cause issues.
Your code seems to do nothing more that verify whether the value in newdata exists in the tbl_ael_parts and is associated with the value master_ael_id value currently showing on frm_qry_niin_local. If so, then just use DCount, or use this for your query:
strSQL2 = "SELECT tbl_ael_parts.master_ael_id INNER JOIN tbl_ael_parts ON
tbl_master_niin.master_niin_id = tbl_ael_parts.master_niin_id WHERE (((tbl_ael_parts.master_ael_id)=
" & Forms!frm_qry_niin_local!master_ael_id & ") AND niin=" & newdata & ");"
Dim rst As DAO.Recordset
Set rst = currentdb.OPenrecordset(strsql2)
If (rst.EOF and rst.BOF) Then
' no records returned
Else
' records found
End If
If niin is a Text field:
strSQL2 = "SELECT tbl_ael_parts.master_ael_id INNER JOIN tbl_ael_parts ON
tbl_master_niin.master_niin_id = tbl_ael_parts.master_niin_id WHERE (((tbl_ael_parts.master_ael_id)=
" & Forms!frm_qry_niin_local!master_ael_id & ") AND (niin='" & newdata & "'));"
If both niin and master_ael_id are Text fields:
strSQL2 = "SELECT tbl_ael_parts.master_ael_id INNER JOIN tbl_ael_parts ON
tbl_master_niin.master_niin_id = tbl_ael_parts.master_niin_id WHERE (((tbl_ael_parts.master_ael_id)=
'" & Forms!frm_qry_niin_local!master_ael_id & "') AND (niin='" & newdata & "'));"

MS Access VBA IF()

I am trying to write an if loop for MS Access VBA
In php I would write:
if($query=="0"){
run query 1
} else {
run query 2
}
I do need to call the query in and refer to multiple tables (ie. 'query 1' will extract data from a combo box, whereas, 'query 2' will run another query)
------------------------------------EDIT: 02/06/14 13:34 AEST ----------------------------
Dim variabl1 As String
variabl1 = Me.cmbItemDetails.Column(1)
Dim variabl2 As String
variabl2 = "" & Forms!frmRaiseOrder!cmbDebtorCode & ""
'you can use variable as a parameter in SQL, but only if you hardcode your SQL statement as a string... See directly below
Dim SQL As String
SQL_count = "SELECT COUNT(CustItemPrice) FROM tblSpecialPricing WHERE ItemListID = '" & variabl1 & "' AND CustListID = '" & variabl2 & "' "
SQL_select = "SELECT CustItemPrice FROM tblSpecialPricing WHERE ItemListID = '" & variabl1 & "' AND CustListID = '" & variabl2 & "' "
Dim rs As Recordset
Set rs = CurrentDb.OpenRecordset(SQL_count)
If rs.RecordCount = "0" Then
Me.txtStreetPrice.Value = Me.cmbItemDetails.Column(3)
Else
DoCmd.OpenQuery "qrySelectCustomerName"
End If
Thanks to #MurDeR for the assistance for the above statements
----------------------------------------------- Update as of 9th July -----------------------------------
Hi everyone;
If you are trying to create an IF() statement in ACCESS VBA, use the following syntax...
Private Sub cmbItemDetails_Change()
Me.txtItemDescription.Value = Me.cmbItemDetails.Column(2)
Me.txtStreetPrice.Value = Me.cmbItemDetails.Column(3)
Me.txtItemName.Value = Me.cmbItemDetails.Column(1)
Dim variabl1 As String
variabl1 = Me.cmbItemDetails.Column(0)
Dim variabl2 As String
variabl2 = "" & Forms!frmRaiseOrder!cmbDebtorCode & ""
'you can use variable as a parameter in SQL, but only if you hardcode your SQL statement as a string... See directly below
Dim SQL As String
SQL_count = "SELECT COUNT(CustItemPrice) FROM tblSpecialPricing WHERE ItemListID = '" & variabl1 & "' AND CustListID = '" & variabl2 & "' "
SQL_select = "SELECT CustItemPrice FROM tblSpecialPricing WHERE ItemListID = '" & variabl1 & "' AND CustListID = '" & variabl2 & "' "
Dim rs As Recordset
Set rs = Nothing
Set rs = CurrentDb.OpenRecordset(SQL_count)
RecordCount = rs.Fields(0)
If RecordCount = "1" Then
'SPECIAL PRICE EXISTS - this code will run only if the count query is greater than zero
MsgBox "Special Price Exists", vbOkay, "Alert"
'
'
Me.txtUnitPrice.Value = Me.cmbItemDetails.Column(3)
'Me.txtUnitPrice.Value = "" & Forms!frmRaiseOrder!subformCreateOrder!frmSelectCustomPriceinsubform!CustItemPrice & ""
'Me.txtUnitPrice.Value = Me.subfrmItemPrice.CustItemPrice.Value
Else
'NO SPECIAL PRICE - this code will run only if the coutn query is zero
'MsgBox "No Special Pricing for this item", vbOkay, "Alert"
'
'
Me.txtUnitPrice.Value = Me.cmbItemDetails.Column(3)
End If
End Sub
I would really like to thank and credit #MurDeR for their help and also if you have any questions, PM me or post here
You can work with a recordset in VBA.
See this bit of code for a start.
Dim variabl As String
variabl = Me.ComboBox1.Value
'you can use variabl as a parameter in SQL, but only if you hardcode your SQL statement as a string... See directly below
Dim SQL As String
SQL = "SELECT * FROM TableA WHERE YourColumnName = '" & variabl & "'"
Dim db As DAO.Database
db = CurrentDb
Dim rs As DAO.Recordset
Set rs = db.OpenRecordset("SQL Statement or Query Name")
If rs.RecordCount = 0 Then
DoCmd.OpenQuery "Query1"
Else
DoCmd.OpenQuery "Query2"
End If
rs.Close
Set rs = Nothing
Let me know if you have any other questions. Also note, you need to make sure you're entering proper query names. I know VBA has pathetic intellisense, so this can be tricky when entering query names as strings.