I am trying to change the background colour of a cell based on its contents. We are looking at grades, either 'A to U' or '9 to 1'. The cell needs to be highlighted if the grades are 2 lower than their target grade. We have it working if the cells are just numbers or just letters but not both.
Here is the Custom Code for the report:
Public Function gradeCheck(SubjectGrade AS String, TargetGrade AS String) AS String
Dim gradeValue = convertGradeToInt(SubjectGrade)
Dim targetValue = convertGradeToInt(TargetGrade)
If (targetValue - gradeValue) < -1
Return "Orange"
Else
Return "White"
End If
End Function
Public Function gradeCheckInt(SubjectGradeInt AS Integer, TargetGradeInt AS Integer) AS String
If (TargetGradeInt - SubjectGradeInt) >= 2
Return "Orange"
Else
Return "White"
End If
End Function
Public Function convertGradeToInt(grade AS String) AS Integer
Select Case grade
Case "A*"
return 1
Case "A"
return 2
Case "B"
return 3
Case "C"
return 4
Case "D"
return 5
Case "E"
return 6
Case "F"
return 7
Case "G"
return 8
Case "U"
return 9
End Select
End Function
Here is the code that works for numbers on their own or letters on their own:
Letters
= IIF(ISNOTHING(Fields!report_Grade.Value)
, "White"
, IIF(ISNOTHING(Fields!TargetGrade.Value)
, "White"
,code.gradeCheck(Fields!report_Grade.Value, Fields!TargetGrade.Value)
)
)
Numbers
= IIF(ISNOTHING(Fields!report_Grade.Value)
, "White"
, IIF(ISNOTHING(Fields!TargetGrade.Value)
, "White"
,code.gradeCheckInt(Fields!report_Grade.Value, Fields!TargetGrade.Value)
)
)
And here is what I feel should work, but is only highlighting the correct numbers, not letters:
= IIF(ISNOTHING(Fields!report_Grade.Value)
, "White"
, IIF(ISNOTHING(Fields!TargetGrade.Value)
, "White"
,IIF(IsNumeric(Fields!report_Grade.Value)
,code.gradeCheckInt(Fields!report_Grade.Value, Fields!TargetGrade.Value)
,code.gradeCheck(Fields!report_Grade.Value, Fields!TargetGrade.Value)
)
)
)
Any help would be greatly appreciated.
Thanks
It looks like your grades always come from the same column so this must be a string (even if it contains a number). If this is the case then I would modify your convertGradeToInt function by testing if the string is a value something like
Public Function convertGradeToInt(grade AS String) AS Integer
If Val(grade) > 0 then
return Val(grade)
ELSE
Select Case grade
Case "A*"
return 1
Case "A"
return 2
Case "B"
return 3
Case "C"
return 4
Case "D"
return 5
Case "E"
return 6
Case "F"
return 7
Case "G"
return 8
Case "U"
return 9
End Select
End If
End Function
Now, if the passed in value is numeric you just get the same value back, if it's a string it returns the matching grade (or zero if not match found).
Now your color expression can be simple
=IIF(Code.convertGradeToInt(Fields!TargetGrade.Value) - Code.convertGradeToInt(Fields!report_Grade.Value) >= 2 , "Orange", Nothing)
You should not need any other code, just the one function and one expression for the colour.
I may have overlooked something as it's not tested but hopefully it will give you enough to solve the problem.
Thanks to Alan above I was able to make it work. Here is the final custom code I used:
Here is the final custom code I used:
Public Function gradeCheck(SubjectGrade AS Integer, TargetGrade AS Integer) AS String
If TargetGrade - SubjectGrade >= 2
Return "Orange"
Else
Return "White"
End If
End Function
Public Function convertGradeToInt(grade AS String) AS Integer
If Val(grade) > 0 then
return Val(grade)
ELSE
Select Case grade
Case "A*"
return 9
Case "A"
return 8
Case "B"
return 7
Case "C"
return 6
Case "D"
return 5
Case "E"
return 4
Case "F"
return 3
Case "G"
return 2
Case "U"
return 1
End Select
End If
End Function
And here is the colour expression:
= IIF(ISNOTHING(Fields!report_Grade.Value)
, "White"
, IIF(ISNOTHING(Fields!TargetGrade.Value)
, "White"
, code.gradeCheck(Code.convertGradeToInt(Fields!report_Grade.Value), Code.convertGradeToInt(Fields!TargetGrade.Value))
)
)
Related
Is there any short form for writing MySQL CASE statements as in PHP switch? For example, if i have:
SELECT
CASE Type
WHEN 1 THEN "A"
WHEN 5 THEN "B"
WHEN 10 THEN "B"
WHEN 20 THEN "B"
WHEN 30 THEN "B"
WHEN 300 THEN "C"
ELSE "-"
END TypeDesc
In PHP syntax we can write it in brief:
switch ($Type) {
case 1: $TypeDesc = 'A'; break;
case 5:
case 10:
case 20:
case 30: $TypeDesc = 'B'; break;
case 300: $TypeDesc = 'C'; break;
default: $TypeDesc = '-'; }
I tried:
WHEN 5 OR 10 OR 20 OR 30 THEN "B"
and
WHEN IN(5, 10, 20, 30) THEN "B"
and these two:
WHEN 5
WHEN 10
WHEN 20
WHEN 30 THEN "B"
WHEN 5 THEN
WHEN 10 THEN
WHEN 20 THEN
WHEN 30 THEN "B"
But i get incorrect result or error!
Use
case when <condition>
instead of
case <variable> when <value>
like this
SELECT
CASE WHEN Type = 1 THEN "A"
WHEN Type < 300 THEN "B"
WHEN Type = 300 THEN "C"
ELSE "-"
END TypeDesc
I'm still new with the vba. I have an database that with the help of others peoples I've finally able to do validation check when importing. However, I can get check done with numbers as text, but if I need alpha character or if the cell is blank I'm stuck. This is what I have for numbers as text. I need two checks: 1) accept alphanumeric or blank (null) and 2)numeric or blank (null).
Function chk2(A As String) As Boolean
Dim i As Integer, l As Integer, c As String
l = Len(A)
If l = 4 Then
chk2 = True
For i = 1 To l
c = Mid(A, i, 1)
If Not (c >= "0" And c <= "9") Then
chk2 = False
Exit Function
End If
Next i
End If
End Function
This one works fine as long as there are characters to fill in each row/cell.
Thanks in advance for your help.
If you're returning a boolean value, you should only return a true value if everything has executed correctly, that way you aren't getting a false positive if something fails.
You could use a check if the cell has 0 length for a blank cell, i.e. If Len = 0
What you are doing in your If Not statement is checking if the ascii value of c is between the ascii values of 0 and 9 so you can use or statements to check if it is between a and z or A and Z or if there is a space which is character 32 - Chr(32) :
Function chk2(A As String) As Boolean
Dim i As Integer, l As Integer, c As String
chk2 = false
l = Len(A)
If l = 0 then
'do something if the cell is blank
chk2 = true
ElseIf l = 4 Then
For i = 1 To l
c = Mid(A, i, 1)
If Not ((c >= "0" And c <= "9") Or (c >= "a" And c <= "z") Or (c >= "A" And C <= "Z") Or c = Chr(32)) Then
Exit Function
End If
Next i
chk2=true
End If
End Function
I have a function that converts a decimal value to binary. I understand I have the logic correct as I can get it to work outside of a function.
def decimaltobinary(value):
invertedbinary = []
value = int(value)
while value >= 1:
value = (value / 2)
invertedbinary.append(value)
value = int(value)
for n, i in enumerate(invertedbinary):
if (round(i) == i):
invertedbinary[n] = 0
else:
invertedbinary[n] = 1
invertedbinary.reverse()
value = ''.join(str(e) for e in invertedbinary)
return value
decimaltobinary(firstvalue)
print (firstvalue)
decimaltobinary(secondvalue)
print (secondvalue)
Let's say firstvalue = 5 and secondvalue = 10. The values returned each time the function is executed should be 101 and 1010 respectively. However, the values I get printed are the starting values of five and ten. Why is this happening?
The code works as expected, but you didn't assign the returned value:
>>> firstvalue = decimaltobinary(5)
>>> firstvalue
'101'
Note that there are easier ways to accomplish your goal:
>>> str(bin(5))[2:]
'101'
>>> "{0:b}".format(10)
'1010'
I have following situation:
Report with nested groups, whether group column has value 1 or 2. Next child group has 2 groups for each parent group, so for parent group 1 there is two child groups (1-1 and 1-3), and also for parent group 2 I have two child groups (2-2 and 2-4).
My question is, how to set color to WhiteSmoke for rows from 1-1, and color White for rows from 1-3, and again WhiteSmoke for 2-2 and White for 2-4.
If there is order like 1, 2, 3, ..., then will be easy with using Mod operator, but my order is 1, 3, 2, 4 and i cannot find algorithm for alternating color
EDITED
I found the answer.
=IIF(RunningValue("NameofGrouptoAlternateColor", CountDistinct, "NameofParentGroup") Mod 2, "White", "Wheat")
This worked for me and I think it's what the original poster was trying to accomplish.
=IIF(RunningValue(Fields!FieldToGroupOn.Value, CountDistinct, "ParentGroupName") Mod 2, "LightGrey", "Transparent")
Where:
FieldToGroupOn is the field in the dataset you are grouping on and wish to produce alternating colors.
ParentGroupName is the name of the row group in the tablix that is the parent of the group you wish to alternate colors for.
assuming that this is the order: 1,3,2,4,5,7,6,8... you want to color only 3,4,7,8..
Then the expression should be:
=iif(RowNumber(Nothing) Mod 4 <> 0 AND
((RowNumber(Nothing)+1) Mod 4 <> 0), "White", "WhiteSmoke")
If I understood correctly you want to alternate colors on "group change".
If so, this is the solution:
IIf(RowNumber("TheNameOfYourGroup") Mod 2 = 0, "White", "WhiteSmoke")
That's the expression you use for your Background Color property.
I've forced to use custom code to achieve your goal, here is my solution:
Custom code section
Public Shared ReverseLookup = True
Public Function GetColor(ByVal currentValue As Integer, ByVal previosValue As Integer) As String
If ReverseLookup = True
If currentValue = previosValue Then
GetColor = "Gray"
Else
GetColor = "Green"
ReverseLookup = False
End If
Else
If currentValue = previosValue Then
GetColor = "Green"
Else
GetColor = "Gray"
ReverseLookup = True
End If
End If
End Function
And in the BackgroundColor property :
=Code.GetColor(Fields!secondid.Value, Previous(Fields!secondid.Value))
input parameters are current secondid value (value from paren group of details) and previos secondid value.
And here my result:
I believe that it is exactly what you need :)
I have an object that looks like this one:
object =
title : 'an object'
properties :
attribute1 :
random_number: 2
attribute_values:
a: 10
b: 'irrelevant'
attribute2 :
random_number: 4
attribute_values:
a: 15
b: 'irrelevant'
some_random_stuff: 'random stuff'
I want to extract the sum of the 'a' values on attribute1 and attribute2.
What would be the best way to do this in Coffeescript?
(I have already found one way to do it but that just looks like Java-translated-to-coffee and I was hoping for a more elegant solution.)
Here is what I came up with (edited to be more generic based on comment):
sum_attributes = (x) =>
sum = 0
for name, value of object.properties
sum += value.attribute_values[x]
sum
alert sum_attributes('a') # 25
alert sum_attributes('b') # 0irrelevantirrelevant
So, that does what you want... but it probably doesn't do exactly what you want with strings.
You might want to pass in the accumulator seed, like sum_attributes 0, 'a' and sum_attributes '', 'b'
Brian's answer is good. But if you wanted to bring in a functional programming library like Underscore.js, you could write a more succinct version:
sum = (arr) -> _.reduce arr, ((memo, num) -> memo + num), 0
sum _.pluck(object.properties, 'a')
total = (attr.attribute_values.a for key, attr of obj.properties).reduce (a,b) -> a+b
or
sum = (arr) -> arr.reduce((a, b) -> a+b)
total = sum (attr.attribute_values.a for k, attr of obj.properties)