So, our branches are wanting shipping labels created which I have created a template on Crystal reports.
Our issue is using the NofM function. If the user prints one label it will say 1of1 which is correct. We want it so the counter is determined by the number of prints they require for example:
If the user prints 4 pages it will be 1of4 to 4of4.
Any assistance would be appreciated
In Field Explorer, expand 'Special Fields'.
Use the 'Page N of M' special field.
It sounds like you need a solution to duplicate the printing copies based on a parameter.
Option 1. if the max expected quantity is not too large, you can create multiple sections (Details a, Details b, Details c, ...) and use a dynamic suppress condition to hide the sections beyond the quantity parameter.
Option 2. Create a "REPEATER" table with a single column (How_Many) and rows for 1 | 2 | 3 | 4 | 5 | 6 | ...
Now, in your report, add the REPEATER Table and add a Record Selection condition of
{?QTY} >= {Repeater.How_Many}
Related
I am adept in both SQL and CR, but this is something I've never had to do.
In CR, I load a table that will always contain 1 record. There is a range of columns (like Column1, Column2 ... Column60). (bad design, I know, but I can't do anything to change that).
Thanks to this old design I have to manually add each column in my report like this:
-----------
| TABLE |
-----------
| Column1 |
| Column2 |
| Column3 |
| ... |
-----------
Now I would like to be able to create a subreport and create a datasource for it in such a way that [Column1...Column60] becomes a collection [Row1...Row60]. I want to be able to use the detailsection of the subreport to dynamically generate the table. That would save me a lot of time.
Is there any way to do that? Maybe a different approach to what I had in mind?
Edit
#Siva: I'll describe it the best way I can. The table exists out of 500+ columns and will only hold 1 record (never more). Because normalization was never taken into account when creating these tables (Objective C / DBF ages) columns like these: Brand01,Brand02,Brand03...Brand60 should have been placed in a separate table named "Brands"
The document itself is pretty straight forward considering there's only one record. But some columns have to be pivoted (stacked vertically) and placed in a table layout on the document which is a lot of work if you have to do it manually. That's why I wanted to feed a range of columns into my subreport so I can use the detail section of my subreport to generate the table layout automatically.
Ok got it... I will try to answer to the extent possible...
you need to have 2 columns in report that will show the 60 column names as 60 rows as 1st column and 60 column data as 2nd column. For this there are two ways that I can think of.
if columns are static and report need to be developed only once then though its a tough job manually create 120 formulas 60 for row names where you will write column names and 60 for data for respective columns and place in report since you have only one record you will get correct data. Like below:
formula 1:
column1 name // write manually
Formula 1:
databasefield for column1 // this has data for column1
Above will be one row in report like this you will get 120 formulas 60 rows and you don't need sub report here main report will do the job.
Since you are expecting dynamic behavior (Though columns are static), you can create view from database perspective or datatable (Please note I have no idea on datatable use it as per your convinience).
Create in such a way that it has 2 columns in table and in report use cross tab that will give you dynamic behaviour.
In cross tab column1 will be rows part and column 2 will be data.
Here also I don't see any requirement for sub report you can directly use main report. If you want sub report you can use aswell no harm since you have only 1 record
I have a report that is only one record, however, the user specifies how many times it needs printed, let's say 10. Each time it prints it prints 4 of the same report. Like this, Page 1 x 4, Page 2 x 4, Page 3 x 4, etc. With 10 copes their will be 40 pages altogether.
Update:
I was able to get all the pages I needed based on the values the user inputs. So if there are 10 pallets I have 40 pages of labels, which is correct. Now the control number part that needs to be displayed. It is kind of like a page number but every 4 pages the number needs to increment by 1. I assume I can use WhilePrinterRecords and some how increment, but I am still new to Crystal and unfamiliar with it.
Example:
Page 1: Control number 1
Page 2: Control number 1
Page 3: Control number 1
Page 4: Control number 1
Page 5: Control number 2
Page 6: Control number 2
Page 7: Control number 2
Page 8: Control number 2
This would continue until there is no more pages to print.
if you want 4 copies for each label, what you could do is create 4 sections on the report with the same info. Make sure that you assign the label size to each page(e.g. 4x6). e.g. if you have that info on your header, create PHa, PHb, PHc and PHd, same for details or PF.
don't know if this could work for you, but at least is a recommendation. You can create suppressed sections with the same info(e.g. 10 sections) and create a parameter that control that suppress condition defaulted in 4. If the user what to print 5, it will enable section 5th, same if want to print 3 it will suppress the 4th.
Upadte: how to get the increment:
place a formula on your page footer like below one. It will return value when gets an integer and suppress it when is equal to 0(right click on it, number tab, customize, suppress if 0).
if pagenumber = Ceiling(pageNumber,4) then numbervar page := page +1
then place another formula on your PF as well like below one and suppress it when pagenumber = Ceiling(pageNumber,4) so it won't show when the other has value and put one overlapping the other to get the value in the same place.
if {1st formula} <> 0 then numbervar page1 := {1st formula};
page1 + 1
2nd Update:
Because is a label and your details are acting as a new page do this:
create a new detail section, so you will have details a and b and place your formulas on details b
I have used additional tables for such tricks; these tables must be linked to report to multiply main query results. Some care has to be taken to not allow multiple users printouts to mix.
Example, assuming your report query has some unique id to link and your user/session has also some unique id:
you create table cr_special(reportid int, userid int, ctlnumber int)
you design report, linked to this table by reportid and filtered by userid; changing ctlnumber field is taken from your special table
before printing, you delete all records with reportid/userid combo and insert new ones
you print report, giving userid as parameter
Say you want to print 10 reports with increasing numbers - then you insert 10 records into your special table with ctlnumber increasing from 1 to 10.
Variation of this solution is to use some other non-related table, like our all-dates-containing dates table :)
Both of these solutions are ugly, but they usually work.
Another approach is to use some stored procedure to return these sequential numbers as records and link your report to such procedure; Crystal Reports and stored procedures do not behave always well however.
I'm trying to modify a report created in Crystal Reports 7 (which I know almost nothing about). I want to use a CrossTab, as this seems to be the best way to accomplish what I want. I have a column with three possible values: A, B, C. The cross tab creates three columns. I want to suppress C. How can I do this?
Also, is there anyway to create rows based on one field (i.e. a PK value), but display another - like a description? For example, if a list of states have a PK value of 1-50, I want them ordered by PK, but I want to display the state name.
All you ask is possible;
i suggest not to use cross tab: cross tab is intended for an uknown number of rows and columns (varying on data) ad for summarizing (max value, sum of values) results on a grid.
you should, instead:
Create a blank report
Drop the fields from the Field explrorer into the Details Section (just A and B columns)
Use Report Sort Expert to sort elements no the PK value
I have a report which displays information by group; I'd like to not show any group that doesn't have at least two items in it. Is there an easy way to do this?
Example:
Bob
3/1
4/3
Joe
3/2
3/7
3/9
Mark
5/9
James
John
8/17
9/2
Grouped on name, should not show Mark or James.
If your report is simplistic enough, you can get away with just suppressing the Group Header, Group Footer, and Details sections by using a summary function like count({table.somedate},{table.dudesname}) < 2. Note that the second parameter to a summary function has to be a field being used to group on.
Your mileage may vary with doing it this way. If you are displaying calculated summaries in the report footer, for example, it won't make sense to just suppress these groups as their data will still affect any report-level summary. The other problem you might run into is needing to use a distinct count on some field instead of just a count, depending on your table joins.
You could create a group-selection formula (Report | Selection Formula | Group...):
Count({table.field_to_count}, {table.grouped_field}) < 2
I want to create multiple groups in ireport, and the data should display in a group-wise manner.For Eg:
First the Group1 data should be printed completely, then,
Group1:
Module Data
After this i want to print the Group2 data completely
Group2:
Category data
I am using the Result Set datasource.
Can Someone help me in this?
Jasper reports will work exactly in this manner as long as your query results are ordered properly.
For example, let's say you are grouping by a field called "MY_GROUP" and it has values "GROUP A" and "GROUP B". In your report you will create a group for field "MY_GROUP". In your query, make sure you have MY_GROUP as the first field in your ORDER BY clause. You can also accomplish this in iReports by adding the "MY_GROUP" field as your the first field in the Sort Options section of the Report query.
Now that you have added your group and are ordering properly your results will come out like this:
Header - GROUP A
Detail - GROUP A
Footer - GROUP A
Header - GROUP B
Detail - GROUP B
Footer - GROUP B
Exactly as you wish. My guess is that you were not properly ordering your query results. This could result in having multiple groupings for GROUP A, GROUP B, etc. all interspersed.
If groups in iReport don't keep all the data together, use subreports. When Jasper gets to a subreport, it runs the whole subreport and puts the whole thing into the report. You could have something like:
Subreport 1 - Group 1
Group 1 first record
Group 1 second record
Group 1 third record
...
Group 1 last record
Subreport 2 - Group 2
Group 2 first record
Group 2 second record
Group 2 third record
...
Group 2 third record
It's exactly as Tom said. Jasper Reports Groups do not order the data retrieved from the query, they just take it in the order it comes.
In order to display the information in a group-wise manner, you have to add an ORDER BY to the query so the rows the report receives are already ordered.
So there is an issue that happens when you use multiple group headers. The first header behaves like expected ordered by Column Value A only on unique values. The 2nd header using Column Value B will print on every row despite being non-unique values.
In theory you should be able to use ORDER BY:
ORDER BY ValueA, ValueB
to properly display the report assuming you are using sql, plsql, etc... However, in my case that did not happen, though for others it seems to work.
Use subreports to attach the minor differences via unique reports. You create a root report with empty details. Then you create Unique reports to serve as sub reprots. Finally, you use the subreport element to link the values into the root report. Though that is a good bit of work and may cause repeat code.
A hacky way I used was: A mixture of "Print When Expressions" with logical boolean expressions with 2 group headers and a column header.
Boolean Expressions:
$F{QUERY}.equals(Query1) && ($P{P_Typequery}.equalsIgnoreCase("QueryA") && $P{P_parameter} == null)
and
$F{QUERY}.equals(Query1) && ($P{P_Typequery}.equalsIgnoreCase("P_QueryA") && $P{P_parameter} != null)
with two group headers and a column header. The column header will not repeat for every row so you assign one of the booleans expressions to it's "print when" so it does not always print. The first group header will not repeat for every row and works. The 2nd group header is used for the times you DO want it to repeat for every unique value since it always prints for every row, and you use the other boolean on it's "print when". Hope it helps