Crystal Reports, Link Subreport To Date Group - crystal-reports

I am trying to create a report to show our overall quality tending over time by month or quarter (over a span of several years). The main report will show all of our shipments over the specified time period grouped by month/quarter, and the sub report will show all returns entered during that month/quarter that result in scrap or rework.
The issue I am having is linking the sub report to the date group in the main report. After several attempts using different methods, the best I could do is show all returns within the date parameter in every group footer.
This is my first time posting, so I'm not sure what additional info will be needed to assist. Please let me know if there is more needed.
*Edit for additional info
I would like the subreport to show data for each month or quarter in the given time period. So if the date range of the report is for 1/1/2018 - 9/30/2018 and the data is grouped by month, I would like the subreport to show only the data from each month group. General layout below.
January
Shipments
Returns (subreport showing data for January)
February
Shipments
Returns (subreport showing data for February)
*Second edit to add screenshot and more info
I stripped all the parameters from the subreport because I couldn't get any of them to work. The only parameter on the main report is the Date Range that prompts users for a start and end date.
The main report has the shipments in the details section.
Current layout below. If I can get this current issue resolved, I will be adding values passed up from the subreport to calculate the quality rating for each month, then passing them back down to a second subreport to summarize and chart.
Quality Trend Layout
*Third edit for data source and example data
The main and subreports are pulled from tables in our company database.
SQL query used for the main report. Only the "Releases" table is used to show how many and when each part was shipped. DelType=0 is specifying a customer delivery. The date range is defined by a user entered parameter.
Main Report
SELECT
"Releases"."DateComplete",
"Releases"."DelType",
"Releases"."PartNo",
"Releases"."Qty",
"Releases"."JobNo",
"Releases"."PartDesc"
FROM "COMPANY"."dbo"."Releases" "Releases"
WHERE "Releases"."DelType"=0 AND
("Releases"."DateComplete">={ts '2018-01-01 00:00:00'} AND
"Releases"."DateComplete"<{ts '2018-10-01 00:00:00'})
I am trying to use CustReturn.DateEnt as the datetime link to Releases.DateComplete in the main report (not currently linked at a paramter because it didn't work), and only select records that are customer returns resulting in rework, scrap, sort, or repair.
Subreport
SELECT
"CustReturn"."DateEnt",
"CustReturn"."CustRMANo",
"CustReturnDet"."OrigJobNo",
"CustReturnDet"."PartNo",
"CustReturnDet"."QtyReturned",
"CustReturnDet"."QtyToRework",
"CustReturnDet"."QtyToRestock",
"NonConformance"."Disposition",
"NonConformance"."ReturnType",
"CustReturn"."IssueDate",
"NonConformance"."NonConfDate",
"CustReturnDet"."PartDesc"
FROM
("COMPANY"."dbo"."CustReturn" "CustReturn" INNER JOIN "COMPANY"."dbo"."CustReturnDet" "CustReturnDet" ON "CustReturn"."CustRMANo"="CustReturnDet"."CustRMANo")
LEFT OUTER JOIN "COMPANY"."dbo"."NonConformance" "NonConformance" ON "CustReturnDet"."NonConfNo"="NonConformance"."NonConfNo"
WHERE ("NonConformance"."Disposition"='REPAIR' OR
"NonConformance"."Disposition"='REWORK' OR
"NonConformance"."Disposition"='SCRAP' OR
"NonConformance"."Disposition"='SORT') AND
"NonConformance"."ReturnType"='CUSTOMER'
Quality Trend Example Data

First, I want to give a big thanks to Digital.Aaron. Your help in solving this is greatly appreciated.
Your answer was quite close to what I needed. I was still unable to get the subreport to show any data after adding the additional lines to the SQL statement, so I tried something a little different. I made the additional statements into formula fields.
Main Report Field
DATEADD("D", -1*(DATEPART("D",{Releases.DateComplete})-1),{Releases.DateComplete})
Subreport Field
DATEADD("D", -1*(DATEPART("D",{CustReturn.DateEnt})-1),{CustReturn.DateEnt})
I used these fields as the link between the main report and subreport, but still couldn't get the data to show. The issue turned out to be setting them as = to each other in the record select formula of the subreport. I named the formulas DatePeriod
Original Record Select
{#DatePeriod} = {?Pm-#DatePeriod}
Modified Record Select
{#DatePeriod} in Date({?Pm-#DatePeriod})
Once I made the change, everything fell into place.
Thanks again,
Jeff

So it looks like you're grouping on Releases.DateComplete. Let's assume this value is the same for all records associated with a given month. Let's also assume the following (simplified) sample data for Shipments:
ShipmentDate | PartNo | Qty | DateComplete
01/01/2018 | 0001 | 1 | 01/31/2018
01/05/2018 | 0031 | 10 | 01/31/2018
01/31/2018 | A314 | 4 | 01/31/2018
Your Returns data would then need to look something like this:
ReturnDate | PartNo | Qty | DateComplete
01/15/2018 | 0031 | 7 | 01/31/2018
Notice they both have a DateComplete column.
Now in your Crystal Report template, you'll use the DateComplete field from the main report results set as the input to your subreport parameter. Your design layout looks like it would be correct here, as you'll want the subreport to be called in the group footer.
EDIT: So it looks like DateComplete is not the same for all records in a given month. That's fine. We're going to add a column to both the main query and the subreport query that WILL be the same for all records in a given month, and that we can then use to link the records.
Your main query would become:
SELECT
Releases.DateComplete,
Releases.DelType,
Releases.PartNo,
Releases.Qty,
Releases.JobNo,
Releases.PartDesc,
DatePeriod = DATEADD(DAY, -1*(DATEPART(DAY,Releases.DateComplete)-1),Releases.DateComplete)
FROM COMPANY.dbo.Releases Releases
WHERE Releases.DelType=0
AND (Releases.DateComplete>={ts '2018-01-01 00:00:00'} AND Releases.DateComplete<{ts '2018-10-01 00:00:00'})
Your subreport query would then become:
SELECT
CustReturn.DateEnt,
CustReturn.CustRMANo,
CustReturnDet.OrigJobNo,
CustReturnDet.PartNo,
CustReturnDet.QtyReturned,
CustReturnDet.QtyToRework,
CustReturnDet.QtyToRestock,
NonConformance.Disposition,
NonConformance.ReturnType,
CustReturn.IssueDate,
NonConformance.NonConfDate,
CustReturnDet.PartDesc,
DatePeriod = DATEADD(DAY, -1*(DATEPART(DAY,CustReturn.DateEnt)-1),CustReturn.DateEnt)
FROM COMPANY.dbo.CustReturn CustReturn
INNER JOIN COMPANY.dbo.CustReturnDet CustReturnDet ON CustReturn.CustRMANo = CustReturnDet.CustRMANo
LEFT OUTER JOIN COMPANY.dbo.NonConformance NonConformance ON CustReturnDet.NonConfNo = NonConformance.NonConfNo
WHERE NonConformance.ReturnType='CUSTOMER'
AND (
NonConformance.Disposition='REPAIR'
OR NonConformance.Disposition='REWORK'
OR NonConformance.Disposition='SCRAP'
OR NonConformance.Disposition='SORT'
)
DatePeriod will always be the date of the first day of the month. Now we can use this as the Link field between the main report and the subreport. You could also consider making this the field that you Group on, instead of the month value.

Related

Crystal reports - Can't filter on custom formula number field

Crystal reports don't let me use a custom count formula field to filter which transactions to show in a manager report.
I'm creating a Crystal report that team leaders are supposed to take out to see on how many occasions their employees have reported in sick. A record is only supposed to show if that person has reported in sick 6 or more times the last 12 months.
The report shows a record (a page) for each employee belonging to the managers organisational unit. Below the employee information is a subreport where I show the transactions from the salary/time system. Using select expert, I have filtered out the transactions that is supposed to show. I have then created a database field that count which day was 12 months back from today, and filtered so that only the transactions falling into this period shows.
My last problem is that I only want to show the record that has a minimum of 6 such transactions during the period. I created a formula field named #Antal ("amount" in Swedish) that simply counts the distinct number of dates in the "from"-date for the salary transactions I'm showing (since a change of law 2019-01-01 we needed to create a new transaction type, so some of the occasions after 2019 may have two transactions referring to one sick leave, thus I'm counting the first day of the period instead), DistinctCount ({P_LSTAT.P_SXXX06})
Now, the subreport has a new column with Antal (amount) that counts the amount of the desired salary transaction. I then try to use the selection formula to only show records where {#Antal} >= 6 but I get the following error:
This formula cannot be used because it must be evaluated later
Is there any other (better) way of doing this, or am I simply missing something?
For your selection based on {#Antal} >= 6 you need to use the group selection formula, not the record selection formula. Record selection is used to select records which meet the criteria before reading in the data. Group selection is used to filter out entire groups of records based on summarised values, after the records have been read in and the summaries calculated - which sounds like exactly what you need here.
The value of a Formula Field is out of scope when the Select Expert is evaluated.
There is no process for calculating the value of a Formula Field before it is printed within the section of the report it is placed. The Select Expert is evaluated prior to any section of the report being printed, so at this time all Formula Fields are effectively Nothing.

DSUM function in crystal reports?

I am trying to convert an old Microsoft Access report into Crystal reports. I have everything working perfectly except for this last small detail. The Access report uses a DSUM function within an if statement for one of the fields on the report.
After much searching, I've determined that CR doesn't have anything similar.
Here's basically what I'm dealing with.
I have a proposal report. In the details of the report I print the qty, description, and a couple of price fields.
The data looks like something this:
Proposalnum Partitem RolltoItem Unitprice
18611.............1.......... NULL........0.00
18611.............2......... NULL.......17225.92
18611............3............ 2............156.90
18611............4............. 2............482.05
What I need to do is when I print a specific part, I need to query through the rest of the records to find the parts that have a matching number in the rolltoitem field and add the unitprice to the part I'm printing.
So in this example when I print partitem #2, I need to add the 156.90 and the 482.05 from parts 3 and 4 to the 17225.92 so I print a total of 17864.87.
Is there any way to do this?
As far as i know, there is no such function.
But I would try this.
The general idea is: group the data by ProposalNum and use a subreport to select the "children rows" and sum the "children prices".
Details:
Create an empty group section by PartItem.
If you want to show only items where RoolToItem is null, use a suppress function for this case.
In the details section, put a subreport. The data source of the subreport would be the same of the main report.
Change subreport links to select data in subreport based on fields: PartItem in the main report = RolltoItem in the subreport.
Pass other fields to the subreport without select data: ProposalNum, PartItem, UnitPrice. I think you need to create parameters in the subreports before doing that - example: ParentProposalNum, ParentPartItem, ParentUnitPrice.
Create a new formula: ParentUnitPrice + Sum ({YourDataSource.UnitPrice})
Put the formula in the subreport footer a long with the other fields. Maybe: ParentProposalNum, ParentPartItem, formula.
It is a theoretical solution. I hope it points out to the right direction.
If you are trying to sum the Unitprice column for all items that have the same value in Rolltoitem, you could do this with a SQL Expression Field. The code would look something like this. My Where clause may need tweaked though since I'm not sure what your database structure looks like.
(
Select Sum("YourDataBaseTableName"."Unitprice")
From YourDataBaseTableName
Where "YourDataBaseTableName"."Rolltoitem" = *currentRolltoitemValue*
)
Syntax can also vary for SQL Expression Fields based upon what type of database you are using. The syntax I provided is fairly general, but should work on SQL Server.
EDIT: Adding example with explanation of how it works.
Here is one of my SQL Expression Fields from a crystal report that prints a Bill of Lading for shipped goods.
(
Select Sum("SHIPMENTS"."PALLET_COUNT")
From SHIPMENTS
Where "SHIPMENTS"."BOL_ID" = "BOL"."ID"
)
In my database the BOL table is the starting point. A single BOL can contain 1 or more SHIPMENTS, and a single SHIPMENTS can contain one or more PRODUCTS.
Top level grouping is on BOL.ID. The PALLET_COUNT is found once and only once on each SHIPMENTS. I also had a sorting requirement for the data in the details section that prevented me from using a Running Total Field.
This allows a BOL with 2 SHIPMENTS that contains a total of 3 products to look like this:
BOL.ID SHIPMENTS.ID SHIPMENTS.BOL_ID PALLET_COUNT PRODUCT.ID
1 10 1 2 XXX
1 9 1 1 YYY
1 10 1 2 ZZZ
The correct PALLET_COUNT for this BOL should be 3, since PRODUCTS XXX and ZZZ are in the same SHIPMENTS and the PALLET_COUNT is duplicated because of its relationship to the PRODUCTS.

Crystal Report: Comparing 2 Years item performance based on QTY sold

I am new to crystal.
I have to show the top 217 items based on the quantities shipped in 2014 and side by side 2013.
Is there way to put in one report the data.
Item1 in 2103 may not be the same as 2014.
I get the data from invoice history detail table, and add the qty shipped from all item and then sort the top 217 items on basis of the sum.
I can have them in 2 reports or the previous year data from sub-report,but then the sub report data will appear as row after the current year. however how can I put them in 1 report side by side for a better comparison.
Thanks for your help
Steps:
Create a report that does what you want for a single year (say 2013)--you'll probably want to use a top-N grouping.
Create a second report, without a datasource
import the first report into the second one (call it 'year N-1'); don't link the sub-report to the main
import the first report into the second report a second time (call it 'year N'); don't link the sub-report to the main
edit the second sub-report and set the date to 2014
If you want the report to be more flexible, create a parameter in the main report (named 'year'). Link this parameter to each of the sub-reports, changing the respective, record-selection formulas to use the value to calculate the correct date ranges.

Create a chart using the records of certain type grouped by month, with a moving balance

I am trying to create a chart (bar or line) in crystal from one table in my database (Sage CRM).
The records are as follows
CustomerId Date Invoice Amount
1234 3/4/2013 Cust Invoice 3322.00
1234 3/4/2013 Payment 2445.00
1234 4/5/2013 A/c transaction 322.00
1234 5/6/2013 interest 32.00
1234 6/6/2013 payment 643.00
So I would like to have a report that meets the following criteria
Only records for the last 12 months grouped in month
Only invoice types of payment, invoice and interest
A moving balance that calculates all the invoice amounts ie
(when displaying the information for July 2012, the moving balance will be the total of all invoices prior to this date.
Without this field I can create the chart no problem using select expert but I am not sure now what to do)
Should I use a cross tab? if so how will I do the selection to only show the invoices I want and the the date range I want?
After spending almost a week on this problem, with a lot of help from an expert I have finally got a solution.
In order to create a amount that is the sum of all records for a company, month and invoice type since the beginning of time, while only displaying records for the last year, I have created a SQL command
Select
//All of the fields for the report,
movingBalance.Amount
from myInvoiceTable as mit
<join to any other tables for the report>
left join (
select customerID, sum(amount) as Amount
from myInvoiceTable
where Record_Type in ('Payment', 'Invoice','Interest')
and Date < {?Report Start Date}
group by customerID) movingBalance
on mit.customerID = movingBalance.customerID
where mit.RecordType in ('Payment', 'Invoice','Interest')
and mit.Date >= {?Report Start Date}
and mit.Date <= {?Report End Date}
There are a couple of tricks to using commands:
For performance reasons you generally want to include ALL of the data for the report in a single command. Avoid joining multiple commands or joining one or more tables to a command.
Filter the data in the command, NOT in the Select Expert in the report.
Create any parameters in the Command Editor, not in the main report. Parameters created in the report won't work in the Command Editor.
This has done the trick.
Create Date Parameters in the report to filter out the records at the time of fetching now when you run the report you have left with the data you need.
Now you can manuplate the data inside report using formula fields.
Accoding to me writing stored procedures is a bit hectic task as you can manuplate the data inside the report. I don't have any intentions to disrespect anyone opinions but frankly its my opinion.
In that case Rachsherry I would recommend the following.
For criteria parts 1 & 2 I think instead of using stored procs, it may be easier for you to use a formula.
For invoices right click the invoice field, then "Format Field" in the common tab next to the Suppress option there is a formula button, enter the following...
IF {YourInvoiceField} IN ["Payment", "Invoice", "Interest] THEN FALSE ELSE TRUE
For your date requirement you need to use a selection formula... The code for that should look something like this
{YourDateHere} > DateAdd ("yyyy", -1, CurrentDate) AND {YourDateHere} < CurrentDate
The above code basically looks at dates between the day the report is run, and exactly a year before.
For your moving balance, you should be able to achive that with the guide here
Edit - An alternative to this is to use parameter fields (Which I don't personally like) it just means having to input the parameters every time the report is refreshed, they are self explanatory but you can find a guide here

Crystal Reports: get access to linked elements in selection formula

I'm making a report using Crystal Reports 2008 and Peachtree database. Report should display customers who didn't place orders in a last 30 days. I already figured out how to link two tables in CR with left outer join. But I wasn't able to find how that linking can be used in formulas, such as selection formula. What I am trying to achieve is to get date of last placed order for current customer and use this information to determine if customer should be displayed or not.
What is the right approach to solving this problem?
Assuming your data is setup properly and adding 'customer' and 'last order date' to the details section shows you everything, then you can just add conditional formatting formula for the suppress property of the section when 'data date - last order date < 30', leaving you only showing records where last order date is more than 30 days.