SSRS =Switch not altering text - tsql

Can anyone please help explain why when the first switch value is 0 it will change to red, but when it is the text value "Expired" (altered with a CASE WHEN in the query) the text remains black.
This does not work:
=Switch(Fields!Days_Until_Expiry.Value = "Expired", "Red"
, Fields!Days_Until_Expiry.Value > 1 AND Fields!Days_Until_Expiry.Value < 90, "Orange"
, Fields!Days_Until_Expiry.Value > 90, "Green")
, CASE
WHEN DATEDIFF(d, c.Date_Expiration, SYSDATETIME()) > 0
THEN 'Expired'
[...]
This does work:
=Switch(Fields!Days_Until_Expiry.Value = 0, "Red"
, Fields!Days_Until_Expiry.Value > 1 AND Fields!Days_Until_Expiry.Value < 90, "Orange"
, Fields!Days_Until_Expiry.Value > 90, "Green")
, CASE
WHEN DATEDIFF(d, c.Date_Expiration, SYSDATETIME()) > 0
THEN 0
[...]
This is going to be a simple explanation I haven't been able to find, isn't it...
[EDIT]:
Seems the problem is in the query.
, CASE
WHEN DATEDIFF(d, c.Date_Expiration, SYSDATETIME()) > 0
THEN 'Expired'
ELSE ABS(DATEDIFF(d, c.Date_Expiration, SYSDATETIME()))
END AS Days_Until_Expiry
How can I make this query work and have SSRS pick up both the returned int values and the text string?

From what I see the switch statement is unable to determine whether Days_Until_Expiry is returning a string or an int. Ideally (depending on your version of SSRS) you should have seen a #Error instead of just a blank textbox.
I tried to recreate this (in SSRS 2008R2) but I ended up seeing the #Error in the textbox with an error message in my output window:
The Value expression for the textrun ‘Textbox3.Paragraphs[0].TextRuns[0]’ contains an error: Input string was not in a correct format.
When you updated your CASE statement so that Days_Until_Expiry always returns an int the Switch was able to evaluate all conditions correctly.
[Edit]: If you are trying to get string and int values into SSRS so that you can further evaluate the status to be "Red", "Orange" or "Green", you can combine the CASE and SWITCH logic into to the CASE statement as follows:
CASE
WHEN DATEDIFF(d, c.Date_Expiration, SYSDATETIME()) > 0
THEN 'Red'
WHEN ABS(DATEDIFF(d, c.Date_Expiration, SYSDATETIME())) > 1 AND ABS(DATEDIFF(d, c.Date_Expiration, SYSDATETIME())) < 90
THEN 'Orange'
ELSE 'Green'
END AS Days_Until_Expiry
You can then directly display Days_Until_Expiry without using any SWITCH statement. Let me know if I am missing something.

Related

Conditional formatting for a cell in a Table in my report

I’m trying to use conditional formatting for a fill color in a table cell in a report. The statement I’m using is:
IIF (GETDATE() >= (DATEADD(day, 25, B6CONDIT.B1_CON_ISS_DD)) AND (GETDATE () <= (DATEADD(day, 30, B6CONDIT.B1_CON_ISS_DD)), "Yellow", "White"))
I'm getting an error when I try to apply it to my table that says:
"IIF (GETDATE() >= (DATEADD(day, 25, B6CONDIT.B1_CON_ISS_DD)) AND (GETDATE () <= (DATEADD(day, 30, B6CONDIT.B1_CON_ISS_DD)), "Yellow", "White")) is not valid color."
What am I doing wrong?
Thanks!
Phil R
I've made sure that my parentheses are matched and I know that Yellow and White are valid colors.

SWIFT Variable used before being initialized [duplicate]

This question already has answers here:
Variable used before being initialized in function
(6 answers)
Closed 4 years ago.
I want to know why this code will not run. The error appears on the very last line (the print statement) (the last "letter grade") and says
"Variable 'letterGrade' used before being initialized"
let score = 86
var letterGrade: Character
if(score >= 90)
{
letterGrade = "A"
}
else if(score >= 80)
{
letterGrade = "C"
}
else if (score >= 70)
{
letterGrade = "C"
}
else if (score >= 60)
{
letterGrade = "D"
}
else if (score > 0)
{
letterGrade = "F"
}
print("Your letter grade is \(letterGrade)")
Yes, it is used before being assigned a grade (the compiler does not know that you've covered all the cases in your if statements before throwing this error - and in fact you haven't covered zero as #MartinR tells you ).
You could have a default value (in the UK a "U" is ungraded) by changing line 2 to
var letterGrade: Character = "U"
and better still use type inference to say
var letterGrade = "U"
You might also like to use a switch for this type of problem - look in the Swift documents using this link - https://docs.swift.org/swift-book/LanguageGuide/ControlFlow.html
But here is my version of your code using a switch
let score = 86
var letterGrade: Character
switch score {
case 90 ..< 100:
print("A")
case (80 ..< 90):
print("B")
case (70 ..< 80):
print("C")
case (0 ..< 70):
print("D")
default:
print("F")
}
This overcomes the problem of your compiler error.
Hope this helps you.
You cannot use a variable before initializing it (giving it an initial value).
You handled the cases where score >= 90 and score >= 80 and score >= 70 and score >= 60 and score > 0.
What if score was equal to 0? this case isn't handled, if it happened the variable letterGrade will stay uninitialized.
To fix this, you can use the answer by #stevenpcurtis, or you can replace the last else if statement with else only.
Also consider using a switch statement with a default case.

Query using "CASE WHEN" statement in WHERE causes QuerySyntaxException: unexpected AST

I'm trying to make a query using Spring Data, but I cannot make it work:
#Query(SELECT t FROM Thing t WHERE name LIKE :name AND CASE WHEN (:minVal <= 0) THEN TRUE ELSE (val <= :minVal) END AND CASE WHEN (:maxVal <= 0) THEN TRUE ELSE (val >= :maxVal) END)
Page<Thing> getThings(#Param("name") String name, #Param("maxVal") int maxVal, #Param("minVal") minVal);
StackTrace:
Caused by: java.lang.IllegalArgumentException:
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST
node: CASE near line 1, column 49 [SELECT t FROM Thing t WHERE name
LIKE :name AND CASE WHEN (:minVal <= 0) THEN TRUE ELSE (val <=
:minVal) END AND CASE WHEN (:maxVal <= 0) THEN TRUE ELSE (val >=
:maxVal) END] at
org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1750)
at
org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
at
org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683)
at
org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:331)
at sun.reflect.GeneratedMethodAccessor40.invoke(Unknown Source) at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606) at
org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:334)
at com.sun.proxy.$Proxy83.createQuery(Unknown Source) at
org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:78)
... 207 more
Caused by:
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST
node: CASE near line 1, column 49 [SELECT t FROM Thing t WHERE name
LIKE :name AND CASE WHEN (:minVal <= 0) THEN TRUE ELSE (val <=
:minVal) END AND CASE WHEN (:maxVal <= 0) THEN TRUE ELSE (val >=
:maxVal) END] at
org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:91)
at
org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:109)
at
org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:284)
at
org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
at
org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:158)
at
org.hibernate.engine.query.spi.HQLQueryPlan.(HQLQueryPlan.java:126)
at
org.hibernate.engine.query.spi.HQLQueryPlan.(HQLQueryPlan.java:88)
at
org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:190)
at
org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:301)
at
org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:236)
at
org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1800)
at
org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:328)
I'm using this because I want to make a longer query using five filters at least, and I want to simplify the effort of doing the filter combinations making differents querys.
Don't know if there is a different (and better) way to do what I want, glad to ear it if it is.
Thank you.
EDIT: Using native query works fine, but isn't compatible with pagination yet...
It looks like Hibernate cannot evaluate the result of a CASE expression when it returns a boolean literal directly. A workaround is to make the CASE expression part of another expression, e.g. by comparing it to another boolean literal.
So instead of:
... AND CASE WHEN (:minVal <= 0) THEN TRUE ELSE (val <= :minVal) END
Try:
... AND (CASE WHEN (:minVal <= 0) THEN TRUE ELSE (val <= :minVal) END) = TRUE
But looking at that expression, wouldn't it be simpler to just do:
... AND (:minVal <= 0 OR val <= :minVal)
Is it not equivalent?

Filtering in SSRS

I'm trying to filter my parameters in a condition where I have it choose a record when a multiple selection ListBox is selected. If a person doesn't select a record it by default chooses the "Not Selected" option. The issue is:
=IIF(
InStr(Join(Parameters!ProvinceID.Value,”,”),0),
True,
IIF(
InStr(Join(Parameters!ProvinceID.Value,”,”),
Fields!ProvinceID.Value
)<>0,
True,
False)
)
The result wont allow the Proper filter.
InStr(Join(Parameters!ProvinceID.Value,”,”),0)
Shouldn't that 0 be "0"
Try:
=IIf(
InStr(Join(Parameters!ProvinceID.Value, ", "), "0") > 0
,True
,IIf(
InStr(Join(Parameters!ProvinceID.Value, ", "), Fields!ProvinceID.Value) > 0,
,True
,False
)
)
InStr will return an integer value of the position where the string searched for starts (if found). Therefore your boolean tests (1st argument of the IIf() function) need to determine if a number equal to or greater than 1 has been returned.
As you are searching for a string, the 0 being searched for in the string must be coded as "0".
If Fields!ProvinceID.Value returns an integer, then it too must be converted to a string using the CStr() function like so:
=IIf(
InStr(Join(Parameters!ProvinceID.Value, ", "), "0") > 0
,True
,IIf(
InStr(Join(Parameters!ProvinceID.Value, ", "), CStr(Fields!ProvinceID.Value)) > 0,
,True
,False
)
)
What are you comparing to? Usually the IIF needs something like =IIF(Fields!ListBox1.Value = "value", "option1", "option2")
=IIF(Fields!Eyes.Value = "Green", "Green", "Other Colour")

crystal reports conditional formatting for summary fields

I'm trying to create a decimal formatting formula on my summary fields. The values in the database could have 0, 1, or 2 decimal places. I've started with this:
If (CurrentFieldValue mod 1 = 0) Then
0
Else If (CurrentFieldValue mod .1 = 0) Then
1
Else
2
On a simple single data field, this works and displays the value with 0, 1, or 2 decimal places based on the data coming from my database. The same formula doesn't work for a summary field on my reports with group data. Any ideas?
Edit: Since I don't know how to format code in a comment, I'll address the suggestion of using a formula here:
Didn't work. Formula:
Sum ({myTable.dataValue}, {myTable.groupField})
then I used:
If ({#formula} mod 1 = 0) Then
0
Else If ({#formula} mod .1 = 0) Then
1
Else
2
And I still got whole numbers for everything. My rounding is set to .01 with no formula. Do I need a formula for rounding too? I still don't understand why this works on individual values but not for group summaries.
OK- it turns out this is due to our lack of understanding of the mod function :)
Everything mod 1 actually returns 0. This is the formula you need to use:
if {ER100_ACCT_ORDER.ER100_ORD_TOT} * 100 mod 100 = 0 then
0
else if {ER100_ACCT_ORDER.ER100_ORD_TOT} * 100 mod 10 = 0 then
1
else
2
:)
How about just creating a formula field instead of using the built-in summary field:
sum({mytable.myfield})
Then you can use your conditional formatting:
If ({#formula} mod 1 = 0) Then
0
Else If ({#formula} mod .1 = 0) Then
1
Else
2