Lookupset with duplicate records SUM not working SSRS 2008 - sum

I have the below data in a dataset called Questions and all IDs in another dataset called Dataset1
ID Answer
1 Yes
2 Yes
2 No
2 Yes
3 No
My expected output should be as below
ID Yes No
1 1 0
2 2 1
3 0 1
I am trying to match the ids from Dataset1 and get the Answer from Questions dataset.
If I just use Lookup, it is just checking the first match and ignoring the second record. For eg, in the above data, for ID-2, it is checking the first record with id 2 and counting 'Yes' and ignoring the other 'No' and 'Yes'
=Sum(iif(Lookup(Fields!ID.Value, Fields!ID.Value, Fields!answer.Value, "Questions") = "Yes", 1, 0))
I want to count all Yes and No like shown in the expected output above
I have tried using Lookupset but I couldn't get it working. Is there any easier way without using custom code. If custom code is necessary, could you please advise on how to achieve this.
Thank you in advance.

Why do you need a second dataset?
Have a matrix on the questions dataset, row grouped by ID then use a sum in each column as follows:
=SUM(IIF(Fields!answer.Value="Yes",1,0))
=SUM(IIF(Fields!answer.Value="No",1,0))

You can count the output from a lookupset by using the following custom code:
Function CountAnswers(ByVal AnswerArray As Object(), Answer As string) As Object
If AnswerArray Is Nothing Then Return cint(0)
If Answer Is Nothing Then Return "Nothing"
Dim TotalCount As Decimal = New Decimal()
Dim AnswerPosition As Decimal = New Decimal()
TotalCount = 0
For AnswerPosition = 0 to AnswerArray.GetUpperBound(0)
TotalCount = Switch(IsNothing(AnswerArray(AnswerPosition)),TotalCount, cstr(AnswerArray(AnswerPosition))=Answer,TotalCount + 1, TRUE,TotalCount)
Next
return TotalCount
End Function
Then enter the following under "Yes" and "No" on a matrix on Dataset1:
Code.CountAnswers(Lookupset(Fields!ID.Value, Fields!ID.Value, Fields!answer.Value,"Questions"),"Yes")
Code.CountAnswers(Lookupset(Fields!ID.Value, Fields!ID.Value, Fields!answer.Value,"Questions"),"No")

Related

Single cell string to list to multiple rows

I have a pandas data frame,
Currently the list column is a string, I want to delimit this by spaces and replicate rows for each primary key would be associated with each item in the list. Can you please advise me on how I can achieve this?
Edit:
I need to copy down the value column after splitting and stacking the list column
If your data frame is df you can do:
df.List.str.split(' ').apply(pd.Series).stack()
and you will get
Primary Key
0 0 a
1 b
2 c
1 0 d
1 e
2 f
dtype: object
You are splitting the variable List on spaces, turning the resulting list into a series, and then stacking it to turn it into long format, indexed on the primary key, along with a sequence for each item obtained from the split.
My version:
df['List'].str.split().explode()
produces
0 a
0 b
0 c
1 d
1 e
1 f
With regards to the Edit of the question, the following tweak will give you want you need I think:
df['List'] = df['List'].str.split()
df.explode('List')
Here is a solution.
df = df.assign(**{'list':df['list'].str.split()}).explode('list')
df['cc'] = df.groupby(level=0)['list'].cumcount()
df.set_index(['cc'],append=True)

IF OR Statements which always evaluate to TRUE

Recently I found an error which was due to the way I constructed an IF OR statement.
The original statement:
If a = 1 OR 2 OR 3 Then
`Execute code 1`
`Else if a = 4 OR 5 OR 6 Then`
`Execute code 2`
`Else`
`Do nothing`
The corrected code:
If a = 1 OR a = 2 OR a = 3 Then
`Execute code 1`
`Else if a = 4 OR a = 5 OR a = 6 Then`
`Execute code 2`
`Else`
`Do nothing`
So, the issue was the first part of the IF statement would always evaluate true regardless of the value of a, because it also evaluates the boolean value of the number 2, which is true. So simply spelling out that each number should be compared to the value of a fixes that issue.
My questions are:
1. When using an if statement and you have a comparative operation ( if a =1) followed by "OR 2", in what situation would you actually want to look at the boolean value of the number versus comparing the number against the value of the previously referenced variable?
Is there a way to identify if statements present in the code which will logically ALWAYS be true (and probably have a error)?
Edit: the_lotus pointed out that the boolean value of each number was not being evaluated but bitwise operations were performed between all the values and then a boolean evaluation was performed on the result. In this particular case it may be possible for it to evaluate either true or false depending on the value of a, though I am still interested in identifying if statements which always evaluate true.
As per your Edit, since you want to check if the value of A falls within a range, what you could do is store the ranges as an array and perform IndexOf to see if the value of A is in the collection.
Here is a quick example:
Dim a As Integer = 4
Dim collection1() As Integer = {1, 2, 3}
Dim collection2() As Integer = {4, 5, 6}
If Array.IndexOf(collection1, a) > -1 Then
Console.WriteLine("a = 1, 2, or 3")
ElseIf Array.IndexOf(collection2, a) > -1 Then
Console.WriteLine("a = 4, 5, or 6")
Else
Console.WriteLine("a is not a value between 1-6")
End If
Fiddle: Live Demo

Business Objects CountIf by cell reference

So I have a column with this data
1
1
1
2
3
4
5
5
5
how can I do a count if where the value at any given location in the above table is equal to a cell i select? i.e. doing Count([NUMBER]) Where([NUMBER] = Coordinates(0,0)) would return 3, because there are 3 rows where the value is one in the 0 position.
it's basically like in excel where you can do COUNTIF(A:A, 1) and it would give you the total number of rows where the value in A:A is 1. is this possible to do in business objects web intelligence?
Functions in WebI operate on rows, so you have to think about it a little differently.
If your intent is to create a cell outside of the report block and display the count of specific values, you can use Count() with Where():
=Count([NUMBER];All) Where ([NUMBER] = "1")
In a freestanding cell, the above will produce a value of "3" for your sample data.
If you want to put the result in the same block and have it count up the occurrences of values on that row, for example:
NUMBER NUMBER Total
1 3
1 3
1 3
2 1
3 1
4 1
5 3
5 3
5 3
it gets a little more complicated. You have to have at least one other dimension in the query to reference. It can be anything, but you have to be counting something in conjunction with the NUMBER dimension. So, the following would work, assuming there's another dimension in the query named [Duh]:
=Count([NUMBER];All) ForAll([Duh])

Report Builder 3.0 How to filter on different columns

I have a parameter in my report (Report Builder 3.0) called REPORT_FILTER. This parameter has 4 available values. The labels are (1) Home Group, (2) Home Branch, (3) Other Group, and (4) Other Branch. The corresponding values are 1, 2, 3, and 4.
The SQL used to run this report adds "1" to the "Filter1" column for the Home Group and "2" to the "Filter1" column for the Other Group.
The SQL used to run this report adds "1" to the "Filter2" column for the Home Branch and "2" to the "Filter2" column for the Other Branch.
When the SQL runs, I get 1 or 2 in the "Filter 1" and "Filter 2" columns. This data is just what I expect.
What I would like to do is add a filter to the report so the user only gets the records they want. What I'm struggling with is that the filter(s) will have to use 2 columns and I'm not sure how to do that.
For example, if the user selects, Home Group (value = 1), the report should only return those records that have a 1 in the Filter1 column
If the user selects, Other Branch (value = 4), the report should only return those records that have a 2 in the Filter2 column
This report already takes a while to run several minutes, so (I think) I would prefer to filter the results in Report Builder instead of with the SQL. If I could do it with SQL, that would be acceptable. I've tried to write SQL to do this but haven't been able to succeed as well.
Any suggestions would be appreciated. Thanks for the help.
Pretty easy to do in SQL, just add this WHERE condition:
WHERE
CASE
WHEN
#REPORT_FILTER = 4 and Filter2 = 2 then 1
WHEN
#REPORT_FILTER = 3 and Filter2 = 1 then 1
WHEN
#REPORT_FILTER = 2 and Filter1 = 2 then 1
WHEN
#REPORT_FILTER = 1 and Filter1 = 1 then 1
ELSE 0
END = 1
And similarly in SSRS, just use a Filters expression of
(Parameters!REPORT_FILTER.Value = 4 And Fields!Filter2.Value = 2)
OR
(Parameters!REPORT_FILTER.Value = 3 And Fields!Filter2.Value = 1)
OR
(Parameters!REPORT_FILTER.Value = 2 And Fields!Filter1.Value = 2)
OR
(Parameters!REPORT_FILTER.Value = 1 And Fields!Filter1.Value = 1)
Set the expression type to Boolean and set the comparison value to True.

Sum variables in VBA

I have found myself into an issue that looked so simple and stupid at the beginning but keeps me struggling to solve it for over 24 hours now.
I have a string (bunch of numbers delimited by |) that I want to be converted into array and then sum some of the array keys depending on the case.
The first issue I have found was the Integer length limitation, I couldn't believe when VBA was unable to return a number higher than 32767 (Then I found longs...). After "solving" that I found that when trying to SUM some 0 values it actually increase my grand total and I can't find any explanation for this.
Below you can see what I have now:
Public Function calcTime(TimeType As String)
Dim jsSting As String
Dim strSplit As Variant
Dim tempTime as Double
jsSting = "100|0|10080|400|0|4320|70|0|1440|30|0|2280|10|0|7400|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|300|0|15855|90|0|1721"
'Split the string by delimiter
strSplit = Split(jsSting, "|")
Select Case UCase(TimeType)
Case "TOTAL"
tempTime = WorksheetFunction.Sum(strSplit(2), strSplit(5), strSplit(8), strSplit(11), strSplit(14), strSplit(17), strSplit(20), strSplit(23), strSplit(26), strSplit(29), strSplit(32), strSplit(35), strSplit(38))
Case "GROUP1" ' Team 1 + Team2
tempTime = WorksheetFunction.Sum(strSplit(2), strSplit(5), strSplit(8), strSplit(11), strSplit(14))
Case "GROUP2" ' Team 1 + Team2 + Team3
tempTime = WorksheetFunction.Sum(strSplit(2), strSplit(5), strSplit(8), strSplit(11), strSplit(14), strSplit(38))
Case "GROUP3" ' Team 5
tempTime = WorksheetFunction.Sum(strSplit(17), strSplit(20), strSplit(23), strSplit(26))
Case "GROUP4" ' Team 2
tempTime = strSplit(14)
Case "GROUP5" ' Team 6
tempTime = WorksheetFunction.Sum(strSplit(29), strSplit(32), strSplit(35))
End Select
Return tempTime
End Function
In this example I have tried to use Excel's SUM function in order to get the desired result but It wasn't a success.
Sticking to the TOTAL case. It sums the following keys - values:
jsString(2) - 10080
jsString(5) - 4320
jsString(8) - 1440
jsString(11) - 2280
jsString(14) - 7400
jsString(17) - 0
jsString(20) - 0
jsString(23) - 0
jsString(26) - 0
jsString(29) - 0
jsString(32) - 0
jsString(35) - 15855
jsString(38) - 0
This gives a total of 41375, however, when I do the sum in VBA I get 43096 and I can't understand why. If I remove from the SUM the values with 0 it returns the correct 41k value.
Hope this makes sense and the answer is simple (I am seriously thinking that I've missed something when assigning the data type).
Thank you in advance for your help !
Did you maybe mean ... ?
Select Case UCase(TimeType)
Case "TOTAL"
tempTime = WorksheetFunction.Sum(strSplit(2), strSplit(5), strSplit(8), strSplit(11), strSplit(14), strSplit(17), strSplit(20), strSplit(23), strSplit(26), strSplit(29), strSplit(32), strSplit(35), strSplit(38)
Anyway, the problem is that you're summing also strSplit(38) which is 1721 even if you wrote in your sample which is equal to 0, exactly the difference between Excel and VBA ;)
Check with a MsgBox strSplit(38) in your code.
strsplit(38) = 1721, which is the difference of 43096 and 41375