Fit page height with JasperReports detail band - jasper-reports

A report contains a unique central "Detail1" band that must fit the whole page height--even when the datasource provides just one record--the footer must remain at the bottom of the A4-sized page:
_______________
| header |
| |
| row1 |
| row2 |
| |
| |
| |
| |
| |
| footer |
|_______________|
YES!
_______________
| header |
| |
| row1 |
| row2 |
| footer |
|_______________|
NO!
I wonder whether this is related to the "stretching" options or to the background.

We also have this more general problem of vertically sizing some band or content relative to the page height.
In your case it could be done, e.g. by either increasing the row2 "bottom margin" or the footer "top margin" (or introducing some "spacer element" inbetween):
variant A variant B variant C
___________ __________ __________
| header | | header | | header |
|_________| |________| |________|
| row1 | | row1 | | row1 |
|_________| |________| |________|
| row2 | | row2 | | row2 |
| . | |________| |________|
| . | | . | | spacer |
|_________| | . | |________|
| footer | | footer | | footer |
|_________| |________| |________|
The only way I currently can think of to solve this, is kind of a hack, if "you know enough about the size of the to-be-streched element siblings":
We want to set the spacer.height (or margin depending on the variant chosen) like this:
spacer.height = page.height - header.height - row1.height - row2.height - footer.height
Example A
Let's assume for simplicity of this example that
only row2.height is flexible (~ dynamic)
for simplicity let's say row2.height is made of numbers separated by linefeeds like this:
17
2
34
Using variant A we could manually test, after how many linefeeds/numbers the footer would be pushed on the next page, let's say 5.
So all we would have to do is to
either dynamically adjust the bottom margin of row2 to max( 0, 5 - row2LinefeedsCount * row2lineHeight ) (e.g. via Groovy or Java)
or if it is based on some SQL select, fill in some blank space lines like this:
-- (Oracle SQL)
select
...,
dyn_row2_col
-- add additional linefeeds if necessary (when < 5 lines)
-- (counts by the content length after removing all digits)
|| lpad(
'',
max( 0, 5 - length( regexp_replace( dyn_row2_col, '\d', '' ))),
CHR(13) )
as dyn_row2_col,
...
from ...
Example B
Another example could be, that row2s height is dependent and linearly increased by the number of subrows of some query result (e.g. if it is a simple subreport with equally sized rows). Then we could maybe use variant C and fill the spacer (invisibly) with some dummy query based on the subrow query (and doing the calculation of the rest space similar to the above example).
search engine tags/phrases
fit band height to page size/height, band height 100% of page size, max-height, stretch vertically to 100% parent container height or page size
implementation/usage thoughts of Jasper Reports
I find it a pain to not be easily able to use flexible positioning/sizing expressions (e.g. to let the footer stick to the bottom, float elements horizontally (e.g. table columns) or spacer.height: 75%) with Jasper Reports in this modern flex layout HTML/responsive layout world. The absolut positioning philosophy should be enhanced here. Eclipse BIRT is much better at this, but has other disadvantages. Of course the implementation could be quite complex, more memory intense and slower, but I think the benefit in non-absolute positioning requirement scenarios would be great.
I wrote some general Scriptlet (I plan to provide in jasper-utils), which solves the floating of horizontal columns based on named component styles (similar to CSS classes) on related columns. It behaves very similar to HTML tables, using the available horizontal space based on column-specific percentage and "underflow-stretch-calc" expressions and the possiblity to show/hide columns (over all related bands).

Related

Excel: Select the newest date from a list that contains multiple rows with the same ID

In Excel, I have a list with multiple rows of the same ID (column A), each with various dates recorded (Column B). I need to extract one row for each ID that contains the newest date. See below for example:
|Column A | Column B|
|(ID) | (Date) |
|-----------|-----------|
|00001 | 01/01/2022|
|00001 | 02/01/2022|
|00001 | 03/01/2022| <-- I Need this one
|00002 | 01/02/2022|
|00002 | 02/02/2022|
|00002 | 03/02/2022| <-- I Need this one
|00003 | 01/03/2022|
|00003 | 02/03/2022|
|00003 | 03/03/2022| <-- I Need this one
|00004 | 01/04/2022|
|00004 | 02/04/2022|
|00004 | 03/04/2022| <-- I Need this one
|00005 | 01/05/2022|
|00005 | 02/05/2022|
|00005 | 03/05/2022| <-- I Need this one
I need to extract the above rows, where the row with the newest date is extracted for each unique ID. It needs to look like this:
|Column A | Column B |
|(ID) | (Date) |
|----------|--------------|
|00001 | 03/01/2022 |
|00002 | 03/02/2022 |
|00003 |03/03/2022 |
|00004 | 03/04/2022 |
|00005 | 03/05/2022 |
I'm totally stumped and I can't seem to find the right answer (probably because of how I'm wording the question!)
Thank you!
Google searches for the answer - no joy. I don't know where to start in excel with this function, I thought perhaps DISTINCT or similar...
Assuming you have Office 365 compatible version of Excel, you could do something like this:
(screenshot/here refers):
=INDEX(SORTBY(A2:B11,B2#,-1),SEQUENCE(1,1,1,1),SEQUENCE(1,2,1,1))
This formula is superfluous albeit convenient - you don't really require the first sequence (there's only one row being returned). However, as you can see in the screenshot, using the self-same formula, this time with a leading 2 in the first argument of that sequence returns the top two (descending order) dates, and so forth.
FOR THOSE w/ Office 365 you could do something like this....
=LARGE(B2#+(ROW(B2#)-ROW(B2))/1000,1)
i.e. adding a "little bit" to the dates that we can subtract later and use as a unique reference (row number, original unsorted list)
As mentioned, reverse engineer, throw into an index, and voila!
=INDEX(A2:A11,ROUND((H2-ROUND(H2,0))*1000,6))
caveats:
the round(<>,6) is purely to eliminate Excel's irritating lack of precision issue.
can work if you're looking up text strings (i.e. attempting to sort alphabetically) EXCEPT large doesn't work with string (no prob, just use unicode - but good luck with expanding out the string etc. ☺ with mid(<>,row(a1:offset(a1,len(<>)-1)..,1)..

Crystal 2008: Suppress record with multiple criteria

Crystal report looks like this:
No.| Name | Test - | Date
1 --| Fido - | yes -- | 1/2/2010
2 --| Rover | no --- | 1/2/2010
3 --| Fido - | yes -- | 1/2/2010
4 --| Fido - | yes -- | 1/8/2010
5 --| Rover | no --- | 1/8/2010
There are lots of observations with much duplication. Currently report suppresses records if duplicate in first column. Only records 1 and 2 would show up.
I need to be able to suppress records where both columns 1 and 3 are the same regardless of what is in column 2. In this case records 1,2,4,5 would all show up.
You can do this. try below way.
Create an array with the values first, For that purpose concatenate the required fields and create an array and select only those that are unique.
create a formula #finalvalues
Global Stringvar array mylist;
if Name&ToText(Date) in mylist
Then
1
else
mylist:=mylist+Name&ToText(Date);
0;
Now go to the supress part of the section where fields are placed and write below code.
if {#finalvalues}=1
then true
else false

How to automatically calculate the SUS Score for a given spreadsheet in LibreOffice Calc?

I have several spreadsheets for a SUS-Score usability test.
They have this form:
| Strongly disagree | | | | Strongly agree |
I think, that I would use this system often | x | | | | |
I found the system too complex | |x| | | |
(..) | | | | | x |
(...) | x | | | | |
To calculate the SUS-Score you have 3 rules:
Odd item: Pos - 1
Even item: 5 - Pos
Add Score, multiply by 2.5
So for the first entry (odd item) you have: Pos - 1 = 1 - 1 = 0
Second item (even): 5 - Pos = 5 - 2 = 3
Now I have several of those spreadsheets and want to calculate the SUS-Score automatically. I've changed the x to a 1 and tried to use IF(F5=1,5-1). But I would need an IF-condition for every column: =IF(F5=1;5-1;IF(E5=1;4-1;IF(D5=1;3-1;IF(C5=1;2-1;IF(B5=1;1-1))))), so is there an easier way to calculate the score, based on the position in the table?
I would use a helper table and then SUM() all the cells of the helper table and multiply by 2.5. This formula (modified as needed, see notes below) can start your helper table and be copy-pasted to fill out the entire table:
=IF(D2="x";IF(MOD(ROW();2)=1;5-D$1;D$1-1);"")
Here D is an answer column
Depending on what row (odd/even) your answers start you may need to change the =1 after the MOD function to =0
This assumes the position number is in row 1; if position numbers are in a different row change the number after the $ appropriately

Cognos Calculate Variance Crosstab (Dimensional)

This is very similar to Cognos Calculate Variance Crosstab (Relational), but my data source is dimensional.
I have a simple crosstab such as this:
| 04-13-2013 | 04-13-2014
---------------------------------------
Sold | 75 | 50
Purchased | 10 | 15
Repaired | 33 | 44
Filter: The user selects 1 date and then we include that date plus 1 year ago.
Dimension: The date is the day level in a YQMD Hierarchy.
Measures: We are showing various measures from a Measure Dimension.
Sold
Purchased
Repaired
Here is what is looks like in report studio:
| <#Day#> | <#Day#>
---------------------------------------
<#Sold#> | <#1234#> | <#1234#>
<#Purchased#> | <#1234#> | <#1234#>
<#Repaired#> | <#1234#> | <#1234#>
I want to be able to calculate the variance as a percentage between the two time periods for each measure like this.
| 04-13-2013 | 04-13-2014 | Var. %
-----------------------------------------------
Sold | 75 | 50 | -33%
Purchased | 10 | 15 | 50%
Repaired | 33 | 44 | 33%
I added a Query Expression to the right of the <#Day#> as shown below, but I cannot get the variance calculation to work.
| <#Day#> | <#Variance#>
---------------------------------------
<#Sold#> | <#1234#> | <#1234#>
<#Purchased#> | <#1234#> | <#1234#>
<#Repaired#> | <#1234#> | <#1234#>
These are the expressions I've tried and the results that I get:
An expression that is hard coded works, but only for that 1 measure:
total(case when [date] = 2014-04-13 then [Sold] end)
/
total(case when [date] = 2013-04-13 then [Sold] end)
-1
I thought CurrentMember and PrevMember might work, but it produces blank cells:
CurrentMember( [YQMD Hierarchy] )
/
prevMember(CurrentMember([YQMD Hierarchy]))
-1
I think it is because prevMember produces blank.
prevMember(CurrentMember([YQMD Hierarchy]))
Using only CurrentMember gives a total of both columns:
CurrentMember([YQMD Hierarchy])
What expression can I use to take advantage of my dimensional model and add a column with % variance?
These are the pages I used for research:
Variance reporting in Report Studio on Cognos 8.4?
Calculations that span dimensions - PDF
IBM Cognos 10 Report Studio: Creating Consumer-Friendly Reports
I hope there is a better way to do this. I finally found a resource that describes one approach to this problem. Using the tail and head functions, we can get to the first and last periods, and thereby calculate the % variance.
item(tail(members([Day])),0)
/
item(head(members([Day])),0)
-1
This idea came from IBM Cognos BI – Using Dimensional Functions to Determine Current Period.
Example 2 – Find Current Period by Filtering on Measure Data
If the OLAP or DMR data source has been populated with time periods into the future (e.g. end of year or future years), then the calculation of current period is more complicated. However, it can still be determined by finding the latest period that has data for a given measure.
item(tail(filter(members([sales_and_marketing].[Time].[Time].[Month]),
tuple([Revenue], currentMember([sales_and_marketing].[Time].[Time]))
is not null), 1), 0)

How to format background color of a cell which is under a group? - SSRS 2008 R2

I have the following matrix:
Design view
--------------------------
| OfficeSID | [Type] |
--------------------------
| [OfficeSid] | [Value] |
--------------------------
Preview
----------------------------
| OfficeSID | A | B |
----------------------------
| 1 | 1029 | 982 |
----------------------------
| 2 | 98 | 782 |
----------------------------
| 3 | 786 | 82 |
----------------------------
| 4 | 29 | 2 |
----------------------------
I want to format background color of the cells i.e 2nd row, 2nd column which is a value field. It is grouped under Type field.
The background color should be the following:
If value < 0 red
If value < 100 and > 0 Orange
If value >= 100 Green
I tried using expressions but it dint work.
This is a pretty common requirement... It sounds like you're trying to set the BackgroundColor property at the cell level, which is correct, so there's no reason it shouldn't be working.
What expression are you using? I'd use something like:
=Switch(Fields!Value.Value < 0, "Red"
, Fields!Value.Value > 0 and Fields!Value.Value < 100, "Orange"
, Fields!Value.Value >= 100, "Green")
Edit after comment:
Hmm, not sure what's going on with your report. I put together a basic example to match your results and it's working as expected.
Put together sample dataset:
Create matrix:
Expression for Value Text Box BackgroundColor property, literally copied and pasted from the answer above:
Final results, which looks like it's working as expected:
So I'm not sure what to suggest here... About the only thing I can think of is whether you have multiple values per OfficeSID/Type combination, in which case you'd need to use an aggregate in the expression, i.e. something like:
=Switch(Sum(Fields!Value.Value) < 0, "Red"
, Sum(Fields!Value.Value) > 0 and Fields!Value.Value < 100, "Orange"
, Sum(Fields!Value.Value) >= 100, "Green")
But other than that I guess you could either add the exact details of the data you're using, or start a new report from the ground up in the simplest way possible. This would show if you can get the background working in a new report with no other logic in place.