SSRS Expression works as cell value expression, but not as background color value expression - ssrs-2008

I have an SSRS report with a matrix in it, where I needed to display the Growth Percentage in a column group compared to the previous column value. I managed this by using custom code...
DIM PreviousColValue AS Decimal
Dim RowName AS String = ""
Public Function GetPreviousColValue(byval Val as Decimal, byval rwName as string) as Decimal
DIM Local_PreviousColValue AS Decimal
IF RowName <> rwName THEN
RowName = rwName
PreviousColValue = val
Local_PreviousColValue = 0
ELSE
Local_PreviousColValue = (Val - PreviousColValue)/PreviousColValue
PreviousColValue = val
END IF
Return Local_PreviousColValue
End Function
..and then using this as the value expression in the cell..
=Round(Code.GetPreviousColValue(ReportItems!Textbox8.Value,Fields!BusinessUnit.Value)*100,0,system.MidpointRounding.AwayFromZero)
So far so good, this produces the expected value. Now I need to use this expression in a background color expression to get a red/yellow/green but in that capacity it fails.
The background color expression looks like this: =IIF(ROUND(Code.GetPreviousColValue(ReportItems!Textbox9.Value,Fields!Salesperson.Value)*100,0,System.MidpointRounding.AwayFromZero)<=-5,"Red"
,IIF(ROUND(Code.GetPreviousColValue(ReportItems!Textbox9.Value,Fields!Salesperson.Value)*100,0,System.MidpointRounding.AwayFromZero) >=5,"Green"
,"Yellow"))
When I run the report the background color expression only ever returns yellow. As a test I pasted the background color expression in as the cell value and ran it again. Results in the image below
I get no build or run time errors so I'm not sure why this does not work.

After some more searching I found a better Custom Code solution than what I was using to get the Growth Percentage in a column group compared to the previous column value. Besides being simpler to read this version has an added benefit: You can dynamically hide the growth percentage column for your first instance of the column group (because it will always be zero or null) and still get the right values in the 2nd/3rd/4th instance of the column group.
Public Function GetDeltaPercentage(ByVal PreviousValue, ByVal CurrentValue) As Object
If IsNothing(PreviousValue) OR IsNothing(CurrentValue) Then
Return Nothing
Else if PreviousValue = 0 OR CurrentValue = 0 Then
Return Nothing
Else
Return (CurrentValue - PreviousValue) / PreviousValue
End If
End Function
The new function is called like so
=Code.GetDeltaPercentage(Previous(Sum(<expression or dataset field>),"Group ByColumn"), Sum(<expression or dataset field>))
Re: the original question - why does my cell value expression not work when used as the background color expression - I took an easy out and just referenced the cell value.
=IIF(ROUND(Me.Value*100,0,System.MidpointRounding.AwayFromZero)<=-5,"Red"
,IIF(ROUND(Me.Value*100,0,System.MidpointRounding.AwayFromZero) >=5,"Green"
,"Yellow"))

Related

SSRS Max date from Lookupset

I've spent a long time looking around for a solution for this and not found quite what I want. Efforts to adapt existing solutions for different problems have also not worked!
I am using LookupSet to return a list of dates, then joining them to return a list:
=Join(LookupSet(Fields!cPatSer.Value,Fields!cPatSer.Value,Fields!DDate.Value,"PatD"))
I want to only show the most recent date from that list. Here is what I have tried so far:
The above function wrapped in a Max function (doesn't work because Join returns a string)
Using a split function to split the resultant string looking for the commas then using the max function
Doing both of the above but converting the output to Date objects using CDate and DateTime.Parse first as follows...
=Join(LookupSet(Fields!cPatSer.Value,Fields!cPatSer.Value,CDate(Fields!DDate.Value),"PatD"))
=Join(LookupSet(Fields!cPatSer.Value,Fields!cPatSer.Value,DateTime.Parse(Fields!DDate.Value),"PatD"))
Can anybody provide any pointers please?
I've found a solution using Custom Code. Oz Locke made a function that does various aggregates for integer data (links below), and I've amended this to work for dates instead.
In the Code property of the report, paste in this:
'Amended from Oz Locke's code:
'https://github.com/OzLocke/SSRSAggLookup/blob/master/AggLookup.vb
'Allows users to adjust the aggregation type of lookupsets in a cell
Function AggLookup(ByVal choice As String, ByVal items As Object)
'Ensure passed array is not empty
'Return a zero so you don't have to allow for Nothing
If items Is Nothing Then
Return 0
End If
'Define names and data types for all variables
Dim current As Date
Dim count As Integer
Dim min As Date
Dim max As Date
Dim err As String
'Define values for variables where required
current = CDate("01/01/1900")
count = 0
err = ""
'Calculate and set variable values
For Each item As Object In items
'Calculate Count
count += 1
'Check value is a number
If IsDate(item) Then
'Set current
current = CDate(item)
'Calculate Min
If min = Nothing Then
min = current
End If
If min > current Then
min = current
End If
'Calculate the Max
If max = Nothing Then
max = current
End If
If max < current Then
max = current
End If
'If value is not a number return "NaN"
Else
err = "NaN"
End If
Next
'Select and set output based on user choice or parameter one
If err = "NaN" Then
If choice = "count" Then
Return count
Else
Return 0
End If
Else
Select Case choice
Case "count"
Return count
Case "min"
Return min
Case "max"
Return max
End Select
End If
End Function
Then in the cell of your report, use this expression:
=code.AggLookup("max", LookupSet(Fields!cPatSer.Value,Fields!cPatSer.Value,Fields!DDate.Value,"PatD"))
https://itsalocke.com/aggregate-on-a-lookup-in-ssrs/
https://github.com/OzLocke/SSRSAggLookup/blob/master/AggLookup.vb

Summing Only Visible Rows in SSRS

I'm trying to sum only the visible rows for a report and I know the format is:
=Sum( iif( <use the condition of the Visibility.Hidden expression>, 0, Fields!A.Value))
In my report, I've set row visbility to:
=IIF(CInt(Fields!EM_ET.Value)=1 Or CInt(Fields!EM_ET.Value)= 2,True,False)
Not exactly sure what I'm missing, but when I use this as an expression:
=Sum(IIF(CInt(Fields!EM_ET.Value)=1 Or CInt(Fields!EM_ET.Value)= 2,True,False),0,Fields!EM_ET.Value)
I get this following error: Value expression for textrun'FTD1.Paragraph[0].TextRuns[0]' has a scope argument that is not valid for aggregate function.
You are giving the True/False as output to the SUM() from your expression.You need to change your expression as,
=Sum(IIF(CInt(Fields!EM_ET.Value) = 1 Or CInt(Fields!EM_ET.Value)= 2,0,Fields!EM_ET.Value))
Thanks coder of code.
I am getting some error message if i am using '0', so i replaced with nothing it's working. I thought it would be helpful.
=SUM(IIF(ISNOTHING(Fields!value1.Value) OR ISNOTHING(Fields!value2.Value),NOTHING,Fields!value1.Value))
I was having similar issues. I know this question has a marked answer, however it isn't entirely correct.
The following contains the code from the "marked correct" answer:
=Sum(IIF(CInt(Fields!EM_ET.Value) = 1 Or CInt(Fields!EM_ET.Value) = 2,0,Fields!EM_ET.Value))
The following snipit of code contains the code from above, with a slight tweak:
=Sum(IIF(CInt(Fields!EM_ET.Value) = 1 Or CInt(Fields!EM_ET.Value) = 2,NOTHING,Fields!EM_ET.Value))
By changing the "0" to "NOTHING" this will resolve any lingering issues with your formula. The formula I was having issues with was returning "#Error" in the cell that was supposed to return the sum of the visible cells in the column within the row group.
My formula originally looked like this:
=IIF(Sum(Fields!VCBitType.Value) <> 0 OR (Parameters!Details.Value = "Detail"), Sum(IIF((Fields!VCBitType.Value = 0) and (Parameters!Details.Value = "Dangerous"),0,Fields!VC.Value)), "")
I altered my formula after seeing Hari's comment above:
=IIF(SUM(Fields!VCBitType.Value) <> 0 OR (Parameters!Details.Value = "Detail"), SUM(IIF((Fields!VCBitType.Value = 0) and (Parameters!Details.Value = "Dangerous"),NOTHING, Fields!VC.Value)), "")
I wanted to set the cells value to "" (empty) rather than hide the cell entirely or set that cell's value to "0" in my report (due to the fact that not displaying the cell entirely made the report look really funky). Because I did this, using a "0" in my formula conflicted with the value of the cell which was "" (empty), causing the formula to break. The only change I made was to alter "0" to "Nothing", this resolved the issue I was having with the cell's formula.

sum two values from different datasets using lookups in report builder

I have a report that should read values from 2 dataset by Currency:
Dataset1: Production Total
Dataset2: Net Total
Ive tried to use:
Lookup(Fields!Currency_Type.Value,
Fields!Currency_Type1.Value,
Fields!Gross_Premium_Amount.Value,
"DataSet2")
This returns only the first amount from dataset 2.
I've tried Lookupset function as well but it didn't SUM the retrieved values.
Any help would be appreciated.
Thanks Jamie for the reply.
THis is what i have done and it worked perfect:
From Report Properties--> Code , write the below function:
Function SumLookup(ByVal items As Object()) As Decimal
If items Is Nothing Then
Return Nothing
End If
Dim suma As Decimal = New Decimal()
Dim ct as Integer = New Integer()
suma = 0
ct = 0
For Each item As Object In items
suma += Convert.ToDecimal(item)
Next
If (ct = 0) Then return 0 else return suma
End Function
Then you can call the function:
code.SumLookup(LookupSet(Fields!Currency_Type.Value, Fields!Currency_Type1.Value,Fields!Gross_Premium_Amount.Value, "DataSet2"))
Yes, Lookup will only return the first matching value. Three options come to mind:
Change your query, so that you only need to get one value: use a GROUP BY and SUM(...) to combine your two rows in the query. If you are using this query other places, then make a copy and change that.
Is there some difference in the rows? Such as one is for last year and one is for this year? If so, create an artificial lookup key and lookup the two values separately:
=Lookup(Fields!Currency_Type.Value & ","
& YEAR(DATEADD(DateInterval.Year,-1,today())),
Fields!Currency_Type1.Value & ","
& Fields!Year.Value,
Fields!Gross_Premium_Amount.Value,
"DataSet2")
+
Lookup(Fields!Currency_Type.Value & ","
& YEAR(today()),
Fields!Currency_Type1.Value & ","
& Fields!Year.Value,
Fields!Gross_Premium_Amount.Value,
"DataSet2")
Use the LookupSet function as mentioned. With this you'll get a collection of the values back, and then need to add those together. The easiest way to do this is with embedded code in the report. Add this function to the report's code:
Function AddList(ByVal items As Object()) As Double
If items Is Nothing Then
Return 0
End If
Dim Total as Double
Total = 0
For Each item As Object In items
Total = Total + CDbl(item)
Next
Return Total
End Function
Now call that with:
=Code.AddList(LookupSet(Fields!Currency_Type.Value,
Fields!Currency_Type1.Value,
Fields!Gross_Premium_Amount.Value,
"DataSet2"))
(Note: this code was not tested. I just composed it in the Stack Overflow edit window & I'm no fan of VB. But it should give you a good idea of what to do.)

Changing Row Colors in SSRS Report via data values

I know you can set the BackgroundColor to alternate between two colors with a fairly simple expression. I have a column that contains date values organized in order. Basically, I want the BackgroundColor to alternate each time the date value changes as you go down the rows. I got partway there with this code:
=iif(Previous(Fields!Req_Del_Dt.Value) = (Fields!Req_Del_Dt.Value), "White", "Lavender")
This will change the color each time the value of a row is not the same as the previous row. This is what the results of this look like:
http://imageshack.us/photo/my-images/24/alternatingcolors.jpg/
How can I make it so that the color changes to one color for an entire date (which might be 3 rows) and then "toggle" to a different color when the next date change occurs? I think I am on the right track, but I just can't figure this one out.
I would greatly appreciate any suggestions or comments. Thank you!
=IIF(RunningValue(Fields!Address.Value, CountDistinct, Nothing) MOD 2 = 1, "White", "Lavender")
For me this does the trick.
You can write custom code. For example:
Private _dateCount As Integer = 0
Function GetDateRowColor(ByVal previousDate As DateTime, ByVal currentDate As DateTime) As String
If previousDate = currentDate Then
' Do nothing
Else
_dateCount++
End If
If _dateCount Mod 2 = 0 Then
Return "White"
Else
Return "Lavender"
End If
End Function
Then, use expression in your Background color, for example:
=Code.GetDateRowColor(Previous(Fields!Req_Del_Dt.Value), Fields!Req_Del_Dt.Value)
HTH.
Got it - I should have tried harder before replying. I had to keep track of the current row number and only switch the value on new rows. Revised code:
Private _dateCount As Integer = 0
Private CurRowNumber as Integer = 0
Private ColorValue as String = ""
Function GetDateRowColor(ByVal previousDate As DateTime, ByVal currentDate As DateTime, MyRowNumber as Integer) As String
'Check if this is a new row number...
If MyRowNumber <> CurRowNumber then
CurRowNumber = CurRowNumber + 1 'New row, so increment counter
If previousDate = currentDate Then
' Do nothing
Else
_dateCount = _dateCount + 1
End If
If _dateCount Mod 2 = 0 Then
ColorValue = "White"
Else
ColorValue = "Lavender"
End If
End If
Return ColorValue 'Always return a value (for columns other than the first one)
End Function
Called like this:
=Code.GetDateRowColor(Previous(Fields!Req_Del_Dt.Value), Fields!Req_Del_Dt.Value, RowNumber(Nothing))
Thank you again for your excellent response & answer!
I had a similar problem:
Tablix/Table in SSRS 16
No grouping possible (would interfere with other functionality of the tablix)
Need to alternate colour blocks of rows with same value in date field
same date value could appear again (this is important, because Nanus Answer i.e. the use of CountDistinct depends on the same value (date) not appearing again in a later block).
For me the code in Loki70 revised answer didn't work. The first line of few random blocks of rows would have alternating colours in the cells. However once I rewrote the code it worked:
Private _dateCount As Integer = 0
Private RowNumberRunner as Integer = 0
Private ColorValue as String = ""
Function GetDateRowColor(ByVal previousDate As DateTime, ByVal currentDate As DateTime, MyRowNumber as Integer) As String
If MyRowNumber <> RowNumberRunner Then
RowNumberRunner = MyRowNumber
If previousDate <> currentDate Then
_dateCount = _dateCount + 1
End If
End If
If _dateCount Mod 2 = 1 Then
ColorValue = "White"
Else ColorValue = "Lavender"
End If
Return ColorValue
End Function
No clue, why that works and the previous code didn't. It's the same functionality, just written differently. It's called the same way:
=Code.GetDateRowColor(Previous(Fields!Req_Del_Dt.Value), Fields!Req_Del_Dt.Value, RowNumber(Nothing))
I had the same issue that Loki70 had and really liked Nanu's solution.
However, once I saw the result I wanted to do more. I wanted to have the primary information appear once but "hide" the rows after the first row of a group. Using Nanu's and Loki70's code together I was able to set the font color of the rows after the first row to the same color as the fill. Thereby hiding the text for that cell.
=IIF(Previous(Fields!Req_Del_Dt.Value) <> (Fields!Req_Del_Dt.Value), "Black",
IIF(RunningValue(Fields!Req_Del_Dt.Value, CountDistinct, Nothing) MOD 2 = 1,
"White", "Lavender"))
I use this to hide the first couple cells of a row which display the same information, and then display the other cells that are different for that subgroup.
Public Function Setcolor(ByVal Runs AS Integer,ByVal Wickets AS Integer) AS String
setcolor="Transperent"
IF(Runs >=500 AND Wickets >=10) THEN return "Green"
END IF
END Function
here's a simple solution. first, i'm going to assume that you're working with MSSQL, since the question is about SSRS. You can select values directly from the query, so in the report itself, you just set background color according to a single value, and not a range...
let's say, you want to present in report Req_Del_Dt.Value with a different color, according to it's range.... so, you can query something like this>
select *,
case when Req_Del_Dt < 30 then 1
when Req_Del_Dt between 30 and 60 then 2
when Req_Del_Dt between 61 and 90 then 3
when Req_Del_Dt between 91 and 150 then 4
else 5 end as color_range
from source_table
having that, in SSRS, you just go to the BackgroundColor property, in the Fill section of the textbox where you're displaying req_del_det, select color expression, and write something like this>
=SWITCH(Fields!color_range.Value = 1, "#ffffff",
Fields!color_range.Value = 2, "#ffebeb",
Fields!color_range.Value = 3, "#ffd8d8",
Fields!color_range.Value = 4, "#ffc4c4",
Fields!color_range.Value = 5, "#ffb1b1")

set Datagirdviewcombobox column value in Vb.net

I have datagrid with two datagridviewcombo column, one column is dynamic fill and one has fixed hardcoded values.
The problem is I can't set the value of dynamic GridViewComboBox, when I try to set it generates continues errors.
System.FormateException: DataGridViewComboBoxCell Value is not valid.
My code to load the grid is
Dim dt As DataTable
dt = GetDataTable("Select valuecol,displayCol From mytable") 'GetDataTable gives me datatable
cmbAntibiotics.DataSource = dt
cmbAntibiotics.DisplayMember = "Antibiotics"
cmbAntibiotics.ValueMember = "AntibioticsID"
Dim Index As Integer
Dim dgr As DataGridViewRow
For Each dr As DataRow In dtFromDB.Rows 'This datatable is filled with database
Index = dtFromDB.Rows.Count - 1
GRDAntimicrobials.Rows.Add()
GRDAntimicrobials.Rows(Index).Cells("cmbAntibiotics").Value = dr("AntibioticsID").ToString 'At this point it shows value (1,2,3) rather then showing its display members
GRDAntimicrobials.Rows(Index).Cells("AntibioticsStatus").Value = dr("AntibioticsStatus").ToString
Next
Pls help with me
It seems like you're trying to assign the value to whatever there is on the cell rather than instantiate the object that resides in the cell and then assign its value. I would try something like this:
Dim vComboBoxColumn As DropDownList = DirectCast(GRDAntimicrobials.Rows(index).Cells("cmbAntibiotics"))
vComboBoxColumn.Value = dr("AntibioticsStatus").ToString