How to sum column values of a select query - vba

I am trying to display the "total of all values" in the column NetPrice to a textbox which is in the form footer if a user chooses items in the two combo boxes. This should be true for only the displayed records.
I don't know how to go about this and hope someone has done this before. I would really appreciate some help.
Private Sub comboPeriod_AfterUpdate()
Dim strSQL As String
If Me.comboPeriod.Value = "Q1" And Len(Me.comboPostCode.Value & vbNullString) <> 0 Then
strSQL = "SELECT * FROM qrySpending WHERE (Month(orderDate) = 4 OR Month(orderDate) = 5 OR
Month(orderDate) = 6) AND (PostCode = '" & Me.comboPostCode.Value & "') ORDER BY Description ASC"
Me.frmDatasheet.Form.RecordSource = strSQL
Me.frmMain.Form.Requery
Me.txtNetPrice.Value = DSum(Nz("NetPrice", 0), "strSQL")
Exit Sub
End If
End Sub

Domain aggregate functions cannot reference SQL statement, only table and query objects. Do aggregate calc in a grouping query which can be the SQL statement in your code. However, SQL statement is not really needed for this. Simply use filter criteria in DSum() in textbox or VBA.
DSum("NetPrice", "qrySpending", "Month(orderDate) = 4 OR Month(orderDate) = 5 OR Month(orderDate) = 6) AND (PostCode = '" & Me.comboPostCode & "'")

Related

MS Access Dropdowns to filter through table

i have a big table, and have created a form that filters through that data.
However, at the moment, these filters do not work.
There are dropdown filters which correspond to columns and the idea is to choose a value from a specific column and get the rows with only the choosen value, also to filter few columns at once like that if neccessary - each box has mostly the same code, just the change of names.
Here is an example of one box code :
Private Sub klk_AfterUpdate()
Dim klkxas As String
klkxas = "Select * from daca where ([wdwqd] = '" & Me.cboLiefName & "') and ([sdcxsadc] = '" & Me.cboSRat & "') and ([Verantwortlicher] = '" & Me.cboVerant & "') and ([cxsacx] = '" & Me.cboLiefKat & "') and ([qxqxsa] = '" & Me.cboliefart & "') and ([sxsa] = '" & Me.cboLand & "') and ([sdxs] = '" & Me.cboAudErg & "')"
Me.Form.RecordSource = klkxas
Me.Form.Requery
End Sub
Can someone help me on how to change the code so it works?
Thanks in advance
If I were to guess, your issue is that even selecting one or more but not all comboboxes (i.e., leaving some comboboxes blank) results in no returned rows. Per your attempted query, this is not an error but valid result of SQL logic. Your users would need to correctly select values in all seven comboboxes to get any rows back.
One solution of this dynamic filtering problem is to use NZ (or IIF) to match each field to itself for non-selected comboboxes. Also, use a saved SQL query that points to form controls without any concatenation of VBA values and punctuation of quotes.
Below will return values if any one or all controls are selected. But do note after combobox selection, only rows with non-NULL across all fields will be returned. Be sure to adjust myForm to actual form name in query:
SQL (save as separate query and as recordsource to form)
SELECT *
FROM Lieferant
WHERE [Bezeichner] = NZ(Forms!myForm!cboLiefName, [Bezeichner])
AND [S_Rating] = NZ(Forms!myForm!cboSRat, [S_Rating])
AND [Verantwortlicher] = NZ(Forms!myForm!cboVerant, [Verantwortlicher])
AND [Lieferantenkategorie] = NZ(Forms!myForm!cboLiefKat, [Lieferantenkategorie])
AND [Lieferantenart] = NZ(Forms!myForm!cboliefart, [Lieferantenart])
AND [Land] = NZ(Forms!myForm!cboLand, [Land])
AND [Audit_Ergebnis] = NZ(Forms!myForm!cboAudErg, [Audit_Ergebnis])
VBA (single line!)
Private Sub cboSRat_AfterUpdate()
Me.Form.Requery
End Sub
If needing to capture rows with potential NULLs, integrate OR conditions:
SQL
SELECT *
FROM Lieferant
WHERE ([Bezeichner] = NZ(Forms!myForm!cboLiefName, [Bezeichner])
OR (Forms!myForm!cboLiefName IS NULL AND [Bezeichner] IS NULL)
)
AND ([S_Rating] = NZ(Forms!myForm!cboSRat, [S_Rating])
OR (Forms!myForm!cboSRat IS NULL AND [S_Rating] IS NULL)
)
AND ([Verantwortlicher] = NZ(Forms!myForm!cboVerant, [Verantwortlicher])
OR (Forms!myForm!cboVerant IS NULL AND [Verantwortlicher] IS NULL)
)
AND ([Lieferantenkategorie] = NZ(Forms!myForm!cboLiefKat, [Lieferantenkategorie])
OR (Forms!myForm!cboLiefKat IS NULL AND [Lieferantenkategorie]IS NULL)
)
AND ([Lieferantenart] = NZ(Forms!myForm!cboliefart, [Lieferantenart])
OR (Forms!myForm!cboliefart IS NULL AND [Lieferantenart] IS NULL)
)
AND ([Land] = NZ(Forms!myForm!cboLand, [Land])
OR (Forms!myForm!cboLand IS NULL AND [Land] IS NULL)
)
AND ([Audit_Ergebnis] = NZ(Forms!myForm!cboAudErg, [Audit_Ergebnis])
OR (Forms!myForm!cboAudErg AND [Audit_Ergebnis] IS NULL)
)
Somehow you (your code) must expand the where clause, for example:
myLieferantName = "Select * from Lieferant where [Bezeichner] = '" & Me.cboLiefName & "' And [Land] = '" & Me.cboLand & "'"
As a side note, a requery isn't needed after adjusting the recordsource:
Me.RecordSource = myLieferantName
' Me.Form.Requery

How to populate combo box from a select Query using VB in access?

I'm new to VB and trying to populate combo box in access from a select query's result which is getting value from another combo box and the code that i'm trying is:
Private Sub addPartsButtonForm_Click()
ssql = "SELECT * FROM EquipmentTbl WHERE [EquipmentID] = '" & Me.equipmentCombo.Column(0) & "'"
Me!comboParts = ssql
Me.comboParts.Requery
End Sub
and when i press the button i got the following result in combo box:
SELECT * FROM EquipmentTbl WHERE [EquipmentID] = '34'
though its giving me the exact equipmentID but expected is something else other than that. Please help me
Set the combo RowSource. Also, no need for quotes in case field is Number.
Dim sSql As String
sSql = "SELECT * FROM EquipmentTbl WHERE [EquipmentID] = " & Me.equipmentCombo.Column(0)
Me.comboParts.RowSource = ""
Me.comboParts.RowSource = sSql

Microsoft Access VBA Populating a field of a percentage of total records

When I click on button command9 I want to use the count function to count how many records matching combo7 and Insp_Cat = 1, then calculate 20% of the total records. Then using the Update statement update the field Insp_Type to "C" ,limiting the number of records to 20% of total records previously calculated.
This is the code I have to date but getting a syntax error on the count line.
Private Sub Command9_Click()
Dim strSql As String
Dim Rec_Qty As Integer
Dim Rec_Perc As Integer
'Return record count for all records in Tbl_Inspections matching WO_ID in Combo7 and Insp_Cat =1
Rec_Qty = Count (WO_ID & Insp_Cat) Where [WO_ID]= Me.[Combo7]& [Insp_Cat]=1 From Tbl_Inspections
Rec_Per = Rec_Qty * 0.2
'Update records for "C" 20% records using Rec_Per value in limit function of Update command
strSql = "Update Tbl_Inspections"
strSql = strSql & "Set Insp_Type = 'C' WHERE WO_ID = Me.Combo7 & Insp_Cat = 1 & Limit = Rec_Per"
CurrentDb.Execute strSql
End Sub
Can anyone help?
Can't use Count() function in VBA, only within a query or in textbox on form or report.
DCount() and other domain aggregate functions used in VBA.
Concatenate literal text and variables.
Rec_Qty = DCount("*", "Tbl_Inspections", "[WO_ID]= " & Me.[Combo7] & " AND [Insp_Cat]=1")
CurrentDb.Execute "Update Tbl_Inspections Set Insp_Type = 'C' WHERE WO_ID = " & Me.Combo7 & " AND Insp_Cat = 1 AND Limit = " & Rec_Per

Trouble with DoCmd.OpenReport with a complicated Where Clause (Syntax Issue)

So first I have gone over a very large amount of other sources trying to look for a solution or an explanation of my error, but I haven't found anything that helps me quite yet.
I have been learning all this stuff on my own so I am definitely lacking in some of the foundation knowledge and it has caught up to me. Basically the form I am having trouble with allows the user to generate three different reports based on the kind of criteria they care about. There are three different combo boxes cboCompany, cboProject, cboEmployee. I use the Nz command to change null values to zero and then use If Statements to determine which report to use depending on what the user selects. I hope that kind of makes since. Its easier to show than explain. That part all works fine though.
The problem I'm getting is when I want to do a print preview for the report the user generates. I need the where clause to take the values the user selects to use in the print preview. I can't get the syntax right for the where clause to actually do this.
Here is how I call my variables. The Nz function as I understand require the variables to be variants, because of this I'm not quite sure how to write the syntax for the where clause. I know integers, strings, and dates all have different syntax but I don't know what variant would be.
Dim Company As Variant
Dim Project As Variant
Dim Employee As Variant
Dim EndDate As String
Dim StartDate As String
Company = Nz(cboCompany, 0)
Project = Nz(cboProject, 0)
Employee = Nz(cboEmployee, 0)
StartDate = txtStartDate.Value
EndDate = txtEndDate.Value
So this next part is how I have written one of the report options with my best guess of the syntax for the where clause. It doesn't work so If you could help point me in the right direction I would greatly appreciate it.
ElseIf Company <> 0 And Project <> 0 And Employee <> 0 Then
DoCmd.OpenReport "ProjectReport_Employee_R", acViewPreview, "", "[cboCompany]= " & Company & " And [cboEmployee]= " & Employee & " And [cboProject]= " & Project & " And [txtStartDate]= #" & StartDate & "# And [txtEndDate]= #" & EndDate & "#", acWindowNormal
If I don't explain things well enough or you need more code to help please let me know, and thank you in advance.
***Edit: Just to give a more complete picture this is the code behind the entire form.
Private Sub cboCompany_AfterUpdate()
Me.cboProject.Requery
End Sub
Private Sub cmdSubmit_Click()
'Open Report With Filter Criteria
Dim Company As Variant
Dim Project As Variant
Dim Employee As Variant
Company = Nz(cboCompany, 0)
Project = Nz(cboProject, 0)
Employee = Nz(cboEmployee, 0)
If Company = 0 Then
MsgBox ("Please Select At Least A Company To Generate A Report")
cboCompany.Value = Null
cboProject.Value = Null
cboEmployee.Value = Null
ElseIf Company <> 0 And Project = 0 And Employee = 0 Then
DoCmd.BrowseTo acBrowseToReport, "ProjectReport_Company_R", "Main_F.NavigationSubform>ProjectReport_F.Child31"
ElseIf Company <> 0 And Project <> 0 And Employee = 0 Then
DoCmd.BrowseTo acBrowseToReport, "ProjectReport_Project_R", "Main_F.NavigationSubform>ProjectReport_F.Child31"
ElseIf Company <> 0 And Project <> 0 And Employee <> 0 Then
DoCmd.BrowseTo acBrowseToReport, "ProjectReport_Employee_R", "Main_F.NavigationSubform>ProjectReport_F.Child31"
ElseIf Company <> 0 And Project = 0 And Employee <> 0 Then
MsgBox ("Please Select A Project")
End If
End Sub
Private Sub Form_Current()
Me.cboCompany.SetFocus
End Sub
Private Sub Form_Load()
'Set Date Values
Dim EndDate As String
Dim StartDate As String
StartDate = Format(DateSerial(Year(Date), Month(DateAdd("m", -1, Date)), 16), "Short Date")
EndDate = Format(DateSerial(Year(Date), Month(Date), 15), "Short Date")
txtStartDate.Value = StartDate
txtEndDate.Value = EndDate
'Set The Form Message on Open Child31
DoCmd.BrowseTo acBrowseToForm, "ProjectReport_Message_F", "Main_F.NavigationSubform>ProjectReport_F.Child31"
End Sub
'------------------------------------------------------------
' Print_Click
'
'------------------------------------------------------------
Private Sub Command39_Click()
On Error GoTo Command39_Click_Err
Dim Company As Variant
Dim Project As Variant
Dim Employee As Variant
Dim EndDate As String
Dim StartDate As String
Company = Nz(cboCompany, 0)
Project = Nz(cboProject, 0)
Employee = Nz(cboEmployee, 0)
StartDate = txtStartDate.Value
EndDate = txtEndDate.Value
If Company <> 0 And Project = 0 And Employee = 0 Then
DoCmd.OpenReport "ProjectReport_Company_R", acViewPreview, "", "", acNormal
ElseIf Company <> 0 And Project <> 0 And Employee = 0 Then
DoCmd.OpenReport "ProjectReport_Project_R", acViewPreview, "", "", acNormal
ElseIf Company <> 0 And Project <> 0 And Employee <> 0 Then
DoCmd.OpenReport "ProjectReport_Employee_R", acViewPreview, "", "[cboCompany]= " & Company & " And [cboEmployee]= " & Employee & " And [cboProject]= " & Project & " And [txtStartDate]= '" & StartDate & "' And [txtEndDate]= '" & EndDate & "'", acWindowNormal
End If
Command39_Click_Exit:
Exit Sub
Command39_Click_Err:
MsgBox Error$
Resume Command39_Click_Exit
End Sub
I think you may be using the wrong field names in the filter.
Suppose that in Report Design your report's RecordSource is tblProject.
When you do this:
DoCmd.OpenReport "ProjectReport_Employee_R", , , "[cboCompany]= " & Company ...
you are effectively opening the report with a recordsource of:
SELECT * FROM tblProject WHERE [cboCompany] = 12345 AND ...
If tblProject doesn't have a field named "cboCompany" then it won't work.
I would base the report on a query rather than using the DoCmd's "WhereCondition" argument.
Make the "ProjectReport_Employee_R" recordsource a query called "qryProjectReport_Employee_R".
...then modify the query definition every time you want to run the report.
For example:
sub print_report()
'add these
dim qdf as Dao.Querydef
dim strSQL as String
if this then
ElseIf Company <> 0 And Project <> 0 And Employee <> 0 Then
'SQL may need modifying...
strSQL= "SELECT * FROM SomeTable WHERE [cboCompany]= " & Company & " And [cboEmployee]= " & Employee & " And [cboProject]= " & Project & " And [txtStartDate]= #" & StartDate & "# And [txtEndDate]= #" & EndDate & "#"
Set qdf="qryProjectReport_Employee_R"
qdf.SQL=strSQL
DoCmd.OpenReport "ProjectReport_Employee_R", acViewPreview
'clean up
set qdf=nothing
end if
end sub
That's all. Let me know if you have any questions.

SQL too long for String

I have the following SQL to be queried. It is a valid SQL. Unfortunately, it is too long for a string in VBA. Anyone knows of a workaround to run this query?
SQL = "SELECT A.cust_ky, A.incid_id, A.OPEN_TS, A.CLOSE_TS, A.REC_UPD_TS, B.wrkgp_id, A.CURR_AGNT_KY, A.incid_ttl_dn " _
& "FROM (MAINTBLS.INCID_FAB A INNER JOIN MAINTBLS.DEPTMNT B ON A.curr_wrkgp_ky=B.wrkgp_ky) " _
& "WHERE B.wrkgp_id='" & wrkgp & "' And (A.open_fg = 1 OR A.pend_fg = 1)" _
& "ORDER BY A.cust_ky, A.curr_agnt_ky ASC"
rs.Open SQL, con, adOpenKeyset
Since you use Oracle, you should use a bind variable instead of dynamic SQL and then set the value in the parameter collection of the command object. Not only will it prevent SQL Injection, but it will better optimize your query.
Also, it looks like your SQL Statement is missing a space before the order by clause. That could easily cause your error. See below - untested, but should give you the idea.
SQL = "SELECT A.cust_ky, A.incid_id, A.OPEN_TS, A.CLOSE_TS, A.REC_UPD_TS, B.wrkgp_id, A.CURR_AGNT_KY, A.incid_ttl_dn " _
& "FROM (MAINTBLS.INCID_FAB A INNER JOIN MAINTBLS.DEPTMNT B ON A.curr_wrkgp_ky=B.wrkgp_ky) " _
& "WHERE B.wrkgp_id= :wrkgp And (A.open_fg = 1 OR A.pend_fg = 1) " _
& "ORDER BY A.cust_ky, A.curr_agnt_ky ASC"
With cmd
.ActiveConnection = conn
.CommandText = SQL
.CommandType = adCmdText
.Parameters.Append .CreateParameter(, adVarChar, adParamInput, wrkgp)
End With
Create a view for the query, something like this
create view fix_for_broken_vba as
SELECT A.cust_ky, A.incid_id, A.OPEN_TS, A.CLOSE_TS, A.REC_UPD_TS, B.wrkgp_id,
A.CURR_AGNT_KY, A.incid_ttl_dn FROM (MAINTBLS.INCID_FAB A INNER JOIN MAINTBLS.DEPTMNT B ON A.curr_wrkgp_ky=B.wrkgp_ky)
WHERE (A.open_fg = 1 OR A.pend_fg = 1)
and then rewrite the query accordingly.
If you are using VBA in an Excel sheet, why don't you consider putting the SQL query in a protected cell of your document? You could even put it in an hidden sheet of your document.
Something like:
Cells(6, 2).Select
sqlString = Cells(6, 2).Value
I did it and it works like a charm in my case.
I've used the following steps for a 100+ line query
Use a long Query with Excel VBA
Initially create the query in SSMS
Create a sheet called SQL Query
Copy and paste the query in to the SQL Query sheet and delete all rows that are blank or commented row
Incorporate any variables in to the declare statement
Use the following macro to loop through the SQL Query sheet
LastRowQ = ThisWorkbook.Sheets("SQL Query").Cells(ThisWorkbook.Sheets("SQL Query").Rows.Count, "B").End(xlUp).Row
Count = 2
Do Until Count > LastRowQ
SQLQTemp = ThisWorkbook.Sheets("SQL Query").Range("B" & Count)
SQLQuery = SQLQuery & " " & SQLQTemp
Count = Count + 1
Loop
SQLDatabaseRS.Open SQLQuery