Report: Counting number of records, between a number range - ms-access-2013

MS Access 2013. I need to write a report that shows the number of books inside our storage boxes.
All books purchased are given a unique nbr (SaleID). We store 25 books per box, and 100 books takes 4 boxes. As we sell books, they are removed from their specific boxes, and over time, lets say 30 books are sold. We can then discard one box, and store the remaining 70 books in three boxes. We have thousands of books and hundreds of storage boxes. I need to run a report that shows me how many books are in stock, per every 100 books, so that I can reduce the number of boxes (and save storage space).
The report should show like this:
001 - 100 34 (i.e. 34 books are in stock in the number range 001 to 100.
101 - 200 35 (35 books in stock)
201 - 300 22 (22 books in stock)
301 - 400 60 (60 books in stock)
etc
The query below does what I want, where I enter the criteria of the hundred books being queried. But I need a line on the report, for each hundred books, for all the books we hold.
SELECT tblSale.BookInStock, Count(tblSale.BookInStock) AS [Total Books]
FROM tblSale
WHERE (((tblSale.SaleID) Between 4201 And 4300))
GROUP BY tblSale.BookInStock
HAVING (((tblSale.BookInStock)=Yes));
If someone has any ideas I'd be grateful for your thoughts
Cheers
Nev

Since you have to query every hundred items, coding will be needed to run through every per hundred batch. Therefore, consider creating a temp table from a VBA looped query.
First iteration of loop creates the table replacing previous, then all other iterations append by hundred batches (notice step used to skip iterator forward) across your thousands. By the way, your HAVING clause condition was moved to WHERE clause.
Dim i As Long
Dim sqlStr As String
Dim db As DAO.Database
Dim tbl As TableDef
Set db = CurrentDb
For Each tbl in db.TableDefs
If tbl.Name = "BoxBooksPerHundred" Then
db.TableDefs.Delete(tbl.Name)
End If
Next tbl
For i = 1 to 4300 Step 100 ' ADJUST AS NEEDED
If i = 1 Then
' MAKE-TABLE QUERY
strsql= "SELECT '" & i & " - " & i + 100 & "' AS [HundredRange], tblSale.BookInStock," _
& " Count(tblSale.BookInStock) AS [Total Books]" _
& " INTO BoxBooksPerHundred FROM tblSale" _
& " WHERE (((tblSale.BookInStock)=Yes)) And" _
& " (((tblSale.SaleID) Between " & i & " And " & i + 100 & "))" _
& " GROUP BY '" & i & " - " & i + 100 & "', tblSale.BookInStock;"
db.Execute strSQL, dbFailOnError
Else
' APPEND QUERY
strsql= "INSERT INTO BoxBooksPerHundred (HundredRange, BookInStock, [Total Books])"
& " SELECT '" & i & " - " & i + 100 & "' AS [HundredRange], tblSale.BookInStock," _
& " Count(tblSale.BookInStock) AS [Total Books]" _
& " FROM tblSale" _
& " WHERE (((tblSale.BookInStock)=Yes)) And" _
& " (((tblSale.SaleID) Between " & i & " And " & i + 100 & "))" _
& " GROUP BY '" & i & " - " & i + 100 & "', tblSale.BookInStock;"
db.Execute strSQL, dbFailOnError
End If
Next i
Set tbl = Nothing
Set db = Nothing
Run this loop on the trigger event that opens report. But since quite a bit of data, try triggering on database open if you expect data not to change often. Ultimately, use this temp table, BooksPerHundred, as recordsource for report.

Related

MS Visual Studio (Reporting Services)

I've worked in SSRS for years but have never learned what this type of coding is actually named (which makes searching for solutions difficult), can anyone help please? Below is an example which allows the developer to have the code run as one continuous string. It also, if you're not familiar, allows for many powerful functions to be used that would otherwise (to my knowledge) not be available (e.g., IIF's, INSTR(JOIN()), SWITCH's, etc.).
=
" select distinct bn " &
" into #ST " &
" from frm_cr_2021 a " &
" join Md..nui_crssw b " &
" ON a.rc=b.cy"&MID(YEAR(Parameters!frm_dt.Value),3,2)&"_rc" &
" join nd_bs..dg_cv c " &
" on b.nd=c.nd " &
" where a.f_Dt<=#frm_dt and a.tr_dt>=#frmy_dt " &
"(select distinct c.ln,a.RC,A.Tr_Lv,a.P_Typ,a.P_Gp,a.Eff_Date,a.Term_Date from frm_"&YEAR(Parameters!frm_dt.Value)&" a "

Passing a MS Access Form date into an Oracle SQL

I'm using MS Access to pull some data from an Oracle server via a pass-through query. The user is presented with a form in which they can input some variables (such as a date range). I would like the Oracle SQL to be able to pick up the two date fields from the form.
The current SQL (which doesn't work) is as follows:
SELECT a.I_LOAN_NUM, a.I_LOAN_SUB_ALLOC, c.N_EXCLV, e.I_GSL_SPNSR, e.N_GSL_SPNSR, b.D_CAL, b.C_LOAN_STAT, g.N_CNTRY
FROM SLD_LOAN_MSTR a
JOIN SLD_LOAN_CDL b on b.I_LOAN_ID = a.I_LOAN_ID
JOIN SLD_EXCLV c on c.I_EXCLV_ID = b.I_EXCLV_ID
JOIN SLD_AC d on d.I_AC_ID = b.I_AC_ID
JOIN SLD_CUST e on e.I_CUST_ID = d.I_CUST_ID
JOIN SLD_DPT_CNTRY f on f.I_DPT_ID = b.I_DPT_ID
JOIN SLD_CNTRY g on g.I_CNTRY_ID = f.I_CNTRY_ID
WHERE (b.C_LOAN_STAT = 'SETTLED' and b.D_CAL between [Forms]![Cost Allocation Form]![Start_Date] and [Forms]![Cost Allocation Form]![End_Date])
ORDER BY b.D_CAL
The above SQL works if I replace the form references with hard coded dates, so I know the SQL is generally good. Example:
WHERE (b.C_LOAN_STAT = 'SETTLED' and b.D_CAL between '01JAN2019' and '01FEB2019')
The error message being generated by the SQL states "ODBC--call failed. [Oracle][ODBC][Ora]ORA-00936: missing expression (#936)"
Both of the date fields in the Form are using the Short Date format.
I'm not sure if this makes any difference or not, but the Form has multiple tabs. From what I've seen from other examples, the Form reference doesn't need to take the tab labels into account.
Thanks
Pass-through queries are executed at the server. In your case the Oracle server doesn't recognize the [Forms]![Cost Allocation Form]![Start_Date] and [Forms]![Cost Allocation Form]![End_Date] attributes.
You could use VBA to dynamically update the query definition of the query to include the form control values. Then execute the query.
Dim strSQL As String
Dim qdf As QueryDef
strSQL = "SELECT a.I_LOAN_NUM, a.I_LOAN_SUB_ALLOC, c.N_EXCLV, e.I_GSL_SPNSR, e.N_GSL_SPNSR, b.D_CAL, b.C_LOAN_STAT, g.N_CNTRY " & _
"FROM SLD_LOAN_MSTR a " & _
"JOIN SLD_LOAN_CDL b on b.I_LOAN_ID = a.I_LOAN_ID " & _
"JOIN SLD_EXCLV c on c.I_EXCLV_ID = b.I_EXCLV_ID " & _
"JOIN SLD_AC d on d.I_AC_ID = b.I_AC_ID " & _
"JOIN SLD_CUST e on e.I_CUST_ID = d.I_CUST_ID " & _
"JOIN SLD_DPT_CNTRY f on f.I_DPT_ID = b.I_DPT_ID " & _
"JOIN SLD_CNTRY g on g.I_CNTRY_ID = f.I_CNTRY_ID " & _
"WHERE (b.C_LOAN_STAT = 'SETTLED' and b.D_CAL between '" & _
[Forms]![Cost Allocation Form]![Start_Date] & "' and '" & [Forms]![Cost Allocation Form]![End_Date] & _
"' ORDER BY b.D_CAL"
Set qdf = CurrentDb.QueryDefs("PassThroughQueryName")
qdf.SQL = strSQL
Also since your using dates, I would suggest you format your dates to the ISO format yyyy-mm-dd
in this case formatting the controls like
Format([Forms]![Cost Allocation Form]![Start_Date], "yyyy-mm-dd") & "' and '" & Format([Forms]![Cost Allocation Form]![End_Date], "yyyy-mm-dd")
Another way would be to just use VBA ADO to access the Oracle Server and retrieve the data. You would still need to build up your SQL string as mentioned here.

MS Access. Grouping records by date

Using MS Access. I'm trying to write a report, grouped by date into weeks (Mon thru Sunday) and give a total of all transactions during the week.
There are only two tables.
Here is the sql:
SELECT tblBuyer.BuyerTradeDate, [booksold]-[bookpaid]-[booktradefee] AS Outcome
FROM tblSale INNER JOIN tblBuyer ON tblSale.BuyerID = tblBuyer.buyerID;
My query returns two columns, BuyerTradeDate and Outcome.
The image below shows some test data.
Sample output from query
I need the report to display:
Report Output
I'd be grateful for any suggestions. Thanks.
Here is what I've come up with that provides the solution I need.
In the report I've added a BuyerTradeDate header with a txt box containing:
="Week Number: " & Format$([BuyerTradeDate],"ww",0,0)
I've added a BuyerTradeDate Footer with a txt box containing:
="Summary for week beginning: " & " " & [BuyerTradeDate] & " (" & Count(*) & " " & IIf(Count(*)=1,"Trade","Trades") & ")"
The report looks like this:
Report Output
Create a field in your source query or in your report having this expression as control source:
=Weekday([BuyerTradeDate],2)
Then group on this in your report.
To have the first and the last date of the week, use these functions:
Public Function DateWeekFirst( _
ByVal datDate As Date, _
Optional ByVal lngFirstDayOfWeek As VbDayOfWeek = vbUseSystemDayOfWeek) _
As Date
' Returns the first date of the week of datDate.
' lngFirstDayOfWeek defines the first weekday of the week.
' 2000-09-07. Cactus Data ApS.
' 2003-05-01. System settings used as default.
' 2012-10-44. Data type of lngFirstDayOfWeek changed to VbDayOfWeek.
DateWeekFirst = DateAdd("d", vbSunday - Weekday(datDate, lngFirstDayOfWeek), datDate)
End Function
Public Function DateWeekLast( _
ByVal datDate As Date, _
Optional ByVal lngFirstDayOfWeek As Long = vbUseSystemDayOfWeek) _
As Date
' Returns the last date of the week of datDate.
' lngFirstDayOfWeek defines the first weekday of the week.
' 2000-09-07. Cactus Data ApS.
' 2003-05-01. System settings used as default.
' 2012-10-44. Data type of lngFirstDayOfWeek changed to VbDayOfWeek.
DateWeekLast = DateAdd("d", vbSaturday - Weekday(datDate, lngFirstDayOfWeek), datDate)
End Function

Macro running extremely slowly

I've been writing a macro which inserts a new row in a holiday sheet for a new recruit, now it was working fine, but now it has ground to a halt and takes a huge amount of time to insert a new row. Here is the affected code:
For f = 1 To Worksheets.Count - 1
Worksheets(f).Select
Range("A1").Select
If Worksheets(f).Name = "FLEXI" Then
Range("A1").Select
N = Range("A2").Value
Range("A" & NewRow).Select
Selection.EntireRow.Insert
Range("A" & NewRow + N + 1).Select
Selection.EntireRow.Insert
GoTo flexidivert
End If
Range("A" & NewRow).Select
Selection.EntireRow.Insert
flexidivert:
Next f
I have screenupdating disabled, enableevents disabled and calculations set to manual so the usual suspects aren't at work here. It's such a simple procedure as well, I can't understand why it takes minutes to compute. NewRow is the row to be pasted in and worksheets.count = 5 so there aren't a huge number to scroll through.
Further to my comments above, Is this what you are trying to do?
For f = 1 To Worksheets.Count - 1
With Worksheets(f)
.Range("A" & NewRow).EntireRow.Insert
If .Name = "FLEXI" Then
N = .Range("A2").Value
.Range("A" & NewRow + N + 1).EntireRow.Insert
End If
End With
Next f
I am assuming that you have declared all your variables correctly and Cell A2 has numberic values.
try the below
Worksheets("FLEXI").select
N = Range("A2").Value
Range("A" & NewRow).EntireRow.Insert shift:=xldown
Range("A" & NewRow + N + 1).EntireRow.Insert shift:=xldown
Range("A" & NewRow).EntireRow.Insert shift:=xldown
no need to select a cell before using INSERT
also, if you know the name of the woreksheet no need to loop, just reference it directly through the collection
HTH
Philip

ASP - Loop while eof or bof - Select random product from idproduct but skip empty ids

I am trying to display a random product image and description from the access database, so i am selecting the highest idproduct then randomising a number between 1 and %highestid%, this is what i have so far....
IF frontpage = 1 then
SQLSTR = "SELECT idproduct AS prodtot FROM products order by idproduct desc"
Set objRS = Server.CreateObject("ADODB.Recordset")
SET objrs = oconn.execute(SQLSTR)
' Check result
Response.Write objRS("prodtot")
' attach
ntop = objRS("prodtot")
Randomize
' Generate random value between 1 and nTop .
nRandom= Int((nTop * Rnd) + 1)
sqlstr = "select * from products where idProduct = " & nRandom
response.Write"<br /><br />" & (sqlstr) & "<br /><br />"
'SET rs = oConn.execute(randomprod)
SET rs = oconn.execute(SQLSTR)
pranproddesc = rs("description")
response.Write(pranproddesc)
pranprodimg = rs("smallImageUrl")
end if
So far so good! But i have a problem, over time products have come and gone and I have alot of gaps in the %idproduct%, ive tried loop while rs.eof but it doesn't seem to do anythimg usefull, if anything at all. Just to clarify I have idproduct 1, 2, 5, 10, 11, 12 etc etc, so when it randomises idproduct3 it all goes up the spout! Can anyone help?
Thank you in advance! :)
Do the following:
IF frontpage = 1 then
Set objRS = Server.CreateObject("ADODB.Recordset")
SET objrs = oconn.execute(SQLSTR)
sqlSTR = "SELECT TOP 1 * FROM products ORDER BY NEWID()"
response.Write"<br /><br />" & (sqlstr) & "<br /><br />"
SET rs = oconn.execute(SQLSTR)
pranproddesc = rs("description")
response.Write(pranproddesc)
pranprodimg = rs("smallImageUrl")
end if
That sql will work in SQL Server:
Look at this page for SQL to return a random row for other databases:
http://www.petefreitag.com/item/466.cfm
Thanks, btw, I learnt something new figuring this out.
Rather than select a random ProductId, select a random row index from the recordset. That way you only have to hit the database once as well :)

Resources