[solved]: Is it possible to group Report data?


Antonio Cambule

Hi there,

I've seen that it is possible to order data in report control.
I would need to group data, means i like to have a group header for every records that match that group.

Example: Group by Date

01-02-2017 (Header)
Record 1 (Row)
Record 3 (Row)
Record 6 (Row)

15-02-2017 (Header)
Record 2 (Row)
Record 5 (Row)
Record 9 (Row)

20-02-2017 (Header)
Record 4 (Row)
Record 7 (Row)
Record 8 (Row)

and so on

Is that somehow possible?

regards
Antonio

Edit: Solution

Here is an ready solution sample on how we can group records and show it in the report control with an group header.

Definition of Group:
1. Logical sorting. Means, first sort the data by a sort criteria
2. Show the sorted record under a given group name/description: Header

This sample:
Uses an usually german datestr DD.MM.YYYY as sort criteria. That means, that i had to convert it into something
sortable. For this there are some converting routines in the sample that first makes an JS-Date from the string, and
then casts the value into an number value that is used for the sorting.

Sorting: A bubblesort algorithm is used. See, that in the algorithm itself i have implemented the above described conversion
for the datestring before the comparing could be done.

The code is commented, so it shouldn't be too hard to customize for other needs.

The report control is not touched too much, just to check if a group header shall be shown.
The sorting and setting of group header is done completely with Javascript in the data array.

Sample Download


DecSoft

Hello Antonio,

I am not sure what to say, because I am not sure if can understand well. Certainly we can have one one header and footer per Report, then, probably this just "put down" your desire. However, what about to use more than one Report control? You know that we can use the Report's Data variable instead an URL, don't you? Then, we can prepare more than one "Data" variable for every Report. Please, let me know if this possbile approach sound too much stupid for your specific case or what.



Antonio Cambule

The Problem is, that i need as much headers as groups and that is variable, depending on the records in data.

The case is, i have a list of products with an expiration date, the groupfield is this date. I may have 2 products expiring tomorrow,
three in a week, 10 in two weeks... and so on.

I hope this is clearer?

Edit 1:

If grouping is not possible...

An other idea could be, that instead of grouping i use an filter mechanism. A select control with two pregiven filters:
default (today, tomorrow and the next day), only today, the rest of the select would be filled with the dates from the whole data (without today). Selecting one, filters the report to the given value, so that only records with that date are shown. That would be a possible
solution to show the data.


DecSoft

Hello Antonio,

I try here various possible approach in order to get your desired multiple headers, but none of them works like expected. Without the need to use a very custom control (made from HTML) I think another possible approach to take is to use CSS classes for certain records' rows, something that is possible using the record's IDs or "index", so maybe we can't create various headers but "simulates" it.

Please, take a look at this Report.zip sample and tell me what do you think about.



Antonio Cambule

Hi David,

the sample looks nice. I think it could be an solution. What i need in that case is the change of the record value in order to show the header or not. Here an Sample Code:

Is that possible to achieve? I think something about a Script Execution inside of the ng-if (like in the input ng-change="$parent.ReportCountChange(Record.ID)), where i can check the old record.expiration against current record expiration?


DecSoft

Hello Antonio,

Certainly we can use an app's function also for the "ng-if" attribute. That function must return true or false. Take a look at this modified Report.zip sample. The appear to work not very good (in terms of efficency) when debugging (too much console messages) but apparently works more or less good when the application is build (no debug code present). Take a look at that and tell me if they can be useful or not for your particular case.



Antonio Cambule

Yes, but the main problem here is...

while the report goes through the records, i need to know not only current record details, but also the previous one to check against them.
Is this possible?


DecSoft

Hello Antonio,

What we receive in the function is the record's index, so, certainly we can look for an "index - 1" record or "index + 1" record in the Report's Data variable.



Antonio Cambule

Hi David,

I'm quite there, just one last question to complete this functionality...

Is it possible to call existing functions with return result inside of other functions?

Example:


DecSoft

Hello Antonio,

I think that is possible in the "ng-if". If you want call to other function inside another also is possible, but you must use certain variable(s) to store the function's results, or use pure Javascript functions & Javascript code.



Antonio Cambule

I use this:

ReportIsGroupToday and ReportIsGroupTomorrow are also AB-Functions with Index Parameter and boolean return

But this doesn't work...


DecSoft

Hello Antonio,

Since you are using AB code, you must do something like this:

* I asume we set the "Result" variables in the function's code, so we can use it after call the function.

* When I said above we can use two functions in "ng-if" I refer to the Report's HTML code, not the AB code.



Antonio Cambule

Hi David,

i can not figure out why this does not work.

Here is an Screenshot of the Result it produces including some Console Warnings with the AB-Function Results.

This is the report html part:

This is one the "ReportIsGroupToday" Function:

Any Idea why the headers are still shown, even if the results are false?

regards
Antonio


DecSoft

Hello Antonio,

Maybe you can provide me with a little app sample? Because the above code appear good in principle. But anyway, where the Report's Data source is come? If you control that source, why don't place some other field in the records so we can know if they must be "marked" or not? I means our records can have a field like "Expired", and then we can work with that field in some manners, for example, by assigning a CSS class to the expired records.

In other words, my opinion is that maybe is better to do the apropiate calculations before data arrive to the Report control. So you can add one or more fields to every record in order to work with them. What do you think about?

P.S. I am not now in my PC but I want to prepare some sample around this as quickly as possible. I am not sure if the below code (placed in the Report's HTML property) can work because I can't try it right now, but they can looks very similar to the working code:



Antonio Cambule

Hi David,

here is an simple sample app that shows the problem.

Report Header 3 Sample.

Thanks
Antonio


DecSoft

Hello Antonio,

Thanks for the sample. I certainly run it but can't view nothing "particular"... the sample apparently works...on the other hand, please, take a look at this other sample that I prepare for you: Report.zip. They shown how we can use the values already set in the Report's Data variable. I honestly think that this can be the better approach, since we no need to perform calculations in the Report, but only look at the appropiate record's fields.



Antonio Cambule

Good Evening,

your example doesn't work for me. I do not need to highlight expired records but group records with the same expiration date, together under one header. When the expiration date is today or tomorrow than in the header there should stand "today" or "tomorrow" for all other records in their corresponding group header should stand the "expiration date".

The sample i sent you is nearly correct. The error there is, that even if the result of the AB-Functions produce the correct value true/false,
the headers are displayed despite their values. So it doesn't matter if they are true or false, they are always shown and that is wrong.

Can you follow me?

Edit:

I found the bugs in my sample and now it works like expected. I have uploaded the new sample to the same place, if you like to see it.
These were the bugs:

1. In AB-Functions using:

2. I thought [Result] inside of AB-Function was somekind of built-in variable like in delphi... I used it wrong,
because in an other Function i tried to read it using "FunctionNameResult" like you had written in one of your previous answers.
My mistake. Now I got it ;-)

Changing the above things made the trick.

Conclusion: It works. But you are right, in the debugger we can see that it runs through felt a thousand times. A better approach probably would be an special functionality inside of the report control, like you do with filter or sort.
But for now I'm happy with that.

Thank you David for your help and thoughts about this
regards
Antonio


DecSoft

Hello Antonio,

Glad to know you find something that works. About the Debugger console, certainly when build the application the debug information doesn't exists and the console messages are reduced or almost eliminated. However, I think we can't go so far than group the records by certain record's field, and then, "visualize" in some way that group using some background, color, etc., that is, using a bit of CSS.

Please take a look at this thread and note how I suggest to use certain "Description" field to do the job, then we can use such "Description" to place some "special row" in a Report, which maybe can be taken as a "group separator". That's the way in which I am thinking to do this from the principle: using record's fields instead of perform app's runtime calculations.



Antonio Cambule

Hi David,

as i don't know if you see edited posts....
I've edited my first post of the thread and uploaded the reworked sample.

I have now completely solved my problem.

I've taken your thoughts and made a new routine in Javascript without touching too much the report control.
The data gets sorted accordingly to the grouping and then i write some header property into the array for every first record of the grouped data. If an header exists, the report control shall show it using ng-if=".." but the calculations are made before and not in the report control anymore.

Thank for your help again, it's great what can be done with AB.

regards
Antonio


DecSoft

Hello to all,

Hi David,

as i don't know if you see edited posts....
I've edited my first post of the thread and uploaded the reworked sample.

I have now completely solved my problem.

I've taken your thoughts and made a new routine in Javascript without touching too much the report control.
The data gets sorted accordingly to the grouping and then i write some header property into the array for every first record of the grouped data. If an header exists, the report control shall show it using ng-if=".." but the calculations are made before and not in the report control anymore.

Thank for your help again, it's great what can be done with AB.

regards
Antonio

Sorry Antonio. It's good to know you solved the issue. Thanks for your own efforts. Please, just tell me if you have any further question.


Everybody can read the DecSoft support forum for learning purposes, however only DecSoft customers can post new threads. Purchase one or more licenses of some DecSoft products in order to give this and other benefits.

This website uses some useful cookies to store your preferences.

I agree. Hide this note. Give me more information.