I have not found a suitable answer to my following problem after much searching.
I have a summary report which shows the total number of appointments by month grouped by specialty name and diagnosis.
Specialty_Name Diagnosis Code Feb Mar Apr
Neurology G35X 0 3 4
G379 8 5 7
Total For Spec 8 8 11
Rheumatology H051 4 9 2
M059 6 10 3
Total For Spec 10 19 5
When I click on the field (ie 11 for Neurology Total For Spec, Apr), which is =COUNT((Fields!Appointment_ID.Value), I want to pass each of the Appointment_IDs to a sub query as the parameter to display the associated client details. However, when I prepare the sub query and drill down report in a manner that I have used before I am only getting the result of the first Appointment_ID; not each one.
The sub query report is set up with the parameter #Appointment_ID VARCHAR(MAX) and a WHERE clause:
CAST(App.App_ID AS VARCHAR(MAX)) in (
SELECT * FROM Serve1.dbo.CreateParameterTable(#Appointment_ID,',')
)
The CreateParameterTable is a function on our server which should handle the string from the summary report and does so on other reports.
(
#StringInput NVARCHAR(MAX)
, #SplitBy NCHAR(1)
)
RETURNS #OutputTable TABLE ( [String] NVARCHAR(36) )
AS
BEGIN
DECLARE #String NVARCHAR(36)
WHILE LEN(#StringInput) > 0
BEGIN
SET #String = LEFT(#StringInput,
ISNULL(NULLIF(CHARINDEX(#SplitBy, #StringInput) - 1,
-1), LEN(#StringInput)))
SET #StringInput = SUBSTRING(#StringInput,
ISNULL(NULLIF(CHARINDEX(#SplitBy, #StringInput),
0), LEN(#StringInput))
+ 1, LEN(#StringInput))
INSERT INTO #OutputTable ( [String] )
VALUES ( #String )
END
If I manually type in multiple Appointment_IDs to my drill down report I get the expected result. Therefore it appears that either my Summary Report is not passing out a string or it is not being handled correctly by the function or the sub report does not like the output of the function Which as I have said works on other reports we have written. I'm stumped.
How to begin troubleshooting your specific problem
Because you've said you can get the subreport working by supplying a string of values as desired, then it appears the problem is with the report providing the delimited string. Before you can fix the issue, you need to see the delimited string being passed to the subreport - so add it to the tablix. Use the same function you're using to reference the value in the "Go to Report" action and add it as a tooltip to each count. That way you can see the string being prepared and tweak your logic until it comes out correctly.
How I would solve your problem
What you're trying to accomplish as a multi-valued parameter is, as I see it, unnecessarily complicated.
In your tablix, you have a set way of organizing the results. You have specialty name, diagnosis, and month (presumably of the diagnosis or date served).
That's three parameters you can pass through to a sub-report. Using similar sql logic as exists in your main report, you can isolate those 11 simply by knowing the values of those three fields plus the year. Obviously, you will need to do some work to find diagnosis/service dates that fall into a given month, but that's not too hard:
Where Month(Date_of_Service) = #Month
and Year(Date_of_Service) = #Year
and Specialty_Name = #Specialty
and Diagnosis_Code = #Diagnosis
Related
I have a report that uses a simple bit of SQL
SELECT
[User Name]
,[Activity]
,(cast(LTRIM(DATEDIFF(SECOND, 0, left(cast(([Activity End Time]-[Activity Start Time])as time),8)))as int)) as [seconds difference]
FROM [iPR].[dbo].[TimeRecordingStatus]
where [Activity Start Time] between #StartDate AND #EndDate
This produces a matrix report that looks like this. I have used "Name" as the group name grouping on [User_Name].
I am trying to enumerate the rows in the "Name" group so that I can alternate colours to make it a bit easier to read. The expression I used in the Rownumber column is
=rownumber("Name")
I am expecting to see an ordered list from 1 to x but instead I get this. Which I can't even begin to parse why it would be in this order? Why 7 then 14 then 7? Any ideas what I'm doing wrong? The group has no filters just Group on [User_Name] and Sort By [User_Name] a to z.
You cannot use RowNumber as this looks at the dataset rather than what is displayed. What you actually need to do is get the number of unique ItemID's on or before each group.
=RunningValue(Fields!ItemId.Value,CountDistinct, "DataSet1")
Here is one of my example
docs for ref https://learn.microsoft.com/en-us/sql/reporting-services/report-design/report-builder-functions-runningvalue-function?view=sql-server-2017
I have a data set like that:
Data Set Contents
From To Comment
----+---+--------
0 50 Bad
50 70 Good
70 100 Excellent
If I have a value of 75, I need to get Excellent by searching the Dataset.
I know about the lookup function but it is not what I want. How can I do that?
The values should be in percentage.
Note : the value (75) is Average of a column (Calculated) it
calculate student grade from max and student mark Version SQL Server
2016
Note 2 : the dataset is from database not static values
Thank You
Assuming you only ever have a fixed number of 'grades' then this will work. However, I would strongly recommend doing this type of work on the server where possible.
Here we go...
I created two datasets
dsGradeRange with the following sql to recreate your example (more or less)
DECLARE #t TABLE (low int, high int, comment varchar(20))
INSERT INTO #t VALUES
(0,49,'Bad'),
(50,69,'Good'),
(70,100, 'Excellent')
SELECT * FROM #t
dsRandomNumbers This just creates 30 random numbers between 0 and 100
SELECT *
FROM (SELECT top 30 ABS(CHECKSUM(NEWID()) % 100) as myNumber FROM sys.objects) x
ORDER BY myNumber
I added a table to the report to show the grades (just for reference).
I then added a table to show the dsRandomNumbers
Finally I set the expression of the 2nd column to the following expression.
=SWITCH
(
Fields!myNumber.Value < LOOKUP("Bad", Fields!comment.Value, Fields!high.Value, "dsGradeRange"), "Bad",
Fields!myNumber.Value < LOOKUP("Good", Fields!comment.Value, Fields!high.Value, "dsGradeRange"), "Good",
True, "Excellent"
)
This gives the following results
As you can see we only need to compare to the high value of each case, the first match will return the correct comment.
Right click on your dataset and add a calculated field. Go to Field Properties > Fields > Add and add the following expression, which descripes your scenario:
=IIF(Fields!Number.Value < 50, "Bad", "Good")
I am working on a macro in MS-Access which does some check on different Values in Form.
Here are the details of what i'm trying to do:
Form : Form is created based on a Table present in database and the structure of the same is like
DataType CalcType Percent1 Percent2 Percent3 percent_check
DT1 Avg 20 30 50 100
DT2 Mean 30 33 35 98
DT3 Sum 10 35 57 102
Column CalcType is a dropdown with three options. Each option would invoke different Macro written for it's calculation.
I have added a separate Field percent_check to validate the sum of P1, P2 & P3.
Requirement:
I want to write a condition that
IF DataType is DT1
THEN IF percent_check<=100
THEN IF CalcType = "Avg" Invoke Avg_Macro
ELSE IF CalcType = "Mean" Invoke Mean_Macro
ELSE Invoke Sum_Macro
ELSE Message(Adjust the percent to make total as 100)
similarly for the rest of the data types.
I have written the cases in Expression Builder
IF Form!DataType = DT1 THEN
IF Form!percent_check <=100 THEN
IF Form!CalcType = Avg THEN RunMacro - Avg_Macro
ELSE IF Form!CalcType = Mean THEN RunMacro - Mean_Macro
ELSE RunMacro - Sum_Macro
ELSE MessageBox("Adjust percent to make total <=100)
But i am neither getting any results nor any error message.
Could anyone please help me in writing this expression for getting the required results.
Thanks!!
Use VBA and rewrite the macro's into VBA too.
Here is a simple mdx query to MS OLAP cube, which outputs sale step stats for 3 cities with ranking of each sale stage, it works fine:
WITH
MEMBER [Measures].[rank] AS
case [Sales_step].currentmember.member_caption
when 'Contacts' then 1
when 'Clients' then 2
when 'Funded' then 3
else 0 end
SELECT {[Measures].[rank],
[Measures].[qnt]} ON COLUMNS,
NON EMPTY
crossjoin({[City].CHILDREN},
{[Sales_step].CHILDREN}) ON ROWS
FROM ( SELECT ( STRTOSET(#[Sales_step], CONSTRAINED) ) ON COLUMNS
FROM [SALES_PIPE])
The output is:
Now I want to build totals for each city without separate sale steps, but showing maximum archived sales stage rank only. The result must be:
I tried the following code to do that:
WITH
MEMBER [Measures].[rank max] AS
case [Sales_step].currentmember.member_caption
when 'Contacts' then 1
when 'Clients' then 2
when 'Funded' then 3
else 0 end
SELECT {[Measures].[rank max],
[Measures].[qnt]} ON COLUMNS,
NON EMPTY [City].CHILDREN ON ROWS
FROM ( SELECT ( STRTOSET(#[Sales_step], CONSTRAINED) ) ON COLUMNS
FROM [SALES_PIPE])
It does not generate error, but returns null values for calculated member [Measures].[rank max]:
It works only when I pass one value to #[Sales_step] parameter. While I need a multivalued param run. When I changed this snippet in case clause:
case [Sales_step].currentmember.member_caption
to:
case strtomember(#[Sales_step]).member_caption
it throwed an error "The STRTOMEMBER function expects a member expression for the 1 argument. A tuple set expression was used". Errors fire both for one- and multy-param when I use this too:
case strtoset(#[Sales_step]).currentmember.member_caption
How do I need to modify calculated member [Measures].[rank max] to get desired result with maximum rank for passed #[Sales_step] multivalue param?
I wonder if something like this works:
WITH
SET [S] AS
NonEmpty(
EXISTING [Sales_step].CHILDREN,
([City].CURRENTMEMBER, [Measures].[qnt]) //<<I think that [City].CURRENTMEMBER is probably redundant in this tuple
)
MEMBER [Mx] AS
CASE
WHEN INTERSECT([S], {[Sales_step].[Funded]}).COUNT = 1 THEN 3
WHEN INTERSECT([S], {[Sales_step].[Clients]}).COUNT = 1 THEN 2
WHEN INTERSECT([S], {[Sales_step].[Contacts]}).COUNT = 1 THEN 1
END
...
...
I'm brand new to MDX and need some help. In SSRS I have a dataset that pulls from an SSAS cube. The dataset always contains six months of data. What I need to be able to do is to compare a value for the max(timeID) with a value for the second max(timeID) and if the value for the max(timeID) > value for the second max(timeID) than the arrow goes up in the indicator, etc...
So for the dataset below I would subtract 20130201's Value which is 8 from
20130301's Value which is 10. The result would be a positive number and the indicator would be an upward pointing green arrow. If it was 0 it would be straight and if negative the arrow would be red and point down. I understand how to deal with the indicator - that's not an issue. It's the MDX I need help with.
20130201 8
20130301 10
20121201 4
I can write it in SQL and it would look like this.
Select Item, case when sum(Time1ContentCount) > sum(Time2ContentCount) then 3 when sum(Time1ContentCount) = sum(Time2ContentCount) then 2 when sum(Time1ContentCount) sum(Time2ContentCount) then 1 end as Indicator, sum(Time1ContentCount) as Time1Count, sum(Time2ContentCount) as Time2Count from (Select timeID, dc.Item, Case when timeID = (Select max(timeID) from FactUsage) then count(fu.Contentid) else 0 END as Time1ContentCount, Case when timeID = (Select max(timeID) from FactUsage where timeID <>(Select max(timeID) from FactUsage)) then count(fu.Contentid) else 0 END as Time2ContentCount from factUsage fu INNER JOIN dimContent dC on dc.ContentID = fu.ContentID WHERE TimeID in (Select distinct top 6 timeid from factUsage order by timeID desc) Group by timeID, Item) a group by Item
Thanks so much for your help!
Edit:
I changed the statement to read as follows for the indicator.
WITH Member MEASURES.Indicator AS (
IIF(( [Measures].[Activity], [Time].[Time ID].LastChild ) >
( [Measures].[Activity], [Time].[Time ID].LastChild.PrevMember),3,
(IIF(([Measures].[Activity], [Time].[Time ID].LastChild ) =
([Measures].[Activity], [Time].[Time ID].LastChild.PrevMember), 2,1))))
SELECT {Measures.Indicator} on 0
FROM [DW]
It works when I run it as a query against the cube in SSMS but I tried to put it in the indicator and that doesn't work. Just adding the IIF statement doesn't work either. When I tried to add it into the query or the cube itself so I could just pull from there it errors out with an out of memory error.
I don't know how much you can edit in the MDX expression - or in your report builder, but to get the difference between two values in a series, you can create a measure (in your report) that is the difference between the CurrentMember and PrevMember. Since the time series (timeid) is sorted by the key, it will always be in the right order (or your schema and architecture needs a rework)
So basically, you can do :
WITH
MEMBER MEASURES.GrowthTime AS (
( [Measures].[Value], [TimeID].CurrentMember ) -
( [Measures].[Value], [TimeID].PrevMember )
)
MEMBER MEASURES.GrowthRatio AS (
( [Measures].[Value], [TimeID].CurrentMember ) /
( [Measures].[Value], [TimeID].PrevMember )
)
SELECT { Measures.Value, Measures.GrowthTime, Measures.GrowthRatio } on 0,
[TimeID].CHILDREN on 1
FROM Cube
This is pseudo as i don't know your cube structure. For TimeID you would want it like [DimensionName].[AttributeName].CurrentMember and PrevMember