I have flight data records for each user. The table below shows an example for one user id. I need to group by user_id (show only one row for each user_id) that has the latest flight_date.
When I added grouping by user_id, the result report displays the right flight date, but the rest of the fields come from the last row for each user (highlighted fields).How do I make it show the entire row with the latest date (4th row in my example)? Thank you!
If you only want to see the most recent record, per userID, based on the flightdate, there are a few options. The most efficient way is to use a custom SQL command, but Crystal can do it by retrieving all of the records, and then suppressing the records you don't want to see.
1.Group the report by USERID (Report > Group Expert > Add the USERID field to the group section)
2. Sort the records by FlightDate ( Report > Sort Expert > Add FlightDate and select Descending NOTE: if FlightDate is not a date, we will need to create a formula to convert it into a date first, otherwise Crystal will treat it as a string and 12/2015 will be higher than 1/2016 (for example)
3.Create a running total to count the number of records within each group (This is how we will tell Crystal to suppress the records we don't want)
--Right click "running Total" on the right hand side, select New. Name it whatever you want; under Field To Summarize add FlightDate, change summary to COUNT
Leave Evaluate as "For Each Record"
Under Reset, select On Change of Group and select the group for USERID
The report should look like this
In the Section Expert, select Details and click the formula button next to "Suppress"
Enter the formula {#RecountCount} > 1 (Or whatever name your running total has)
Now you should only see one record for each user
Related
I have a Dashboard with different visuals.
Data is made up of different values for insurance companies.
I want my slicers/filters to not filter all data, but to only highlight the chosen company.
For example, in my slicer I choose the insurance ABN.
Instead of showing me the value for ABN only in my visuals, I want all other values to still be visible and ABN's value to be highlighted in the visuals.
Does anyone know how to do this?
You can use conditional formatting to achieve this. Lets say that we will change the background color to "highlight" a row (or cells, to be precise).
First, we need a slicer, which will not filter our data. We can do this by duplicating our source table, removing the unnecessary columns and making sure there is no relationship between the source and the duplicate. So if we have a source table, named Table, like this:
Right click on it and select Duplicate:
Then right click the title of the column you want to keep and select Remove Other Columns to get a list of company names only (you may also remove the duplicates, but it's not required). Then in the model delete the relation between both tables:
Now you can place a table showing company name and sales from your data source, and a slicer for company name from the duplicate table. At this point selecting values in the slicer should not affect the table.
Now you need to capture the value of the slicer and use it in a measure, which will determine should current row be highlighted or not. You can use SELECTEDVALUE for that, but note that it will give you a value only if there is a one selected in the slicer. If you want to support highlighting of more than one company, it gets a bit more complicated.
Make a new measure in your source table, like this:
Measure = IF(HASONEVALUE('Table (2)'[Company name]);
IF(SELECTEDVALUE('Table (2)'[Company name]) = MAX('Table'[Company name]); 1; 0);
IF(ISFILTERED('Table (2)'[Company name]) && COUNTROWS(FILTER('Table (2)'; 'Table (2)'[Company name] = MAX('Table'[Company name]))); 1; 0))
In case there is only one value selected in the slicer (see HASONEVALUE), then our measure will return 1 (highlight) or 0 (don't), comparing it with the current row.
Otherwise (i.e. there is no selection in the slicer, or there are 2 or more companies selected), then we will look at the filtered list of companies (Table (2)) - if it contains current row, then 1 (highlight), otherwise 0 (don't). But we will also handle the case, where there is no value selected in the slicer. In this case the list will contain all the companies, i.e. all rows will be highlighted. Here comes ISFILTERED. And at the end, if the list is filtered and current row exists in the filtered list, then 1 (highlight), otherwise 0 (don't).
Now, you need to use this measure to change the background of the column - right click each column in your table and select Conditional formatting -> Background color:
Then format by rules, where Measure >= 1 like this:
Now, when there is no selection in the slicer, there are no rows highlighted in the table:
If you select one company, it is highlighted:
It also work if there are multiple companies selected:
Thank you Andrey for your step-by-step explanation which as been incredible helpful. I'd like to follow up with a further question, particularly regarding the comment below.
"You can use SELECTEDVALUE for that, but note that it will give you a
value only if there is a one selected in the slicer. If you want to
support highlighting of more than one company, it gets a bit more
complicated."
In my model, I've linked a third table (Table (3)) to Table (2) with a many to one relationship with Table (2). Therefore when I click on Table (3), it will filter Table (2), which acts as a slicer for Table (1).
When only 1 value is filtered in Table (2), it conditionally formats the cells in Table (1). However, when more than 1 value is filtered in Table (2), conditional formatting fails.
As I'm looking to avoid manually selecting multiple values in the slicer (Table (2)), I was wondering if there's a workaround for SELECTEDVALUE such that it is able to conditionally format when I filter more than 1 value in Table (2).
See image below. Warehouse and Customer are dropdown lists populated via query. Year is a text field. The two tables display data from datasets driven by the report parameters. Is there a way to repeat the two tables based on each member of the Customer dropdown? Preferbly with a pagebreak after the 2nd table.
I normally do this using subreports. You could either create a single subreport that contains both tables or individual subreports. The individual approach might help with page breaks etc so that's the way I'd go.
Step 1: Create a report for your first table.
As you don't state what each table does, I'll make some up for the sake of illustration.
The key is to create a subreport that displays just the info you need in a single table. So in your case this might mean we only need to pass in a single parameter, CustomerID. You might need to pass in more such as Warehouse but I don't know...
In my made up scenario, let's assume the report shows customer contacts so we create a subreport (let's call it subCustomerConacts). It has a single parameter pCustomerID and a single dataset dsCustomerContacts. The query might looks something like SELECT * FROM CustomerContacts WHERE CustomerID = #pCustomerID. Add whatever tables/textbox etc you need to display your data.
Test this subreport works by manually typing in a CustomerID
Step 2: Create a report for your second table.
Do exactly the same again, creating a new subreport. Let call this subCustomerOrders. Repeat as above until you end up with another report that can display order details (or whatever you need).
Finally, create you main report.
This is basically what you have described in you question in terms of parameters etc.
Now to add this bit that will call you subreports.
Create a dataset (let's call it dsCustomerLoop) that contains each customer from your parameter something like SELECT DISTINCT CustomerID FROM myCustomers WHERE CustomerID IN (#myCustomerParameter)
Add a table to your report, 1 column wide and stretch it so it's wide enough to accommodate you subreports.
Set the dataset to point to dsCustomerLoop
Right-Click the cell in the detail row and do "Insert Row -> Inside Group - Below". You should not have two detail rows.
Next, right click the top detail row and do "Insert -> Subreport"
Right-Click the newly inserted subreport control and choose "properties".
Choose your first SubReport form the drop-down list
Click parameters on the left,
Click "Add" and select the CusomterID parmeter, set it's value to the CustomerID field.
Repeat this process on the seconds row, choosing your seconds subreport.
You may want to also add a 3rd row to the table, you could insert a rectangle into this with page breaks set to force a new page after each seconds subreport.
That's It. When the report runs it will produce two rows per customer, each row containing a subreport.
I hope this is clear enough, I've rushed through it a bit but if anything is unclear, let me know and I'll provide a clearer solution.
I have looked through several of the posts on SSRS tablix expressions and I can't find the answer to my particular issue.
I have a dashboard I am creating that contains summary data for various managers. They are entering monthly summary data into a single table structured like this:
Create TABLE OperationMetrics
AS
Date date
Plant char(10)
Sales float
ReturnedProduct float
The data could use some grouping so I created a table for referencing which report group these metrics go into looks like this:
Create Table OperationsReport
as
ReportType varchar(50)
MetricType varchar(50)
In this table, 'Sales' and 'ReturnedProduct' are the Metric column, while 'ExecSummary' or 'Quality' are ReportType entries. To do the join, I decided to UNPIVOT the OperationMetrics table...
Select Date, Plant, Metric, MetricType
From (Select Date, Plant, Sales, ReturnedProduct From OperationMetrics)
UNPVIOT (Metric for MetricType in (Sales, ReturnedProduct) UnPvt
and join it to the OperationsReport table so I have grouped metrics.
Select Date, Plant, Metric, Rpt.MetricReport, MetricType
FROM OpMetrics_Unpivoted OpEx
INNER JOIN OperationsReport Rpt on OpEx.MetricType = Rpt.MetricType
(I understand that elements of this is not ideal but sometimes we are not in control of our destiny.)
This does not include the whole of the tables but you get the gist. So, they have a form they fill in the OperationMetrics table. I chose SSRS to display the output.
I created a tablix with the following configuration (I can't post images due to my rep...)
Date is the only column group, grouped on 'MMM-yy'
Parent Row Group is the ReportType
Child Row Group is the MetricType
Now, my problem is that some of the metrics are calculations of other metrics. For instance, 'Returned Product (% of Sales)' is not entered by the manager because it is assumed we can simply calculate that. It would be ReturnedProduct divided by Sales.
I attempted to calculate this by using a lookup function, as below:
Switch(Fields!FriendlyName.Value="Sales",SUM(Fields!Metric.Value),
Fields!FriendlyName.Value="ReturnedProduct",SUM(Fields!Metric.Value),
Fields!FriendlyName.Value="ReturnedProductPercent",Lookup("ReturnedProduct",
Fields!FriendlyName.Value,Fields!Metric.Value,"MetricDataSet")/
Lookup("Sales",Fields!FriendlyName.Value,Fields!Metric.Value,
"MetricDataSet"))
This works great! For the first month... but since Lookup looks for the first match, it just posts the same value for the rest of the months after.
I attempted to use this but it got me back to where I was at the beginning since the dataset does not have the value.
Any help with this would be well received. I would like to keep the rowgroup hierarchy.
It sounds like the LookUp is working for you but you just need to include the date to find the right month. LookUp will return the first match which is why it's only working on the first month.
What you can try is concatenating the Metric Name and Date fields in the LookUp.
Lookup("Sales" & CSTR(Fields!DATE.Value), Fields!FriendlyName.Value & CSTR(Fields!DATE.Value), Fields!Metric.Value, "MetricDataSet")
Let me know if I misunderstood the issue.
I have prompt for Fiscal Month in my Webi Report. I want to custom sort it so that the month starts with April, May, June , etc.
How is this possible?
Thanks
Niki
I tried many ways like adding LOVs and managing to sort the values at prompt, etc. But in BO 4.1, How we should do is,
1.Click on Parameters and List of Values.
In Edit SQL write the query with order by so that we get the order. for eg. select distinct fiscal_month,fiscal_month_number from calender_table order by fiscal_month_number.
Validate the query.
In Properties tab, check for hiding fiscal_month_number and give a appropriate name for fiscal_month column.
Now in Business Layer, select the dimension we created for fiscal_month, in Advanced Tab, add the List of Value that is created.
Thanks
Niki
I'm stuck and confused and hopefully can get some help here. I have a query that pulls info from two tables and a report that reads it. My two tables are as such: One of the is a Contact list with phone numbers, names, and addresses. The other table is a paid history. The PhoneNumber field is how they're tied together. There are no duplicate entries in the Contact table but there are multiple paid instances per phone number in the other table.
My report groups them on the phone number, but I also need it to sort by date. My date field is marked as time/date, and it is in the paid table. The issue I'm running into is that I can either Group on PhoneNumber OR sort on the Date field but not both. When I set the Group as the top level, it ignores the Sort that I have set below it. If I take the sort and drag it up so that it becomes the top level, it won't group. When it doesn't group I'm left with multiple instances of the same Contact info... as in I get a new listing for every date that it has ever paid, whereas I need one a single Contact listing with each paid instance to be grouped underneath it.
Here's my query SQL:
SELECT
tblContributorsLead.FirstName,
tblContributorsLead.LastName,
tblContributorsLead.Address1,
tblContributorsLead.ZipCode,
tblContributorsLead.CityName,
tblPledgesLead.PledgeAmountRecd,
tblPledgesLead.DateRecd,
tblPledgesLead.PhoneNumber,
tblPledgesLead.DispositionTime,
tblPledgesLead.Agent,
tblPledgesLead.CampaignName,
tblPledgesLead.Custom20
FROM
tblContributorsLead
INNER JOIN
tblPledgesLead
ON tblContributorsLead.PhoneNumber = tblPledgesLead.PhoneNumber
WHERE
(((tblPledgesLead.PledgeAmountRecd)>0)
AND ((tblPledgesLead.DateRecd) Is Not Null));
Why would I only be able to either group OR sort but not both at the same time?
Edit: http://icloudbackups.com/stripped.zip is a copy of my database stripped down.
I think I understand now what you wanted - to have the phone number groups with the most recent dates show up at the top. To do this you need to identify the Last (or First if you need it the other way around) DateRecd for each PhoneNumber.
SELECT SortingAndGrouping.LastDate, SortingAndGrouping.PhoneNumber, tblPledgesLead.DateRecd
FROM (tblContributorsLead INNER JOIN tblPledgesLead ON
tblContributorsLead.PhoneNumber = tblPledgesLead.PhoneNumber) INNER JOIN
(SELECT CDate(Format(tblPledgesLead.DateRecd,"MM/DD/YYYY")) As LastDate, tblPledgesLead.PhoneNumber
FROM tblContributorsLead INNER JOIN tblPledgesLead ON
tblContributorsLead.PhoneNumber = tblPledgesLead.PhoneNumber
ORDER BY tblPledgesLead.DateRecd DESC) AS SortingAndGrouping ON
tblContributorsLead.PhoneNumber = SortingAndGrouping.PhoneNumber
ORDER BY SortingAndGrouping.LastDate DESC , SortingAndGrouping.PhoneNumber, tblPledgesLead.DateRecd DESC;
You will need to add the additional fields you want to display (I removed them here for clarity), and have the report enforce the same sorting I have here - Create a group for the LastDate column, then a group for the PhoneNumber column, then have the sorting specified.