Libreoffice Calc Finding MAX from a subset of results - indexing

I have a Libreoffice Calc workbook for tracking writing, with 3 sheets in it. 'Time Tracking', 'Time Summary' and 'Yearly Stats'. 'Time Tracking' is where user data is entered, 'Time Summary' is a pivot table for 'Time Tracking'; and 'Yearly Stats' shows long-term progress.
Time Summary (running off some test data) looks a bit like this:
|Column A (Weeks) | ... |Column M (Total Words)
-------+-----------------------+-----+----------------------
Row 7 |02/10/17 - 08/10/17 | |3500
Row 8 |13/11/17 - 19/11/17 | |2300
Row 9 |30/04/18 - 06/05/18 | |1000
Row 10 |30/10/17 - 05/11/17 | |700
Yearly Stats looks like this:
|A |B |C
-------+--------------------+--------+----
Row 1 | |2017 |2018
Row 2 |Total Words |6500 |1000
...
Row 7 |Max Words (Week) |3500 |3500
The formula for 'Yearly Stats'.B7:C7 is currently =MAX($'Time Summary'.$M$7:$M$10), but I need to modify it to filter by the year on the column heading.
https://ask.libreoffice.org/en/question/62260/minif-and-maxif-function-in-calc/ looked to be useful, but when I tried it, the MAX from the formula was returning the MAX of ROW - being 10 - rather than ROW returning the position of the MAX value - even though it seems to work in the example file from the link.
The example formula is:
=IFERROR(INDEX($Sheet1.$J$2:$J$13,MAX(ROW($Sheet1.$J$2:$J$13)*($Sheet1.$A$2:$A$13=A2))-1,1),NA())
My formula uses RIGHT() to compare the last two characters of the column heading with the last two chars of the week in $'Time Summary':$A$7:$A$10 and is:
=IFERROR(INDEX($'Time Summary'.$M$7:$M$10,MAX(ROW('Time Summary'.$M$7:$M$10)*(RIGHT($'Time Summary'.$A7:$A$10,2)=RIGHT(B1,2)))-6,1),NA())
I have, of course, remembered to press CTRL+SHIFT+ENTER as the instructions say, to get the array in the formula to work.
So that's the explanation of my problem. What is it that I'm getting wrong?

Ok, this is a bit long-winded, but I've managed to solve the problem by using the following formula:
=IF(MAX(IF(RIGHT(INDIRECT(CONCATENATE("$'Time Summary'.$A7:$A$",COUNTIF($'Time Summary'.$A:$A,"<>''")+2)),2)=RIGHT(B1,2),INDIRECT(CONCATENATE("$'Time Summary'.$Q$",ROW(INDIRECT(CONCATENATE("$'Time Summary'.$Q7:$Q$",COUNTIF($'Time Summary'.$Q:$Q,"<>''")+5))))),0))>0,MAX(IF(RIGHT(INDIRECT(CONCATENATE("$'Time Summary'.$A$7:$A$",COUNTIF($'Time Summary'.$A:$A,"<>''")+2)),2)=RIGHT(B1,2),INDIRECT(CONCATENATE("'Time Summary'.$Q",ROW(INDIRECT(CONCATENATE("$'Time Summary'.$Q$7:$Q$",COUNTIF($'Time Summary'.$Q:$Q,"<>''")+5))))),0)),NA())
It is wrapped in an IF that replaces any 0 result with '#NA' (just for neatness of output).
Also the right half of the ranges specified make use of a calculation to figure out where the bottom row is, leaving out the total, so that's another reason it's so huge.

Related

LINQ - Select rows based on whether their sum meets a condition

I’ve run into a problem, as I cannot get a proper working LINQ statement here.
Suppose I have a DataTable with x rows and I have to sort based on the sum of the Quantity column. Then I have a condition Requested Quantity = 20. I need to find the rows equal to the exact sum of RequestedQuantity, but only where the combination of 3 rows is equal to it.
+-----+----------+
| Bin | Quantity |
+-----+----------+
| 1 | 10 |
| 2 | 5 |
| 3 | 5 |
| 4 | 10 |
| 5 | 15 |
+-----+----------+
I can’t seem to figure out the proper LINQ syntax to get this to work. My starting point is this:
From row In StorageBins.AsEnumerable.GroupBy( _
Convert.ToDouble(Function (x) x("Quantity"), cultureInfo)).Sum( _
Function (y) Convert.ToDouble(y("Quantity"), cultureInfo) = _
Double.Parse(RequestedQuantity,cultureInfo))
Initially, I am just trying to get any rows that are equal to my condition. My end-goal, however, is getting any three rows that exactly sum up to my Requested quantity.
I’m not an expert in LINQ, unfortunately. I hope some of you might be!
Maybe I'm missing something, but this actually seems like a pretty complicated problem. Pick any 3 records, but only 3, that add up to exactly 20. How many rows are there in the database? Because this could get to be quite a few potential combinations pretty quickly. And what do you do after you get the 3? Do you have to go back through recursively and group up the other records as well? Or you just need the first set of 3 that add up to 20?
Assuming you just need the first 3, I would do something like this:
Get the first record that is less that 20. Remove it from your input list and put it into your target set.
Then get the first record that is less than 20 minus the first value. ie if the first value was a '5', get records that are less than 15 (20 minus 5). This ensures you 'leave room' for the third value. Remove it from the original list and into your target set.
Then get the first record that is exactly 20 minus number one minus number two. Remove it from the input list and into the target set.
Now you would have to do this in iterators. If there is no value that meets the third criterion, release the third value from your target set and put it back in your input list. Then go back to step 2 and pick the next record that matches step 2 (and ideally that is not equal to the previous value). And if you exhaust all of the iterations through step 2, go back to step one and pick the next value there, and start the whole thing over again...
Unless I'm misunderstanding your requirement...

QlikView - Struggling to produce Bubble / scatter from record-data

I would like to make a Bubble-scatter where the data looks like:
Each row is an 'event', with a Day of the event and the event's grade
Day | Grade
------------
1 | A
1 | A
1 | B
1 | (empty)
1 | B
2 | A
I want this to turn into a bubble graph that looks like :
Day along the X-axis ( 1, 2)
On Y-axis I would like to see A,B (vertically)
And I would expect
one big bubble for day-1 A
one big bubble for day-2 A
one little bubble for day-2 A
Given the data above
It is either refusing to display anything at all saying 'undefined values'
I'm really struggling to understand how this bubble/scatter works, and the documentation isn't helping
It asks for Dimension, Measure, Measure and I am putting in many variations of Day, Count(Grade) and Avg(Grade)
Bubble charts are a bit tricky.
In your case you need 2 dimensions: dimension 1 (Grade) and dimension 2 (Day).
Expression is as simple as sum(1) (take into account that you are already double-filtering the data because you have 2 dimensions). To avoid extra bubbles due to the Null entries, just select "ignore null values" in the dimension panel options.

how to calculate a rolling average based on a column in spotfire

I have a data set where you have a Document Property that Selects "items", each "item" has a particular "usage days". I want to calculate an output of "Moving Average" for 1 or more selected items. the data for the moving average lives under a column named "usage days".
How do I calculate this taking into account the "selected date of my choice" and the rolling average number of days of my choice.
Do you have particular ideas of how I can perform the calculation i.e. in a calculated column or a text field?
Car/ Trip / Start Date/ End Date / Days on trip
1 AB123 / 2 / 6/07/2013
1 AB234 / 29/07/2013 / 6/09/2013 / 42
1 AB345 /6/09/2013 /28/09/2013 /22
1 AB456 /29/09/2013 /21/10/2013 /23
2 AB567 / 26/10/2013 / 12/11/2013 / 22
2 AB678 /12/11/2013 /8/12/2013 /26
[The rows above have an example of the problem (sorry couldn't paste an image because im new), I want to calculate the %usage of the Car and or cars for a selected range of time e.g (Select date range JUlY to AUGUST then (#of days on trip for car 1and 2)/#on days in that period)/2*100]
As phiver said, it is still difficult to see what you expect as a result... but I think I have something that might work. First, I slightly altered the dataset you provided, like so:
car trip startDate endDate daysOnTrip
1 AB123 7/6/2013 7/29/2013 23
1 AB234 7/29/2013 9/6/2013 42
1 AB345 9/6/2013 9/28/2013 22
1 AB456 9/29/2013 10/21/2013 23
2 AB567 10/26/2013 11/12/2013 22
2 AB678 11/12/2013 12/8/2013 26
I then added 2 document properties, "DateRangeFirst" and "DateRangeLast", to allow the user to select beginning and ending dates. Next I made input box property controls for each of the aforementioned document properties in a text area so the user can alter the date range. I then added a datatable visualization with a "Limit data using expression:" of "[startDate] >= Date(${DateRangeFirst}) and [endDate]<= Date(${DateRangeLast})" so we could see the trips selected. Finally, to get the average you appear to be looking for, a barchart set to % of total (daysOnTrip) / car with the same data limiting expression as above. The below screenshot should have everything you need to reproduce my results. I hope this gives you what you need.
NOTE: With this method if you select a date in the middle of a trip, an entire row and all of the days on that trip will be ignored.

Table Total Column based on cell values - SQL Report Builder 3.0

I have a table built off a dataset containing timesheet data with possible multiple entries per day (day_date) for a given person. The table is grouped on day_date. The field for hours is effort_hr (see dataset and report layout below).
The table generates a single row with one column for each day (as expected).
For each day I want only one value (total hours for person) so the expression is Sum(Fields!effort_hr.Value) This is properly adding up all the hours for each day.
Now I add a total column at the end of the row to see ALL the hours for the whole timesheet. The expression in the total column cell is Sum(Fields!effort_hr.Value) which is exactly the same as the daily ones. Again, this is adding up all hours for the timesheet.
So this is working great.
I now need a new row that only shows a max of 8 hours per day. So if the person works less, it shows less, but if the person works more, show a max of 8.
In this case, the daily column expression is:
IIF(Sum(Fields!effort_hr.Value)>8.0,8.0,Sum(Fields!effort_hr.Value))
And again, it displays perfectly for each day.
The total for this row is where I run into trouble. I have tried so many ways, but I cannot get the total for the columns in this row. The report keeps showing an #Error in the cell. The report saves fine and there is no error in the expr.
The problem seems to come from the fact that there are 2 values for a given day. So in other words, for 5 days, the person has 6 entries. When I try it for a person with only 5 entries, no problem.
I have tried:
Sum(IIF(Sum(Fields!effort_hr.Value)>8.0,8.0,Sum(Fields!effort_hr.Value)))
RunningValue(IIF(Sum(Fields!effort_hr.Value)>8.0,8.0,Sum(Fields!effort_hr.Value)),Sum,Nothing)
I either get an #Error, or I get the wrong total. Is there any way to just get a total for the cell values in the table? The daily numbers are correct, just give me the total at the end (like Excel).
I could do this in the SQL, but that would mess up other parts of this report.
DataSet:
res_name | day_date | effort_hr
J. Doe | Apr 6, 2015 | 2
J. Doe | Apr 6, 2015 | 9
J. Doe | Apr 7, 2015 | 8
J. Doe | Apr 8, 2015 | 7
J. Doe | Apr 9, 2015 | 10
J. Doe | Apr 10, 2015 | 9
REPORT TABLE Layout:
| Apr 6 | Apr 7 | Apr 8 | Apr 9 | Apr 10 | Totals
Total | 11 | 8 | 7 | 10 | 9 | 45
Reg | 8 | 8 | 7 | 8 | 8 | 39
OT | 3 | 0 | 0 | 2 | 1 | 6
Problem:
Row 1 Column Total works great and gives 45 hours ;
Row 2 Column Total either gives #Error, 41, or some other wrong number - just need it to total the actual values of each cell in the row ;
same problem for Row 3 total
Thanks in advance for your time!
Posting another answer as the previous one has become so long.
I referred to this MSDN link, and used the selected answer. Apparently we need to use custom code to achieve this (if you are not willing to change your dataset and have the calculated values in there).
Right click on report --> report properties --> Go to tab 'Code' --> Paste this
Dim public nettotal as Double
Public Function Getvalue (ByVal subtotal AS Double) AS Double
nettotal = nettotal+ subtotal
return subtotal
End Function
Public Function Totalvalue()
return nettotal
End Function
In the row group expression of second row put
= code.Getvalue(IIF(Sum(Fields!Efforts.Value)>8.0,8.0,Sum(Fields!Efforts.Value)))
In the Total cell expression (for second row) put
=code.Totalvalue()
Save and run, you should see following result.
I used your input data and tried to create the report in given format. I used following function for Row 2 Total
=Sum(IIF(Fields!Efforts.Value>8.0,8.0,Fields!Efforts.Value),"DataSet1",Recursive)
This shows sum as 39 for second row. You can try and let me know if it works for you. If it doesn't I will list the exact steps how I created Matrix and groups.
Note: Don't forget to put your dataset name in the second argument of function Sum. And Recursive, as clear by name, applies Sum recursively for the group.
Update: I followed following steps.
1. Add a Matrix on the report.
2. Under Column group section on Matrix, Select any column name from the dataset. (Otherwise it won't show any columns in the next step)
2. Right click Column --> Add Group --> (Under column group) Add Parent Group. Select Day as Group By --> OK. It will create a new row. Put expression Sum(Efforts) in first row. And your expression =IIF(Sum(Fields!Efforts.Value)>8.0,8.0,Sum(Fields!Efforts.Value)) in the second row.
Right click on the column group section in the group pane --> Select Add Total --> After. It will add new column at the end of Matrix. Put expression Sum(Efforts) in first row and expression =Sum(IIF(Fields!Efforts.Value>8.0,8.0,Fields!Efforts.Value),"DataSet1",Recursive) in the second row.
Save and run you should see following in the report.
Remember to change the names of columns and dataset as par your code.
This is an idea on how to do such grouping, obviously you'd need to do changes for the headers and the 3rd row etc.
HTH.

Highlighting Values in a Crystal Reports Crosstab based on sibling values

I have crosstab which has row columns indicating different classes, and then peoples names across the top.
| | Required | Person 1 | Person 2 | Person 3 |
| Class 1 | 8 6 | 1 6 | 3 6 | 4 6 |
| Class 2 | 6 2 | 3 2 | 2 2 | 1 2 |
Each field contains 2 values The first value is the number of hours spent in the class, the second field is the number of hours required for certification.
The Required field id my grand total summary.
In the cross tab expert the fields are defined as follows.
Rows:
Command.descr -> a field containing the class names
Columns:
Command.fullname -> a field containing students full names
Summarized Fields:
Sum of Command.evlength -> summation of all time spent in a given course
Max of #required -> this formula returns the number of required hours based on the course name
I am trying to highlight the field Sum of Command.evlength if it is greater than or equal to the value of Max of #required.
My solution was to perform background formatting. Right-Click on the Sum of Command.evlength field, select Format Field. Click the borders tab, check Background, and enter a formula.
The formula I was using is:
if CurrentFieldValue >= {#required} then color(152, 251, 152) else crNoColor
This is not the correct formula. My crosstab has been placed in the footer, which causes {#required} to contain the last value in the grid which in the above example is 2.
From my research I thought I would have to use GridRowColumnValue(row or column name) to access the value of {#required} in the crosstab, but I could not come up with the correct string to represent it.
Does anyone have a way for me to correctly perform this comparison?
Frustratingly I don't think you can use the highlighting expert to compare to a dynamic value. You could swap the columns round then add the following formulas:
To the max_of_required background colour:
whileprintingrecords;
global numbervar required_hrs := currentfieldvalue;
crNoColor;
To the sum_of_command.evlength background colour:
whileprintingrecords;
global numbervar required_hrs;
if currentfieldvalue >= required_hrs then
crRed
else
crNoColor;
I think there are a few other ways but i'm not as confident with those so start here.