How to create a running total over pages? - sum

What I want to achieve is a cumulative subtotal on the bottom of each page.
On the first page the total for that page of a column (let’s call this column A ) would be displayed. On the second page the total of page one and page two for column A is displayed and so on until the last page on which the overall total is shown.
Can someone provide me with a way to achieve this?

To create accumulate sum's over page, columns, group's you can used the evaluationTime attribute on the textField
The setup is:
Create a variabile that calculates the value (in your case a sum on a field)
<variable name="mySumVar" class="java.lang.Double" calculation="Sum">
<variableExpression><![CDATA[$F{myFieldToSum}]]></variableExpression>
</variable>
Important do not set resetType on variabile, this would reset the value accordingly and instead we want a accumulative value
Now as report is running (detail band iterating) this variabile will have the current value (sum of fields iterated).
To display an accumulative value relative to page, group etc, we use a textField with relative evaluationTime (if on bottom of page for example in columnFooter if on top you can use columnHeader).
In your case you want accumulative on page so you set evaluationTime="Page"
<textField evaluationTime="Page">
<reportElement x="0" y="0" width="100" height="30" uuid="6736d772-987d-4ad0-af4c-9d19e631eb07"/>
<textFieldExpression><![CDATA[$V{mySumVar}]]></textFieldExpression>
</textField>

Related

How to increment variable to count headlines, titles?

I have a JasperReports template, where I need to count the headlines of different "detail bands".
Now, since the headlines can vary (some datasets can be empty and then the whole band is not rendered), I wanted to use a variable for that.
The build-in variables does not suite, since they don't have a "detail_band_count" or something.
Moreover there is not always a headline in one detail band, there can be 1 or 10 following detail bands, where band 2 - 10 shares the same headline declared in band 1.
However, I managed to create a variable in this manner; but it only counts the pages.
Is there a possibility to call the Variable Expression on Variable access? So it would always increment, as soon as I write $V{headline_COUNT}?
It's hard for me to see how you can use variables, you would probably need to restructure report, find a grouping strategy, since you need to set incrementType to one of the available values and you are correct you can't select "header line" or similar.
However, there is a workaround that you can use to count how many time a specific element is showed using the parameter map $P{REPORT_PARAMETERS_MAP}
Define your counting parameter with a default value (avoid it starting as null)
<parameter name="countReportElement" class="java.lang.Integer" isForPrompting="false">
<defaultValueExpression><![CDATA[0]]></defaultValueExpression>
</parameter>
Now on any text field or other element in the band you like to count, you can use a fake printWhenExpression, to increment this parameter
<reportElement x="0" y="262" width="320" height="25" uuid="8fa62997-ffa2-4777-923b-999d372ce09e">
<printWhenExpression><![CDATA[($P{REPORT_PARAMETERS_MAP}.put("countReportElement",((Integer)$P{REPORT_PARAMETERS_MAP}.get("countReportElement"))+1))!=null?true:false]]></printWhenExpression>
</reportElement>
Note the ternary operation will always evaluate true (since Map.put(K key, V value) will return previous object) and put into the parameter map the value incremented by one every time element is evaluated.
To display the value of your count you access the parameter map directly.
<textField>
<reportElement x="57" y="13" width="100" height="20" uuid="7ca30577-0ca9-47c2-91ae-c7002fbbfbf7"/>
<textFieldExpression><![CDATA[$P{REPORT_PARAMETERS_MAP}.get("countReportElement")]]></textFieldExpression>
</textField>
be sure to set evaluationTime as need in report.

Jasper Report How to print ReportElement on next page when it doesn't fit on the same page?

In my code I have large amount of data that is generated to a jasper report inside a subreport that's larger than one page.
When I print it an unwanted page break happens. One element is sometimes printed on the next page when it doesn't fit on the same page.
what I want to happen:
what happens instead:
here's my code:
<group name="ExampleGroup">
<groupExpression><![CDATA[null]]></groupExpression>
<groupHeader>
<band height="17" splitType="Stretch">
<subreport isUsingCache="true">
<reportElement key="subreport-1" positionType="Float" x="0" y="0" width="594" height="16" uuid="some uuid"/>
<parametersMapExpression><![CDATA[$P{REPORT_PARAMETERS_MAP}]]></parametersMapExpression>
<dataSourceExpression><![CDATA[$P{REPORT_PARAMETERS_MAP}.get("DataSource")]]></dataSourceExpression>
<subreportExpression><![CDATA[$P{REPORT_PARAMETERS_MAP}.get("Data")]]></subreportExpression>
</subreport>
</band>
</groupHeader>
<groupFooter>
<band splitType="Stretch"/>
</groupFooter>
</group>
I already tried to solve the problem by adding parameters, e.g. splitType="Prevent" or keepTogether="true" but both caused an empty page to happen. The parameters I found are only useful when the band should be printed on the same page. But in my case the generated reportElements shouldn't be splitted up. It's not about the group or the band! Because its content is anyway larger than one page. I didn't found anything about that topic.
Probably it would be helpful adding an expression like Group Expression? But I don't know what to add here to say that the row should be printed on the next page when there's not enough space left.
How could I solve that? I'm thankful for any suggestion.
I solved it by adding splitType="Prevent" to the band inside the detail that is called in the subreport.

JasperReports: using variable in variable's expression

I am using Jaspersoft Studio and am trying to set a variable to the value of another variable (well actually, I will need a sum of two variables in another variable)
So I have two variables, A and B. I need to put A in B. Whenever I use a textfield to output A, it works fine. If in the variable B, I put a ($V{A}), and I try to print B, I get a null.
Does anyone have a clue as to why this happens?
Report X contains subreport Y which returns a variable
<returnValue subreportVariable="EXPENDITURES_TOTAL_VAR" toVariable="EXPENDITURES_TOTAL_VAR" incrementerFactoryClass=""/>
(note the same variable name in both reports)
Report X then contains another variable
<variable name="STOTAL_VAR" class="java.lang.Double" calculation="Sum">
<variableExpression><![CDATA[$V{EXPENDITURES_TOTAL_VAR}]]></variableExpression>
</variable>
This WORKS:
<textField>
<reportElement x="120" y="1" width="70" height="30" uuid="f0e81b0f-ddd3-4f31-9711-cfdeb64f36b2"/>
<textFieldExpression><![CDATA[$V{EXPENDITURES_TOTAL_VAR}]]></textFieldExpression>
</textField>
This does not:
<textField>
<reportElement x="310" y="1" width="100" height="30" uuid="263973e7-33b1-4343-a76c-3edbe5506d66"/>
<textFieldExpression><![CDATA[$V{STOTAL_VAR}]]></textFieldExpression>
</textField>
As this is one of the first SO hits when searching for Jasper reports and use variable within other variable and this doesn't give any help - maybe this answer here can help others who search for an answer for how to use a variable within another variable in an iReport:
Taken from here: http://www.jasperassistant.com/docs/guide/ch06s08.html, the short answer is:
Yes you can use a variable within another variable within an iReport - but the variable which you want to use in the other variable must be declared first - so the sequence of the variable matters.
Hope this helps someone.

GridView-like page but with static groups and each group section will have a different layout

I would like to create a page a little like the Grouped Items Page inside the Contoso Cookbook application (if you have seen it). Basically, it's a GridView bound to a CollectionViewSource.
<CollectionViewSource
x:Name="groupedItemsViewSource"
Source="{Binding Groups}"
IsSourceGrouped="true"
ItemsPath="TopItems"
d:Source="{Binding AllGroups, Source={d:DesignInstance Type=data:SampleDataSource, IsDesignTimeCreatable=True}}"/>
The GridView appears to bind the Groups to the highest level of the CVS data source with the Source attribute and then binds each individual section with the ItemsPath attribute.
However, my page differs in that my groups are static, they are: Times, Categories, List. The first will have a listview, the second a grid of tiles and the third will be another listview.
Also, each group section itself has a different layout. It's not just repeating groups and repeating item-layouts. I was expecting to be able to define "static" groups and a layout for each group directly in the XAML and maybe even add test data to those elements, but it seems like GridView requires data binding, even if just to a dummy data source at design time.
So how would you do this? So essentially, it needs exactly the same horizontal scroll and wrapping as the GridView, but the groups have totally different layouts and each group should ideally be definable directly in the XAML?
I'm thinking of creating a normal grid enclosed in a scroll viewer... what do you think? What would you do?
In a GridView, groups can be assigned a GroupStyle like this:
<GridView.GroupStyle>
<GroupStyle HeaderTemplate="{StaticResource MyGroupHeaderTemplate}"
Panel="{StaticResource MyGroupItemsPanelTemplate}"
HidesIfEmpty="True" />
</GridView.GroupStyle>
Now, in your case each group will need its own GroupStyle.
So instead of using a ListView within each group in a GridView, you could:
Define 2 different group styles with header templates and the panel (ItemsPanelTemplate (MSDN)) that you want to use
Define a class that has your custom logic to select which group style to use for a group.(GroupStyleSelector)
Set the GroupStyleSelector property on the GridView in XAML
Define static groups in your view model to contain the data you want: (Times, Categories, List)
This can be accomplished with a DataTemplateSelector. You would have multiple groups, but within each group the items are styled differently. See this SO post for more help articles.

combo box selection property change

I am writing an installer for an application. As part of that I am required to get the country name the user selects. If the user selects United States, I want the value US in my program, i.e. 2 letter code.
Currently I implemented the combo box like this:
<Control Id="CountryList" Type="ComboBox" Sorted="yes" ComboList="yes" Property="COUNTRY" X="30" Y="118" Width="150" Height="15">
<ComboBox Property="COUNTRY">
<ListItem Value="United States" />
<ListItem Value="India" />
<ListItem Value="Australia" />
<ListItem Value="United Kingdom" />
</ComboBox>
</Control>
Can anyone please suggest me how to change the property COUNTRY to US or IN or UK etc. I mean 2 letter code.
Also I have to add all possible countries. Any better way to accomplish this?
Related to this, I want the first combobox to list all the countries. The second combobox can then show the states that belong to the country. :)
Use the Text attribute for a visible text, and Value attribute for the value to be put into the ComboBox property when the item is selected:
<Control Id="CountryList" Type="ComboBox" Sorted="yes" ComboList="yes" Property="COUNTRY" X="30" Y="118" Width="150" Height="15">
<ComboBox Property="COUNTRY">
<ListItem Text="United States" Value="US" />
<ListItem Text="United Kingdom" Value="UK" />
...
</ComboBox>
</Control>
As for your other questions:
Also I have to add all possible countries. Any better way to
accomplish this?
You can take inspiration from this thread and add a build-time step to generate an XML fragment of <ListItem> elements.
The second combobox can then show the states that belong to the
country.
Note that there's no way to catch the event when a selected item is changed in a combobox. That's a well-known limitation of the MSI UI. You can try to achieve what you want with the workaround I call "twin-dialogs". See this thread for more information.