Showing totals from previous months, What am I missing? - sql

when I run this code it isn't showing the right records I need to see. I'm missing something somewhere but I'm not seeing it. The idea is for this to pull a count of all completed, in progress and Not started from the previous month and give me the totals.
Sub Update()
StatusCount "Completed"
StatusCount "In Progress"
StatusCount "Not Started"
'StatusCount "Moved to Cleanup"
'StatusCount "N/A"
'StatusCount "This is a new category" ', Now - 2, Now + 3
End Sub
Sub StatusCount(ByVal status As String, Optional start_date As Date, Optional end_date As Date)
Dim i As Variant
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim qd As DAO.QueryDef
Set db = CurrentDb
Dim SQL As String
If start_date = 0 Or end_date = 0 Then
SQL = "insert into statussummary (Count,mmyy,status) Select count(*), [created], [research status] " & _
"from [gwc master list]" & _
"where [research status] = '" & status & "'" & _
"group by [research status], [created]"
Else
SQL = "insert into statussummary (Count,mmyy,status) Select count(*), [created],[research status] " & _
"from [gwc master list]" & _
"where [research status] = '" & status & "'" & _
" and [created] > #" & start_date & "# and created < #" & end_date & "#" & _
"group by [research status], [created]"
End If
db.Execute (SQL)
rc = db.RecordsAffected
If rc = 0 Then
Debug.Print status & ": " & rc
SQL = "insert into statussummary (Count,status) values (" & rc & ", '" & status & "')"
db.Execute (SQL)
End If
End Sub
Any help is appreciated
-D

First, you need to change your database table field names. As mentioned, "status" is reserved, as is "count". Therefore, your three fields should be something like [R_COUNT], [CREATED], [R_STATUS]. Then, you restructure your VBA code like so:
Sub StatusCount(ByVal status_var As String, Optional start_date As Date, Optional end_date As Date)
This should solve the first conflict with "status". Then, you modify your first SQL statement to specify the correct fields you are inserting into statussummary (as I changed the names to above). Don't forget that you missed a space or two in the code before the continuation marks.
If start_date = 0 Or end_date = 0 Then
SQL = "insert into statussummary ([R_COUNT], [CREATED], [R_STATUS]) Select COUNT(*), [created], [research status] " & _
"from [gwc master list] " & _
"where [research status] = '" & status_var & "'" & _
" group by [research status], [created];"
Else
SQL = "insert into statussummary ([R_COUNT], [CREATED], [R_STATUS]) Select COUNT(*), [created], [research status] " & _
"from [gwc master list] " & _
"where [research status] = '" & status_var & "'" & _
" and [created] > #" & start_date & "# and created < #" & end_date & "#" & _
" group by [research status], [created];"
End If
Finally, fix your last statement:
rc = db.RecordsAffected
If rc = 0 Then
Debug.Print status & ": " & rc
SQL = "insert into statussummary ([R_COUNT], [R_STATUS]) values (" & rc & ", '" & status_var & "');"
db.Execute (SQL)
End If
End Sub

Related

How to Pass SQL Parameter to Form Using OpenArgs?

I have a Database (not built by me) that uses 3 separate forms to accomplish 1 thing.
I would instead like to pass a SQL string to the OpenArgs in order to utilize 1 form.
Original Code for form I'd like to utilize:
Private Sub Form_Open(Cancel As Integer)
Dim strSQL As String
If Not IsNull(Me.OpenArgs) Then
strSQL = "SELECT tbl_COMBINED.[First Name] AS [Name Badge], 'P' AS Logo, Format(Now(),""yyyy"") & STOCKHOLDERS MEETING' AS MEETING " _
& "FROM tbl_COMBINED " _
& "GROUP BY tbl_COMBINED.[First Name], 'P', Format(Now(),""yyyy"") & ' STOCKHOLDERS MEETING', " _
& "tbl_COMBINED.ACCOUNT, tbl_COMBINED.Came " _
& "HAVING tbl_COMBINED.ACCOUNT = '" & CStr(Me.OpenArgs) & "' " _
& "AND ((tbl_COMBINED.Came) Is Null Or (tbl_COMBINED.Came)) = 0"
Me.RecordSource = strSQL
End If
End Sub
Each of the other forms is called by using
DoCmd.OpenForm "frm_newmanualnamebadge", "", "",, acNormal
from the Main form and has the SQL string in the row source. I would like to eliminate the row source and utilize the 1 form. I set the string from each button to:
strManuel = "SELECT tbl_manual_name_badge.NAMEBADGE1, tbl_manual_name_badge.MEETING, " _
& "tbl_manual_name_badge.LOGO, tbl_manual_name_badge.Stockerholder " _
& "FROM tbl_manual_name_badge"
DoCmd.OpenForm "frm_newmanualnamebadge", "", "",, acNormal, strManual
Passing the strManual to the form as a SQL string, however, every time I run it I get a "#Name?" in the name field instead of the name entered.
Here is the code I used on the form:
If Not IsNull(Me.OpenArgs) Then
strSQL = "SELECT tbl_COMBINED.[First Name] AS [Name Badge], 'P' AS Logo " _
& "FROM tbl_COMBINED " _
& "GROUP BY tbl_COMBINED.[First Name], 'P', " _
& "tbl_COMBINED.ACCOUNT, tbl_COMBINED.Came " _
& "HAVING tbl_COMBINED.ACCOUNT = '" & CStr(Me.OpenArgs) & "' " _
& "AND ((tbl_COMBINED.Came) Is Null Or (tbl_COMBINED.Came)) = 0"
Me.RecordSource = strSQL
ElseIf IsNull(Me.OpenArgs) Then
strSQL = "SELECT tbl_manual_name_badge.NAMEBADGE1, tbl_manual_name_badge.MEETING, " _
& "tbl_manual_name_badge.LOGO, tbl_manual_name_badge.Stockerholder " _
& "FROM tbl_manual_name_badge"
Me.RecordSource = strSQL
End If
Well, you either pass one value, or you pass the whole sql string.
But, if you passing the WHOLE sql string for the form, then this makes no sense:
If Not IsNull(Me.OpenArgs) Then
strSQL = "SELECT tbl_COMBINED.[First Name] AS [Name Badge], 'P' AS Logo " _
& "FROM tbl_COMBINED " _
& "GROUP BY tbl_COMBINED.[First Name], 'P', " _
& "tbl_COMBINED.ACCOUNT, tbl_COMBINED.Came " _
& "HAVING tbl_COMBINED.ACCOUNT = '" & CStr(Me.OpenArgs) & "' " _
& "AND ((tbl_COMBINED.Came) Is Null Or (tbl_COMBINED.Came)) = 0"
Me.RecordSource = strSQL
I mean, OpenArgs is a WHOLE sel string, and I am VERY sure that ACCOUNT = " some huge sql string" will NEVER work.
So, you would want this:
Dim strSQL As String
If Not IsNull(Me.OpenArgs) Then
strSQL = me.OpenArgs
else
strSQL = "SELECT tbl_manual_name_badge.NAMEBADGE1, tbl_manual_name_badge.MEETING, " _
& "tbl_manual_name_badge.LOGO, tbl_manual_name_badge.Stockerholder " _
& "FROM tbl_manual_name_badge"
End If
Me.RecordSource = strSQL
So, our logic is now:
if passed sql string (openargs), then that becomes our sql
if no open arges, then use the defined sql we have in the on-load

SQL in VBA erro: Each GROUP BY expression must contain at least one column that is not an outer reference

Trying to extract data with this query and group by Item number, but getting error:
Each GROUP BY expression must contain at least one column that is not
an outer reference
When try to use Order by getting error that need to use GROUP BY.
' Database source and connect
dbstr = "Provider=SQLOLEDB;Data Source=" & get_market_setting(market, "Data Source") & _
";Initial Catalog=" & get_market_setting(market, "Initial Catalog") & _
";Integrated Security=SSPI"
sourceDb.Connect (dbstr)
' Date from/to filter
date_from = ThisWorkbook.Sheets("Data").Range("H3").Value
date_to = ThisWorkbook.Sheets("Data").Range("H5").Value
' Set Header filter
table_TSE = "[" & get_market_setting(market, "Database") & "$Trans_Sales Entry]"
' SQL query string
myquery = "SELECT " & ItemNo & ", -SUM( " & NetAmount & " ) FROM " & table_TSE & _
" WHERE " & ItemNo & " IN " & Itemnr1 & _
" AND [Date] BETWEEN '" & date_from & "' AND '" & date_to & _
" GROUP BY '" & ItemNo & " '"
MsgBox myquery
' Set Recordset to query set database on SQL string
Set sourceRs = sourceDb.OpenRecordset(myquery)
'Assign Data to variable from RecordSet'
sourceRs.MoveFirst
sourceRs.Close
sourceDb.CloseRecordset

Dynamically run strings in a loop

I want to run a string dynamically.
I'm trying to run a VBA loop to build a SQL Union for each record after the first. There could be anywhere from 1 record to 100. I want this to be dynamic so I don't have to limit the number of entries.
Example:
If I have 5 records it creates the SQL query with 4 unions. All the same data etc.
I'm trying to do is this:
When someone opens a form they will enter a list of pack numbers, from that they will select the range of offers under each pack number (All Offers, Promo, or Buyer).
The code then builds a union query for each pack number based on the the offer range they selected.
The output is all the data on those Offers under that pack number.
My full code: (I thought it necessary to get the full picture)
Private Sub ReviewButton_Click()
Dim Owner As String
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim qdfPassThrough As QueryDef
Dim strSeasonSQL As String
Dim strSeason As String
Dim strType As String
Owner = GetNamespace("MAPI").Session.CurrentUser.AddressEntry
If Me.NewRecord = True Then
Me!Owner.Value = Owner
End If
Set db = CurrentDb
Set rs = CurrentDb.OpenRecordset("RetailEntry")
'Set rs = CurrentDb.OpenRecordset("SELECT * FROM RetailEntry")
strSeason = [Forms]![Retail_Navigation]![NavigationSubform].[Form]![cboSeason]
strType = rs.Fields("Offer").Value '[Forms]![ReviewButton]![RetailEntry].[Form]![Offer].Value
On Error GoTo 1
1:
'Build Initial Query based on first record and make sure there are records
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
If Not (rs.EOF And rs.BOF) Then
rs.MoveFirst
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'All Offers
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
If rs.Fields("Offer") = "All Offers" Then
StrSQL = "Set NoCount ON DROP TABLE #catcov; " _
& "SELECT DISTINCT mailyear, offer, description, firstreleasemailed, season_id, offer_type, " _
& "case when description like '%Promo%' then 'Promo' " _
& "Else 'Buyer' end As addtype " _
& "INTO #catcov " _
strSELECT = "FROM supplychain_misc.dbo.catcov; " _
& "SELECT DISTINCT " _
& "a.PackNum " _
& ",a.Description " _
& ",a.CatID " _
& ",DATEPART(QUARTER, FirstReleaseMailed) as Quarter " _
& ",a.RetOne " _
& ",a.Ret2 " _
& ",a.ORIGINALRETAIL " _
& ",a.DiscountReasonCode " _
& ",b.Season_id " _
& ",a.year " _
& ",addtype "
strFROM = "FROM PIC704Current a JOIN #CatCov b ON (a.CatID = b.Offer) and (a.Year = b.MailYear) " _
strWHERE = "WHERE b.Offer_Type In('catalog', 'insert', 'kicker', 'statement insert', 'bangtail', 'onsert', 'outside ad') " _
& " and b.Season_id = '" & strSeason & "' " _
& " and (Case when b.FirstReleaseMailed >= cast(dateadd(day, +21, getdate()) as date) then 1 else 0 end) = 1 "
StrSQL = StrSQL & vbCrLf & strSELECT & vbCrLf & strFROM & vbCrLf & strWHERE
'Promo/Core
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
ElseIf rs.Fields("Offer") = "Promo" Or rs.Fields("Offer") = "Buyer" Then
StrSQL = "Set NoCount ON DROP TABLE #catcov; " _
& "SELECT DISTINCT mailyear, offer, description, firstreleasemailed, season_id, offer_type, " _
& "case when description like '%Promo%' then 'Promo' " _
& "Else 'Buyer' end As addtype " _
& "INTO #catcov " _
strSELECT = "FROM supplychain_misc.dbo.catcov; " _
& "SELECT DISTINCT " _
& "a.PackNum " _
& ",a.Description " _
& ",a.CatID " _
& ",DATEPART(QUARTER, FirstReleaseMailed) as Quarter " _
& ",a.RetOne " _
& ",a.Ret2 " _
& ",a.ORIGINALRETAIL " _
& ",a.DiscountReasonCode " _
& ",b.Season_id " _
& ",a.year " _
& ",addtype "
strFROM = "FROM PIC704Current a JOIN #CatCov b ON (a.CatID = b.Offer) and (a.Year = b.MailYear) " _
strWHERE = "WHERE b.Offer_Type In('catalog', 'insert', 'kicker', 'statement insert', 'bangtail', 'onsert', 'outside ad') " _
& " and b.Season_id = '" & strSeason & "' and b.addtype = '" & strType & "' " _
& " and (Case when b.FirstReleaseMailed >= cast(dateadd(day, +21, getdate()) as date) then 1 else 0 end) = 1 "
StrSQL = StrSQL & vbCrLf & strSELECT & vbCrLf & strFROM & vbCrLf & strWHERE
End If
'Build/Loop Unions for each record after the first
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
rs.MoveNext
strType = rs.Fields("Offer").Value
Do Until rs.EOF = True
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'All Offers
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
If rs.Fields("Offer") = "All Offers" Then
StrUnion = "UNION SELECT DISTINCT " _
& "a.PackNum " _
& ",a.Description " _
& ",a.CatID " _
& ",DATEPART(QUARTER, FirstReleaseMailed) as Quarter " _
& ",a.RetOne " _
& ",a.Ret2 " _
& ",a.ORIGINALRETAIL " _
& ",a.DiscountReasonCode " _
& ",b.Season_id " _
& ",a.year " _
& ",addtype "
strFROMnxt = "FROM PIC704Current a JOIN #CatCov b ON (a.CatID = b.Offer) and (a.Year = b.MailYear) " _
strWHEREnxt = "WHERE b.Offer_Type In('catalog', 'insert', 'kicker', 'statement insert', 'bangtail', 'onsert', 'outside ad') " _
& " and b.Season_id = '" & strSeason & "' " _
& " and (Case when b.FirstReleaseMailed >= cast(dateadd(day, +21, getdate()) as date) then 1 else 0 end) = 1 "
StrSQL2 = StrUnion & vbCrLf & strFROMnxt & vbCrLf & strWHEREnxt
'Promo/Buyer
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
ElseIf rs.Fields("Offer") = "Promo" Or rs.Fields("Offer") = "Buyer" Then
StrUnion = "UNION SELECT DISTINCT " _
& "a.PackNum " _
& ",a.Description " _
& ",a.CatID " _
& ",DATEPART(QUARTER, FirstReleaseMailed) as Quarter " _
& ",a.RetOne " _
& ",a.Ret2 " _
& ",a.ORIGINALRETAIL " _
& ",a.DiscountReasonCode " _
& ",b.Season_id " _
& ",a.year " _
& ",addtype "
strFROMnxt = "FROM PIC704Current a JOIN #CatCov b ON (a.CatID = b.Offer) and (a.Year = b.MailYear) " _
strWHEREnxt = "WHERE b.Offer_Type In('catalog', 'insert', 'kicker', 'statement insert', 'bangtail', 'onsert', 'outside ad') " _
& " and b.Season_id = '" & strSeason & "' and b.addtype = '" & strType & "' " _
& " and (Case when b.FirstReleaseMailed >= cast(dateadd(day, +21, getdate()) as date) then 1 else 0 end) = 1 "
StrSQL2 = StrUnion & vbCrLf & strFROMnxt & vbCrLf & strWHEREnxt
End If
'Move to next Record and loop till EOF
rs.MoveNext
Loop
'If there are no Records then error
Else
MsgBox "There are no Pack Numbers Entered."
End If
'END QUERY
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Build Retail Bump File Pass Through Query
db.QueryDefs.Delete "qryMaster"
Set qdfPassThrough = db.CreateQueryDef("qryMaster")
qdfPassThrough.Connect = "ODBC;DSN=SupplyChainMisc;Description=SupplyChainMisc;Trusted_Connection=Yes;DATABASE=SupplyChain_Misc;"
qdfPassThrough.ReturnsRecords = True
qdfPassThrough.sql = StrSQL & vbCrLf & StrSQL2
rs.Close
Set rs = Nothing
DoCmd.OpenForm "SubCanButton"
DoCmd.OpenQuery "MasterQuery"
DoCmd.Close acForm, "ReviewButton"
End Sub
First, you do a "union distinct" when you don't include ALL:
UNION ALL
SELECT DISTINCT ...
Thus, as your selected records seem the same, only one will returned.
Second, including ALL or not, your concept doesn't make much sense. Why union a lot of identical records? Even if they hold different IDs only, they seem to be pulled from the same table, which you could with a single query.
Third, casting a date value to a date value does nothing good, so:
cast(dateadd(day, +21, getdate()) as date)
can be reduced to:
dateadd(day, +21, getdate())

Getting error message : You tried to execute a query that does not include the specified expression 'CS' as an aggregate function for an UPDATE query

I am trying to execute the below update query but it throws an error stating 'CS' is not part of an aggregate function. No clue as to what the error could be.
UPDATE [Control Shipping Summary Report] INNER JOIN tblmayscores ON [Control Shipping Summary Report].[Supplier DUNS Code] = tblmayscores.[Supplier DUNS] SET tblmayscores.CS = Count([Control Shipping Summary Report].[Supplier Location Code])
WHERE ((([Control Shipping Summary Report].MonthofProblemcaseNumber)=" & curnt_month & ") AND (([Control Shipping Summary Report].YearofProblemcaseNumber)=" & curnt_year & ")) OR ((([Control Shipping Summary Report].YearofProblemcaseNumber)=" & curnt_year - 1 & "));
You could try something like this:
UPDATE tblmayscores
SET CS = DCount("Supplier Location Code", "Control Shipping Summary Report", "((MonthofProblemcaseNumber=" & curnt_month & ") AND (YearofProblemcaseNumber=" & curnt_year & ")) OR (YearofProblemcaseNumber=" & curnt_year - 1 & ")")
Edit
When creating a VBA string literal enclosed in double-quotes ("), any double-quotes within that string must be doubled-up (""). For example, the VBA code
MsgBox "My favorite astronaut is Edwin ""Buzz"" Aldrin."
...will present a messagebox saying My favorite astronaut is Edwin "Buzz" Aldrin..
So, your VBA code...
strsql = "UPDATE tblmayscores SET CS = DCount("[Supplier DUNS]", "Control Shipping Summary Report", "([MonthofProblemcaseNumber]='" & curnt_month & "'" And "[YearofProblemcaseNumber] = '" & curnt_year & "'") Or "[YearofProblemcaseNumber] = '" & curnt_year - 1 & "'")"
...is broken because the string literal includes bare " characters. Try something like this:
strsql = "UPDATE tblmayscores SET CS = DCount(""[Supplier DUNS]"", ""Control Shipping Summary Report"", ""(([MonthofProblemcaseNumber]=" & curnt_month & ") AND ([YearofProblemcaseNumber]=" & curnt_year & ")) Or ([YearofProblemcaseNumber]=" & curnt_year - 1 & ")"")"
Edit
Unfortunately in your particular circumstance the DCount() approach won't work. Also, as you have discovered, UPDATE queries with JOINs on aggregate queries can be problematic. It looks like in your case you'll need to resort to a temporary table. That would involve something like
Dim cdb AS DAO.Database
Set cdb = CurrentDb
strsql = _
"SELECT " & _
"[Supplier DUNS Code], " & _
"COUNT([Supplier Location Code]) AS CodeCount " & _
"INTO zzz_tmp_code_counts " & _
"FROM [Control Shipping Summary Report] " & _
"WHERE " & _
"(" & _
"(MonthofProblemcaseNumber=" & curnt_month & ") " & _
"AND (YearofProblemcaseNumber=" & curnt_year & ")" & _
") " & _
"OR (YearofProblemcaseNumber=" & curnt_year - 1 & ") " & _
"GROUP BY [Supplier DUNS Code]"
cdb.Execute strsql, dbFailOnError
strsql = _
"UPDATE tblmayscores INNER JOIN zzz_tmp_code_counts " & _
"ON tblmayscores.[Supplier DUNS]=zzz_tmp_code_counts.[Supplier DUNS Code] " & _
"SET tblmayscores.CS = zzz_tmp_code_counts.CodeCount"
cdb.Execute strsql, dbFailOnError
DoCmd.DeleteObject acTable, "zzz_tmp_code_counts"

Filtering with Combo Boxes and SQL Using the MID Command

I have tried and tried to get this peice of code working but with no luck.
The code is supposed to pick products that have the same sections of product code as cmbsource.
Private Sub cmbSource_AfterUpdate()
Dim Worktop As String
If ProductType = 1 Then
Worktop = "SELECT [products/stock].[Product Code], [products/stock].Description, [products/stock].[Stock Level] FROM [products/stock] " & _
"WHERE Category = 'DPALRC' " & _
"AND Mid('[Product Code]',1,5) = Mid('" & Me.cmbSource.Value & "',1,5) " & _
"AND Mid('[Product Code]',9,6) = Mid('" & Me.cmbSource.Value & "',9,6) " & _
"ORDER BY [Product Code];"
Me.cmbResult.rowSource = Worktop
Me.cmbResult = vbNullString
End If
Any Ideas?
Thanks in advance,
Bob P
Just a wild guess here.
Worktop = "SELECT ps.[Product Code], ps.Description, ps.[Stock Level]" & vbCrLf & _
"FROM [products/stock] AS ps" & vbCrLf & _
"WHERE ps.Category = 'DPALRC'" & vbCrLf & _
"AND Mid([Product Code],1,5) = '" & Mid(Me.cmbSource,1,5) & "'" & vbCrLf & _
"AND Mid([Product Code],9,6) = '" & Mid(Me.cmbSource,9,6) & "'" & vbCrLf & _
"ORDER BY ps.[Product Code];"
Debug.Print Worktop
Go to the Immediate window (Ctrl+g) and copy the statement from there. Then create a new Access query, switch to SQL View, paste in the statement text, and run it.
If the code I suggested does not return the results you want, show us the actual SQL statement text and explain what is wrong with it.
Worktop = "SELECT [products/stock].[Product Code], [products/stock].Description, [products/stock].[Stock Level] FROM [products/stock] " & _
"WHERE Category = 'DPALRC' " & _
"AND Mid([Product Code],1,5) = Mid('" & Me.cmbSource.Value & "',1,5) " & _
"AND Mid([Product Code],9,6) = Mid('" & Me.cmbSource.Value & "',9,6) " & _
"ORDER BY [Product Code];"
This is my updated version, turns out the only error in the coding was having the single quotes around [Product Code].