I have Arrival Date and Departure Dates and the difference between them in minutes. I would like to format the difference between the dates as DD:HH:mm (Days:24-hours format:minutes). For instance, the minutes 3245 should be shown as 02:02:45(2 days, 2 hours and 45 minutes => 21440 + 260 + 45).
I've tried DateDiff function, but could not get the exact formatting. Also I need to Sum up these at the end.
Please help me with the Report Expression.
You need to add two columns. One will display the formatted expession and one hidden will contain the datediff calculations.
Your calculation column will contain the datediff expression in minutes
= DATEDIFF("n",Fields!date1.Value,Fields!date2.Value)
For the total you can normally use SUM
= SUM(DATEDIFF("n",Fields!date1.Value,Fields!date2.Value))
Your expression display textboxes should refer to the relevant report items (in my example Textbox6 is for detail and Textbox9 is for total)
= Cstr(ReportItems!Textbox6.value \ (24*60)) & ":" &
Format( (ReportItems!Textbox6.value Mod (24*60)) \ 60, "00" ) & ":" &
Format( (ReportItems!Textbox6.value Mod (24*60)) Mod 60, "00" )
= Cstr(ReportItems!Textbox9.value \ (24*60)) & ":" &
Format( (ReportItems!Textbox9.value Mod (24*60)) \ 60, "00" ) & ":" &
Format( (ReportItems!Textbox9.value Mod (24*60)) Mod 60, "00" )
Related
I'm struggling to write an SSRS expression to show dates based on a group heading and parameter date.
The expression needs to look at the cell value and add 1 & 7 days. The date parameter is called inputdate
so if the cell value = '4) Overdue Week 1 - ' then inputdate + 1 &-& inputerdate +7 as WE1
if the cell value = '5) Overdue Week 2 - ' then inputdate + 8 &-& inputerdate +14 as WE2
if the cell value = '6) Overdue Week 3 - ' then inputdate + 15 &-& inputerdate +21 as WE2
and so on...
The cell is based on a grouped header.
Any help is appreciated. Thanks in advance
This is my attempt:
=IIf((Fields!Type_of.Value = "4) Overdue Week 1 - '",
DateAdd("d",1,Parameters!inpdate.Value) +-+ DateAdd("d",7,Parameters!inpdate.Value),0)
,IIf((Fields!Type_of.Value = "5) Overdue Week 2 - '"
,DateAdd("d",8,Parameters!inpdate.Value) +-+ DateAdd("d",14,Parameters!inpdate.Value),0)
IIf((Fields!Type_of.Value = "6) Overdue Week 3 - '"
,DateAdd("d",15,Parameters!inpdate.Value) +-+ DateAdd("d",21,Parameters!inpdate.Value),0)
IIf((Fields!Type_of.Value = "7) Overdue Week 4 - '"
,DateAdd("d",22,Parameters!inpdate.Value) +-+ DateAdd("d",28,Parameters!inpdate.Value),0)
IIf((Fields!Type_of.Value = "8) Overdue Week 5 - '"
,DateAdd("d",29,Parameters!inpdate.Value) +-+ DateAdd("d",35,Parameters!inpdate.Value),0)
IIf((Fields!Type_of.Value = "9) Overdue Week 6 - '"
,DateAdd("d",36,Parameters!inpdate.Value) +-+ DateAdd("d",42,Parameters!inpdate.Value),0)
but it returns an error;
Severity Code Description Project File Line Suppression State
Error [rsCompilerErrorInExpression] The Value expression for the field 'Date_Type_of' contains an error: [BC30198] ')' expected.
In addition to what Harry mentioned, your IIF statement syntax is incorrect. You don't have any closing parenthesis nor a final ELSE.
Here's what should work:
=IIf(Fields!Type_of.Value = "4) Overdue Week 1 - '",
DATEADD("d", Parameters!inpdate.Value, 1) & "-" & DATEADD("d", Parameters!inpdate.Value,7),
IIf(Fields!Type_of.Value = "5) Overdue Week 2 - '",
DATEADD("d", Parameters!inpdate.Value,8) & "-" & DATEADD("d", Parameters!inpdate.Value, 14),
IIf(Fields!Type_of.Value = "6) Overdue Week 3 - '",
DATEADD("d", Parameters!inpdate.Value, 15) & "-" & DATEADD("d", Parameters!inpdate.Value, 21),
Parameters!inpdate.Value)
)
)
I indent to keep track of the levels of IIFs. But as Harry also mentioned, a SWITCH is better when you have multiple scenarios.
=SWITCH( Fields!Type_of.Value = "4) Overdue Week 1 - '", DATEADD("d", Parameters!inpdate.Value, 1) & "-" & DATEADD("d", Parameters!inpdate.Value,7),
Fields!Type_of.Value = "5) Overdue Week 2 - '", DATEADD("d", Parameters!inpdate.Value,8) & "-" & DATEADD("d", Parameters!inpdate.Value, 14),
Fields!Type_of.Value = "6) Overdue Week 3 - '", DATEADD("d", Parameters!inpdate.Value, 15) & "-" & DATEADD("d", Parameters!inpdate.Value, 21),
True, Parameters!inpdate.Value
)
I have a Time column in which is in minute , in ssrs i need to get average and output in such a way that its in Day, Hour and min.
For example Column name is Time (Min).How to write an expression in such a way that we can get result in day, hour and min
Assuming that your time column is just an integer datatype containing a number of minutes then something like this will work.
The following calculates based on a report parameter to make it easier to test so oyu will need to swap this out for the correct column name and aggregations. e.g. if you time column is called MyTime and you want to calculate based on the average then swap out Parameters!MyMins.Value with AVG(Fields!MyTime.Value)
= INT(Parameters!MyMins.Value / 1440) & " days " &
INT((Parameters!MyMins.Value MOD 1440) / 60) & " hours " &
(Parameters!MyMins.Value MOD 60) & " mins"
adjust the output to suit you formatting requirements....
The above turns 4455 minutes into the string "3 days 2 hours 15 mins"
Enter the following expression:
=Format(TimeSerial(0,Parameters!MyMins.Value,0),"dd") & " Days "
& Format(TimeSerial(0,Parameters!MyMins.Value,0),"HH") & " Hours "
& Format(TimeSerial(0,Parameters!MyMins.Value,0),"mm") & " Minutes "
Alternatively, create another parameter e.g. MyTime
=TimeSerial(0,Parameters!MyMins.Value,0)
(Ensure that this parameter is evaluated after MyMins by moving it down the list)
Then put that into the code above
=Format(Parameters!MyTime.Value,"dd") & " Days "
& Format(Parameters!MyTime.Value,"HH") & " Hours "
& Format(Parameters!MyTime.Value,"mm") & " Minutes "
Trying to create a TextBox expression:
="Validity: " & IIF(Fields!ID.Value = 2, Fields!Value.Value, "") & " from date above."
from a dataset:
ID; NAME; VALUE;
1; Delivery; x Factory;
2; Validity; 30 days;
3; Pricing Structure; Subject to...;
so that the text box would read "Validity: 30 days from date above" but returns "Validity: from date above"
The problem is the report only allows me to use aggregate First, max, etc from the dataset producing an incorrect result.
"Validity: " & IIF(First(Fields!ID.Value, "DataSet") = 1, First(Fields!Value.Value, ), "") & " from date above."
"Validity: x Factory from date above"
Your dataset is showing "30 days", do you require the text box to show this or do you require it to be "60 days"?
Meanwhile if you restrict you dataset to one row of data, ie insert a where/having clause such as : HAVING (ID = 2), then you could use the aggregate sum function in your expression:
="Validity: " & IIF(Sum(Fields!ID.Value, "DataSet1") = 2, Fields!Value.Value, "") & " from date above."
I'm surprised that I can't find any existing solutions to this online but I just need an SQL function that returns an ISO standard week number (i.e. the start of week 1 is always the first Monday of the year).
None of the DatePart function options consistently return the correct result. I had thought the option "vbFirstFourDays - Start with the first week that has at least four days in the new year." but testing it for today (12th Jan) returns week 3, not week 2 (my expression is DatePart("ww",Now(),2) )
This year ISO week 1 starts on 4th Jan, next Year the 2nd Jan and last year it was the 5th of Jan.
Many thanks
The DatePart function does indeed calculate the ISO-8601 week number almost* correctly when it uses vbMonday for the firstdayofweek argument and vbFirstFourDays for the firstweekofyear argument, e.g.,
DatePart("ww", Date(), vbMonday, vbFirstFourDays)
or, when used directly in an Access query
DatePart("ww", Date(), 2, 2)
* Note that the bug documented here has apparently never been fixed, so the following Mondays in the 21st century are reported as being in week 53 when according to ISO-8601 they should be in week 1 of the following year:
2003-12-29
2007-12-31
2019-12-30
2031-12-29
2035-12-31
2047-12-30
2059-12-29
2063-12-31
2075-12-30
2087-12-29
2091-12-31
Just to follow on from Gord Thompson, Microsoft have provided a workaround which returns the correct ISO week in all circumstances. It simply changes week 53 to week 1. Simply place this in a VBA Module and then you'll be able to use the function in Excel/Access.
Public Function ISOWeek(MyDate As Date) As Integer
ISOWeek = Format(MyDate, "ww", vbMonday, vbFirstFourDays)
If ISOWeek > 52 Then
If Format(MyDate + 7, "ww", vbMonday, vbFirstFourDays) = 2 Then ISOWeek = 1
End If
End Function
There are more problems with the ISO weeknumbers than just the 2 week digits returned by DatePart.
January 1st on a Friday should be in week 53 of the previous year
December 31 on a Monday should be in week 1 of the next year
A lot of businesses in Europe use a four digit number to show year and week together. In those cases:
Friday #01/01/2021# should be shown as week "2153"
Monday #12/31/2018# should be shown as week "1901"
I have created 2 wrappers around the DatePart function to add the correct year and show the right weeknumber in case DatePart is in error.
Public Function ISO_YYWW(dat As Date) As String ' ISO 8601 / NEN 2772
Dim ww As Integer
ww = CInt(ISO_WW(dat))
If ww >= 52 And Val(Format(dat, "ww")) <= 2 Then
ISO_YYWW = Format(((Year(dat) - 1) Mod 100), "00") & Format(ww, "00")
ElseIf ww = 1 And Month(dat) = 12 Then
ISO_YYWW = Format(((Year(dat) + 1) Mod 100), "00") & Format(ww, "00")
Else
ISO_YYWW = Format(dat, "YY") & Format(ww, "00")
End If
End Function
Public Function ISO_WW(dat As Date) As String ' ISO 8601 / NEN 2772
If Format(dat, "DD-MM") = "31-12" And DatePart("W", dat, vbMonday, vbFirstFourDays) = 1 Then ' 31-dec on a monday
ISO_WW = "01"
ElseIf Format(dat, "DD-MM") = "30-12" And DatePart("W", dat, vbMonday, vbFirstFourDays) = 1 Then ' 30-dec on a monday
ISO_WW = "01"
ElseIf Format(dat, "DD-MM") = "29-12" And DatePart("W", dat, vbMonday, vbFirstFourDays) = 1 Then ' 29-dec on a monday
ISO_WW = "01"
Else
ISO_WW = Format(DatePart("ww", dat, 2, 2), "00")
End If
End Function
I have tested from 1970 to 2021 and found no problems using this code
Sub test()
Dim dat As Date, yy As Integer, f As Integer
f = FreeFile
Open CodeDb.Name & ".txt" For Output As #f
Print #f, "date", "day", "ISO_WW / DOW", "ISO_YYWW"
For yy = 1970 To 2021
For dat = CDate("31/12/" & yy) - 7 To CDate("31/12/" & yy) + 7
If ISO_WW(dat) >= 52 Or ISO_WW(dat) = "53" Or Val(ISO_WW(dat)) = 1 Then
Print #f, Format(dat, "yyyy-mm-dd"), Format(dat, "DDD"), ISO_WW(dat) & " / " & DatePart("W", dat, vbMonday, vbFirstFourDays), ISO_YYWW(dat)
End If
Next dat
Print #f, ""
Next yy
Close #f
End Sub
Part of my query is like so:
SELECT * FROM TableA
WHERE ColumnA >= DATEADD(DAY, - 30, GETDATE())
With the expression at the where clause above, you can pull a rolling 30 days data without having to supply values. Now users of the report want to see it represented like:
2nd April – 1st May
when the report is ran. Knowing that I have no parameters as the requirement is to not use parameters, how do I reference ">= DATEADD(DAY, - 30, GETDATE())" to reflect the start date and the end date in the report?
SSRS doesn't have built-in support for ordinal numbers (i.e. "1st" or "2nd" instead of "1" or "2"). This page contains custom code to add this functionality to your SSRS report; however it is slightly wrong. Here is a corrected version:
Public Function FormatOrdinal(ByVal day As Integer) as String
' Starts a select case based on the odd/even of num
if(day = 11 or day = 12 or day = 13)
' If the nymber is 11,12 or 13 .. we want to add a "th" NOT a "st", "nd" or "rd"
return day.ToString() + "th"
else
' Start a new select case for the rest of the numbers
Select Case day Mod 10
Case 1
' The number is either 1 or 21 .. add a "st"
Return day.ToString() + "st"
Case 2
' The number is either a 2 or 22 .. add a "nd"
Return day.ToString() + "nd"
Case 3
' The number is either a 3 or 33 .. add a "rd"
Return day.ToString() + "rd"
Case Else
' Otherwise for everything else add a "Th"
Return day.ToString() + "th"
End Select
end if
End Function
If you add this code to the code section of your report under report properties, your textbox expression would be:
Code.FormatOrdinal(Day(Globals!ExecutionTime)) & " " & MonthName(Month(Globals!ExecutionTime), False) & " - " & Code.FormatOrdinal(Day(DateAdd("d", -30,Globals!ExecutionTime))) & " " & MonthName(Month(DateAdd("d", -30,Globals!ExecutionTime)), False)
Right Click on the Textbox, Go To Textbox Properties then, Click on Number tab, click on custom format option then click on fx button in black.
Write just one line of code will do your work in simpler way:
A form will open, copy the below text and paste there to need to change following text with your database date field.
Fields!FieldName.Value, "Dataset"
Replace FieldName with your Date Field
Replace Dataset with your Dateset Name
="d" + switch(int(Day((Fields!FieldName.Value, "Dataset"))) mod 10=1,"'st'",int(Day((Fields!FieldName.Value, "Dataset"))) mod 10 = 2,"'nd'",int(Day((Fields!FieldName.Value, "Dataset"))) mod 10 = 3,"'rd'",true,"'th'") + " MMMM, yyyy"