Difference between two time values in SSRS report - reporting-services

I have the following select statement:
SELECT [TR_DATE]
,[TR_TIME]
,RIGHT('000000' + CONVERT(varchar,TR_TIME), 6)
,TIMEFROMPARTS(SUBSTRING(RIGHT('000000' + CONVERT(varchar,TR_TIME), 6),1,2), SUBSTRING(RIGHT('000000' + CONVERT(varchar,TR_TIME), 6),3,2), SUBSTRING(RIGHT('000000' + CONVERT(varchar,TR_TIME), 6),5,2),0,0) as trtime
,[ET_TYPENO]
,[ET_NAME]
FROM [DB400].[dbo].[TRANSACTIONREPORT]
where DEPT_NAME = 'GIJIMA AST HOLDINGS (PTY) LTD'
/*and LOC_NAME = 'Front Door and Gate'*/
and TR_DATE between '20200120' and '20200130'
order by TR_DATE, MST_LASTNAME, MST_FIRSTNAME, TR_TIME
which returns the following data:
I would like to use this to calculate the time the was spent in the building.
Note that ET_TYPENO = 1 equates to "Allowed Normal In" and ET_TYPENO = 2 to "Allowed Normal Out"
I have the following expression inside an ssrs report
=iif(Fields!ET_TYPENO.Value=2,
DateDiff(DateInterval.Hour, previous(Fields!trtime.Value),Fields!trtime.Value),
"")
But it resolves to the following #Error.
UPDATE
Expected Result
Calculate the time difference between the "Allowed Nornmal In" event and the "Allowed Normal Out" event.
Take line 2 and 3 for example. "Allowed Nornmal In" occured at 07:23:19 and "Allowed Normal Out" occured at 08:55:48. I need it to return the time difference between these two times. I.E. 1:32:29.

The trtime needs to be converted to a DATE type with the CDATE() function to use the DATEDIFF function.
=IIF(Fields!ET_TYPENO.Value = "OUT",
DateDiff(DateInterval.Hour, CDATE(previous(Fields!trtime.Value)), CDATE(Fields!trtime.Value)),
NOTHING)
Also, shouldn't Fields!ET_TYPENO.Value = 1 ?

Taking the suggestion from Honnover Fist's answer that the parameter of the DateDiff need to be Dates instead of Times. (The Documentation does say that a Time will work). I have changed my query to a DATETIMEFROMPARTS() instead of a TIMEFROMPARTS().
Then I changed the condition to the below code so that the hours would be displayed more accurately.
=IIF(Fields!ET_TYPENO.Value = 2,
DateDiff(DateInterval.Minute, previous(Fields!TR_DATETIME.Value), Fields!TR_DATETIME.Value) / 60,
NOTHING)

Related

SSRS - IIF error in Report Builder

I am having an issue with a divide by zero error that I have half way worked through.
Basically I need (EstimatedValuePlanned - EAC) / EstimatedValuePlanned
I have the following, however I am still getting #Error on some:
= IIF (Fields!EstimatedValuePlanned.Value = 0 , 0,
Fields!EstimatedValuePlanned.Value - Fields!EAC.Value)
/
SUM(Fields!EstimatedValuePlanned.Value)
I have changed the code around several times but I still either get Error or NaN
Thank you
IIF will always evaluate both parts of the function, so when SUM(Fields!EstimatedValuePlanned.Value) is zero you will get the error even though that's not what will be returned.
Try using a SWITCH statement. SWITCH stops once an expression returns True.
Something like this
= SWITCH(
SUM(Fields!EstimatedValuePlanned.Value) = 0 , 0,
True, (Fields!EstimatedValuePlanned.Value - Fields!EAC.Value) / SUM(Fields!EstimatedValuePlanned.Value)
)
The True expression simply acts like an else
UPDATE WITH SAMPLE
I created a new report added a dataset and set the dataset query to be the following (just to generate some dummy data).
DECLARE #t TABLE (EVP float, EAC float)
INSERT INTO #t VALUES
(1,2),
(2,3),
(5,4),
(0,2),
(1,0),
(0,0)
SELECT * FROM #t
I then added a table, set the first to columns to be EVP and EAC respectively and set the 3rd column to an expression as follows.
=SWITCH (
Fields!EVP.Value = 0, 0
, True, (Fields!EVP.Value - Fields!EAC.Value) / Fields!EVP.Value
)
The report design looks like this.
And when it's run this is the result....
Try replicating the above steps and see if you can get it to work like this first then review difference to your report.
I got it to work with:
=IIF (Fields!EstimatedValuePlanned.Value = 0 , 0,
Fields!EstimatedValuePlanned.Value - Fields!EAC.Value)
/
IIF(Fields!EstimatedValuePlanned.Value =
0,1,Fields!EstimatedValuePlanned.Value)
Thank you both

Multiple Or in an IIF function

Given this data: Complete Dataset
I only want to get the Total_AR of those TransactionYrMonth=ParameterPeriod so I produced it using this code:
=IIF(
IsNothing(Sum(Fields!Total_AR.Value)),0,
Sum(IIF(Cdate(Fields!TransactionYrMnth.Value)=Cdate(Parameters!Period.Value),
Fields!Total_AR.Value,0)
)
)
From there, I got this dataset:
Filtered Dataset
Now, what I need to do is to get the sum of the first 3 service months starting from January to March that is equal to the latest transaction month which is April.
So the sum should be equal to $204,329 + -$96,640 + -$259,008 = -$151,319
To make it possible, I tried to use a code like this:
=Sum(IIF(
Cdate(Fields!TransactionYrMnth.Value)=Cdate(Parameters!Period.Value) And (
Cdate(Fields!ServiceYrMnth.Value)=DateAdd(DateInterval.Month, -3, CDate(Parameters!Period.Value)) Or
Cdate(Fields!ServiceYrMnth.Value)=DateAdd(DateInterval.Month, -2, CDate(Parameters!Period.Value)) Or
Cdate(Fields!ServiceYrMnth.Value)=DateAdd(DateInterval.Month, -1, CDate(Parameters!Period.Value))), Fields!Total_AR.Value,0
))
I have no luck producing it. I even got an error saying
‘Textbox11.Paragraphs[0].TextRuns[0]’ contains an error: [BC30516] Overload resolution failed because no accessible 'IIf' accepts this number of arguments.
Anyone, please help?
I got a solution already using this code:
=Sum(IIF(
Cdate(Fields!TransactionYrMnth.Value)=Cdate(Parameters!Period.Value) And
CDate(Fields!ServiceYrMnth.Value) >= DateAdd(DateInterval.Month, -3, CDate(Parameters!Period.Value)) And
CDate(Fields!ServiceYrMnth.Value) <= DateAdd(DateInterval.Month, -1, CDate(Parameters!Period.Value)), Fields!Total_AR.Value, 0
)
)

SSRS Pie chart hide 0 Value

SQL Server 2012 - SSRS Questions
I currently have a Pie chart that shows the number of deliveries as a percentage on whether they are late, on time or early. What I am trying to do is use an Expression in the Chart Series Labels "Visible" property to hide the label if it is 0 on the chat. Of note in the table this value is returned as 0.00 I have tried using various SWITCH and IFF Statements to do this but nothing seems to work and its likely I am getting the syntax wrong, can anyone help?
Table Values
TotalIssued Early Late OnTime EarlyPerc LatePerc OnTimePerc
6, 0, 4, 2, 0.00, 66.67, 33.33,
=SWITCH(
(First(Fields!EarlyPerc.Value, "EstimatesIssued") = 0),false,
(First(Fields!LatePerc.Value, "EstimatesIssued") = 0),false,
(First(Fields!OnTimePerc.Value, "EstimatesIssued") = 0),false,
true)
Thanks
Try:
=SWITCH(
First(Fields!EarlyPerc.Value, "EstimatesIssued") = 0,false,
First(Fields!LatePerc.Value, "EstimatesIssued") = 0,false,
First(Fields!OnTimePerc.Value, "EstimatesIssued") = 0,false,
true,true)
UPDATE:
If you have one field per percentage and your dataset returns one row always, you have to select each serie in the ChartData window and press F4 to see properties window.
In properties window set for EarlyPerc Visible property:
=IIF(Fields!EarlyPerc.Value=0,False,True)
And so on for the next two series you have (LatePerc and OnTimePerc).
Let me know if this helps.

how to add #interval in a line chart ssrs

I was trying to add #interval in SSRS for my line chart, so the end user can select day, week, month from #interval. If the end used selects #interval = Week, the line will show only 1 number for every week, so the line will look nicer with less number.
I am thinking to create #interval in report parameters, then create expression for "chart data-values".
This was the expression I wrote, but it did not work.
=switch (Parameters!Interval.Value='Day', sum(Fields!DealPerActiveDealer.Value),
Parameters!Interval.Value='Month', Avg (sum(Fields!DealPerActiveDealer.Value)),
Parameters!Interval.Value='Week', Avg (sum(Fields!DealPerActiveDealer.Value))
Does anyone know how to work on this? Many Thanks!
I rarely use the Switch but the syntax looks correct. You should be using double quotes instead of single in an expression.
=SWITCH(PARAMETERS!INTERVAL.VALUE = "DAY", SUM(FIELDS!DEALPERACTIVEDEALER.VALUE),
PARAMETERS!INTERVAL.VALUE = "MONTH", AVG(SUM(FIELDS!DEALPERACTIVEDEALER.VALUE)),
PARAMETERS!INTERVAL.VALUE = "WEEK", AVG(SUM(FIELDS!DEALPERACTIVEDEALER.VALUE))
As to your chart, you might also need to change the axis with your time line. I assume it shows every day now but should be dynamic also. Your grouping expression would be something like:
=DATEPART(SWITCH(Parameters!Interval.Value = "Day", "d"
Parameters!Interval.Value = "Month", "m",
Parameters!Interval.Value = "Week", "ww"), Fields!DATEFIELD.Value)

Inherited database has leap year code that compiler doesn't like

In my job, I have inherited an Access 97 database. This database is very unstable and I need to remedy that in one way or another. I have been trying to go through and debug the current version so that I can migrate it to 2007. I have run across some code that the compiler doesn't like and not sure how to fix it...here is the code:
Function DaysInMonth(ByVal D As Date) As Long
' Requires a date argument because February can change
' if it's a leap year.
Select Case Month(D)
Case 2
If LeapYear(Year(D)) Then
DaysInMonth = 29
Else
DaysInMonth = 28
End If
Case 4, 6, 9, 11
DaysInMonth = 30
Case 1, 3, 5, 7, 8, 10, 12
DaysInMonth = 31
End Select
End Function
I get a compile error: Sub or Function not defined and it highlights the first "LeapYear".
Any help at all would be greatly appreciated! Thanks!
LeapYear is another function or procedure that appears not be present in your modules or has been made Private. LeapYear isn't a VBA function. There must have been a function that takes a year Year(D) and returns TRUE or FALSE if it's a leapyear. either insert one or set the existing one to Public
Edit:You could use IsLeapYear but change to 'LeapYear' and call using IsLeapYear(D)
The code in question is idiotic -- it was clearly written by somebody who didn't have a clue about VBA dates, which already know everything that is needed without needed to encode this crap into a CASE SELECT.
This expression will get you the number of days in a month:
Day(DateAdd("m", 1, DateValue(Month(Date()) & "/1/" & Year(Date()))) - 1)
What this does is get the first of the current month, adds a month to it (for the first of the next month), and then subtracts 1 from it. Since the integer part of the VBA date type is the day part, that will get you the last day of the current month. Then you take the result and pull the day out with the Day() function.
Coding that up as a function:
Function DaysInMonth(ByVal dteDate As Date) As Integer
Dim dteFirstOfMonth As Date
Dim dteLastOfMonth As Date
dteFirstOfMonth = DateValue(Month(dteDate) & "/1/" & Year(dteDate))
dteLastOfMonth = DateAdd("m", 1, dteFirstOfMonth) - 1
DaysInMonth = Day(dteLastOfMonth)
End Function
You could also code this up using the fact that the DateSerial() function treats the zeroth day as the last of the previous month:
Function DaysInMonth(ByVal dteDate As Date) As Integer
Dim dteOneMonthFromDate As Date
Dim dteLastOfThisMonth As Date
dteOneMonthFromDate = DateAdd("m", 1, dteDate)
dteLastOfThisMonth = DateSerial(Year(dteOneMonthFromDate), Month(dteOneMonthFromDate), 0)
DaysInMonth = Day(dteLastOfThisMonth)
End Function
But that doesn't make it any shorter...
None of this requires figuring out leap year rules -- those are built into the VBA date type.
And, of course, the function should not return a Long, but an Integer, since the maximum value it can ever return is 31.
LeapYear may not be your only issue.
In Access '97, go to the VBA editor and click "Tools/References":
Look in the references of your '97 project and see what DLLs are listed.
A screen will appear that shows you the ActiveX DLLs that can be used for the project. The ones that are checked are the ones currently used:
Odds are there is a DLL there that needs to be referenced in your new 2007 database.