![]() |
function for row number and/or conditional grouping
Hopefully the notes are self explanatory. This function will return a row number based on a PK or other unique field or a group number based on some grouping value such as an FK. Note the value does not have to be number, it could be a date, text or boolean.
It handles the situation where similar functions might recalculate when the user selects a row. It is also extremely fast when compared with sql equivalents. Just copy and paste the whole function into a standard module. Note the highlighted WHERE clause is required to initialise the collection. If not included you will get an error (one for each row) the first time you run it and subsequently an incorrect result. The function can only be used once in any query (including sub queries/referenced queries) otherwise you will get incorrect results. Similarly if you require two group numbers in a single query (e.g. a row number and a grouping based on an FK) you will need a copy of the function with a different name (Perhaps call one rowNumber?;)) Queries run consecutively should not be a problem so long as one query finishes before the next one starts. The query does not need to be sorted but obviously makes sense for grouping. The returned value can be selected and the column sorted - values are not recalculated unless a record is added or deleted and the recordset requeried. Some may see this as an advantage, others a disadvantage but it is what it is. Code:
Function GroupNumber(Optional v As Variant = -1) As Long |
Re: function for row number and/or conditional grouping
1 Attachment(s)
Hi CJL
Thanks for posting this code I did a quick check to compare the speed of the GroupNumber approach with the use of Serialize to obtain a rank order. Both were quick but in my limited testing Serialize was usually slightly faster e.g. qryY7ScAss1MarkGN - time = 0.1875s qryY7ScAss1MarkRANK - time = 0.1015625s and again... qryY7ScAss1MarkGN - time = 0.1328125s qryY7ScAss1MarkRANK - time = 0.1015625s but not always... qryY7ScAss1MarkGN - time = 0.1171875s qryY7ScAss1MarkRANK - time = 0.125s As you rightly point out it is a good idea to clear GroupNumber from memory. I got some peculiar results when I didn't do so Also, despite your very clear warnings, I forgot to add GroupNumber()=True in my first attempt. This resulted in the repeated errors you mentioned & I had to use the 3 fingered salute to escape. It would be good if this error could be handled to avoid this issue but I had no luck with doing this Haven't yet looked at the other uses of your code you mentioned but it certainly merits further consideration. I'd be interested in other members' experience with using this code |
Re: function for row number and/or conditional grouping
Quote:
I'll take a look at your serialise function. With regards group number I can see plenty of situations where could be useful - lists of invoices/lines, customers/invoices, products/transactions, products/versions, transactions by period to name but a few. |
Re: function for row number and/or conditional grouping
Had a look at the Serialise function- they are two different animals. Both are way better compared with using a subquery to provide a hierarchy.
But there are three differences I can see: 1. Serialise is based on a values within the data, GroupNumber is not. So the first row will always be 1, sort the data into a different order and the first row is still 1. 2. for the same reason, filter out some records and Serialise does not recalculate new values whilst with GroupNumber the row numbers are recalculated. 3. Where there are multiple values the same (e.g. FK or scores in the Serialise example), both Serialise and GroupNumber return the same value for each row - however for the next row after the group, serialise takes into account the number of rows in that group, whilst serialise returns +1 e.g. Serialise....GroupNumber 1...............1 2...............2 2...............2 2...............2 5...............3 6...............4 1 & 2 might produce the same results if Serialise could be based on a form recordset or clone - not tested and probably not what is required given what is identified in 3. For GroupNumber, you have a consistency of increment which is easier to code for highlighting groups. On performance, it may well be that a dictionary will be faster that a collection - I'll create a dictionary alternative for comparison. In conclusion, I believe these each serve different requirements as identified in point 3. |
Re: function for row number and/or conditional grouping
look at that I already posted similar code to help an OP in sept-2:
Code:
Public Function fncList(ByVal p_id As Long, ByVal p_max_rows As Integer) As Integer |
Re: function for row number and/or conditional grouping
3 Attachment(s)
Agree that GroupNumber & Serialize (US spelling!) provide slightly different functionality but a couple of extra points about Serialize
1. Serialize is based on the field specified. For example: Code:
PupilRank: Serialize("qryY7scAss1Marks","PupilID",[PupilID]) 2. It is also possible to sort by one field e.g. Mark & rank by another e.g. PupilID This results in unique rank values for each record even where the marks are equal 3. I'd never thought of using the rank order for conditional formatting but that also works using Serialize. Whether that's beneficial or a distraction may depend on the data and the formatting condition used. See attached screenshots and example app I'm certainly not saying one method is better than the other - both are useful. I've not tried arnel's code |
Re: function for row number and/or conditional grouping
@arnel - as you say similar.
You have an additional parameter in your function, but it doesn't appear to be populated when the function is called? How does that work? Doesn't it need to be Optional? |
Re: function for row number and/or conditional grouping
1 Attachment(s)
@Colin - I was think more like this attachment - not very pretty but you get the idea
|
Re: function for row number and/or conditional grouping
That's certainly better than my second (deliberately bad) example with the orange conditional formatting
Out of interest what did you use as your CF rule to get that effect? |
Re: function for row number and/or conditional grouping
per my original post
expression is ... [rank] mod 2 =0 where rank is the groupnumber field, and predicated on score |
Re: function for row number and/or conditional grouping
Thanks. I still had GroupNumber predicated on PupilID instead of Mark!
|
All times are GMT -8. The time now is 11:06 AM. |
Powered by vBulletin®
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
(c) copyright 2017 Access World