Count rows in multiple columns left to right until specific criteria is met - excel

I have the following table below. I will be referencing a specific number based on other extraneous information. Lets say the specific number is 30. I first need to count 30 numbers down my September list then move to October then November until count has reached 30. Then I need to count all the missing values until the next value would reach the 30th count from the previous task. So for this example the 30th number would be November 19th. The count of the missing should be 55, November 15th (if I counted that right). That value would then be stored in a cell.
I obtained the missed days with the following formula: =IFERROR(SMALL(IF(ISERROR(MATCH(ROW(L$1:INDEX(L:L,N$2)),M$2:INDEX(M:M,COUNT(M:M)+ROW(M$1)),0)),ROW(L$1:INDEX(L:L,N$2))),ROW()-ROW(L$1)),"") (see table 2 for column reference)
The max column value will be blank if there is no data in the month column, therefore the missed column will also have not data. I set that up with the following formula:
=IF(COUNTA(M:M)>1,31,"") (see table 2 for column reference)
Table 1
September max missed October max missed November max missed
1 30 4 1 31 2 2 30 1
2 6 3 6 7 3
3 7 4 7 9 4
5 11 5 8 10 5
8 12 12 9 11 6
9 13 15 10 16 8
10 14 20 11 17 12
15 16 28 13 18 13
22 17 30 14 19 14
23 18 31 16 20 15
24 19 17 22 21
25 20 18 27 23
29 21 19 28 24
26 21 25
27 22 26
28 23 29
30 24 30
25
26
27
29
Table 2
L M N O
(blank) September max missed
I have an idea of how I would write this, but do not know the syntax:
x = Select(Range("G8").Value)
'value that holds specific value (30 for above example)
If x < 31 Then
'30 days in September
y = Count(M2:M32) Until = x
'values in September
z = Count(O2:O32) Until = value of y - 1
'What if the last value is the 30th of September, how would you stop on August 31st?
Range("A1").Value = z
'value of z is stored in cell A1
Elseif x < 62 Then
'61 days in September and October
y2 = Count(M2:M32) & Count(Q2:Q32) Until = x
'Values in September and October
z2 = Count(R2:R32) & (S2:S32) Until =value of -1
'Again, if the last value is the 31st of October how would you stop on September 30th?
Range("A1").Value = z
'Value of z is stored in cell A1
Elseif
'continue for each month (12 times)
End If
There are a couple of things that could cause some problems here with my suggestions (that I just thought of). How would I dictate my starting month? Lets say I wanted to reference a specific cell and that cell contains the number 4. So I would want to start in April, even if I had data in March. Another way of thinking about this is March is in year 2019 and April is in 2018. So then how could I could I get the code to jump from say December back to January? Say column Z is December and column A is January. I wouldn't necessarily want my code to only read left to right. It would need to start in reference to another cell and then jump back to the start if the year changes.
I apologies for the lengthiness, but that's my best effort in explaining. Let me know if you have any questions or if I can provide anyone with more example, pictures, etc.

I think you should reorganize your data table to something like this:
Day Status
01.09.2018 ok
02.09.2018 ok
03.09.2018 ok
04.09.2018 missed
05.09.2018 ok
06.09.2018 missed
07.09.2018 missed
08.09.2018 ok
09.09.2018 ok
10.09.2018 ok
11.09.2018 missed
12.09.2018 missed
13.09.2018 missed
14.09.2018 missed
15.09.2018 ok
16.09.2018 missed
17.09.2018 missed
18.09.2018 missed
19.09.2018 missed
20.09.2018 missed
21.09.2018 missed
22.09.2018 ok
23.09.2018 ok
24.09.2018 ok
25.09.2018 ok
26.09.2018 missed
27.09.2018 missed
28.09.2018 missed
29.09.2018 ok
30.09.2018 missed
01.10.2018 ok
02.10.2018 ok
03.10.2018 ok
04.10.2018 ok
05.10.2018 ok
06.10.2018 ok
07.10.2018 ok
08.10.2018 ok
09.10.2018 ok
10.10.2018 ok
11.10.2018 ok
12.10.2018 ok
13.10.2018 ok
14.10.2018 ok
15.10.2018 ok
16.10.2018 ok
17.10.2018 ok
18.10.2018 ok
19.10.2018 ok
20.10.2018 ok
21.10.2018 ok
22.10.2018 ok
23.10.2018 ok
24.10.2018 ok
25.10.2018 ok
26.10.2018 ok
27.10.2018 ok
28.10.2018 ok
29.10.2018 ok
30.10.2018 ok
31.10.2018 missed
After that, you could easily manage your counts, find anything you want via filtering, specifying date start and so on

Related

Convert Daily dates to weekly using a specific first day of the week

I am currently working on grouping/aggregating data based on date range for a weekly plot.
Below is how my dataframe looks like for Daily data:
daily_dates
registered
attended
02/10/2022
0
0
02/09/2022
0
0
02/08/2022
1
0
02/07/2022
1
0
02/06/2022
20
06
02/05/2022
05
03
02/04/2022
15
12
02/03/2022
10
08
02/02/2022
10
05
The first day of the week I'd want is Sunday.
My current code to perform weekly group is:
weekly_df = weekly_df.resample('w').sum().reset_index()
The output I am desiring is:
weekly_dates
registered
attended
02/06/2022
22
06
01/30/2022
40
28
A bit of explanation about desired output - the reason for 02/06/2022 & 01/30/2022 is that both these dates are start date of that respective week which is a sunday. And for the week of 01/30/2022 only 02/05/2022|05|03, 02/04/2022, 02/03/2022, 02/02/2022 dates are considered as those are the one's in the daily dataframe.
My current implementation follows the instructions provided here.
I am looking for any suggestion to achieve my Desired Output
Try:
df.resample('W-SUN', label='left', closed='left').sum().reset_index()
Output:
daily_dates registered attended
0 2022-01-30 40 28
1 2022-02-06 22 6

SQL aggregating a text field based on latest date text value

I have the following script:
DROP TABLE IF EXISTS [dbo].[test]
CREATE TABLE [dbo].[test]
(
[Name] [varchar](50) NULL,
[Amount] [int] NULL
)
GO
INSERT INTO [dbo].[test]
(
[Name]
,[Amount]
)
VALUES
('Abc - 20 april to 7 june 2020',25)
,('Abc - 20 april to 7 june 2020',33)
,('Abc - 20 april to 29 june 2020',15)
,('Abc - 20 april to 29 june 2020',55)
,('Abc - 20 april to 10 may 2020',20)
,('Abc - 20 april to 10 may 2020',75)
,('Abc - 20 april to 10 may 2020',89)
GO
SELECT *
FROM [dbo].[test]
The resulting table gives the following results:
Name | Amount
-------------------------------|-------
Abc - 20 april to 7 june 2020 | 25
Abc - 20 april to 7 june 2020 | 33
Abc - 20 april to 29 june 2020 | 15
Abc - 20 april to 29 june 2020 | 55
Abc - 20 april to 10 may 2020 | 20
Abc - 20 april to 10 may 2020 | 75
Abc - 20 april to 10 may 2020 | 89
I would like to be able to determine the most recent end date in the text field and eliminate the repetitive data by grouping it showing the record with the latest end date and aggregating the amount. The result should be a single record with the following data:
Name | Amount
-------------------------------|-------
Abc - 20 april to 29 june 2020 | 312
I've played around with some group bys and text manipulation functions and this is as far as I got using the following code:
select (case when [Name] like '%-%'
then trim(left([Name], charindex('-', reverse([Name])) - 1))
else [Name]
end) as [Name]
,sum(Amount) as Amount
from [dbo].[test]
group by
(case when [Name] like '%-%'
then trim(left([Name], charindex('-', reverse([Name])) - 1))
else [Name]
end)
The above code doesn't really do so much as to just aggregate unique records only. I was looking for something more intelligent that will find and recognize that all of my records really mean the same thing and that the latest end date in the Name field is 29 june 2020 and will only display that single record with the total aggregated Amount.
Any help would be much appreciated.

Aging Bucket DAX formula issue

I have a table as stated below,
MEM_ID dateDiff
4522 10
111 1
1112 -1
1232 5
121135 20
145 30
12254 60
I want a Dax formula which will give the output as stated below under measure column as
MEM_ID dateDiff Measure
4522 10 0-15 Days
111 1 0-15 Days
1112 -1 <0 Days
1232 5 0-15 Days
121135 20 15-30 Days
145 30 15-30 Days
12254 60 >60 Days
I have used this formula which didnt worked, any help much appriricated =IF(MAX([DateDiff]) <= 1, "0", IF(MAX([DateDiff])>=1 && MAX([DateDiff])<15,"1-15 Days",IF(MAX([DateDiff])>=15 && MAX([DateDiff])<30,"15-30 Days",IF(MAX([DateDiff])>=30 && MAX([DateDiff])<60,"30-60 Days",IF(MAX([DateDiff])>=60 && MAX([DateDiff])<90,"60-90",BLANK())))))
Using a lookup-table like Ian Ash suggests is better, but if you must use an IF formula, Try the formula you have, but delete the MAX functions.
=IF([DateDiff]< 1, "0",
IF([DateDiff]>=1 && [DateDiff]<15,"1- 15 days",
IF([DateDiff]>=15 && [DateDiff]<30,"15-30 Days",
IF([DateDiff]>=30 && [DateDiff]<60,"30-60 Days",
IF([DateDiff]>=60 && [DateDiff]<90,"60-90",
BLANK())))))
I would solve this problem by creating a look up table as follows.
Create a new worksheet called Lookup, then starting from A1 add the following data:
Min Max Bucket Description
-1000 0 1 <0 Days
1 15 2 0 - 15 Days
16 30 3 16 - 30 Days
You can add additional rows if you need to add more buckets. For example, to create a bucket for 30 to 60, you would add the row:
31 60 4 30 - 60 Days
Once you have the lookup table defined, you can reference into it using the following formula from your main worksheet:
=OFFSET(Lookup!$A$1,SUMPRODUCT((B2>=Lookup!$A$2:$A$4)*(B2<=Lookup!$B$2:$B$4)*(Lookup!$C$2:$C$4)),3)
In the above formula, the value being looked up is in B2.
If you have added rows to your lookup table, you will need to extend the look up range in the formula, i.e. Lookup!$A$2:$A$4 changes to Lookup!$A$2:$A$5 and so on.

Sum of diagonal products

I am looking to get the sumproduct but only for specific diagonals in an array. My setup is like below and the yellow highlighting should give an idea of how the formula should calculate
As text:
Years Rates 0 1 2 3
25 0.16 25 24 23 22
26 0.11 26 25 24 23
27 0.12 27 26 25 24
28 0.13 28 27 26 25
29 0.17 29 28 27 26
30 0.16 30 29 28 27
Years Sum of products
25
26
27
28
29
30
Note, the table on the right dictates how many years to include, so if the table were extended to include 4 years then 0.17*4 would need to be included in the sum product for 25
What is the best way to do this? Ideally not a CSE formula/ VBA. The actual table is much bigger, so I might need to be conscious of speed too.
I intend to edit this with what I came up with but I hope to see some different ways of doing this so I hope it's okay that I hold off for now.
Simply:
=MMULT(G4:J4,B7:B10)
Regards
You could give this CSE a try, maybe it's not as bad (even though you don't want one)
=SUMPRODUCT(B7:B10,TRANSPOSE(G4:J4))
I think a 'CSE' formula will be best even though you'd prefer not to.
With the first formula in B11 and the setup as in your image, (with the 0, 1, 2, 3 in D1:G1, the word "Rates" in B1, and the array in D2:G7 etc)
{=SUM(IF($D$2:$G$7=A11, $D$1:$G$1*$B$2:$B$7, 0))}
and drag down
This is the best way I can find, without using a CSE formula
=SUMPRODUCT(--($C$2:$F$7=$A11),$B$2:$B$7*$C$1:$F$1)
The first array is n x m in size and the second array is the product
of a n x 1 and 1 x m array, which is converted to an n x m
array. This provides SUMPRODUCT with two identically sized arrays as required.

Excel formula to get the count of certain value based on odd/even line

I have this data in Excel.
A B C
--------------------------------------
Line Number Value #1 Value #2
1 21 35
2 21 27
3 21 18
4 10 47
5 50 5
6 37 68
7 10 21
8 75 21
I tried to calculate the total "21" based on odd line number. In this situation, the answer should be 3. However, neither" IF(MOD(A1:A8,2)=1,COUNTIF(B1:C8,21)) " nor " {IF(MOD(A1:A8,2)=1,COUNTIF(B1:C8,21))} "worked and Google didn't yield anything helpful. Could anyone help me? Thanks!!
This works for odd lines:
=SUM(COUNTIF(A:B,21)-SUMPRODUCT((A:B=21)*(MOD(ROW(A:B),2)=0)))
there may be a better way of writing this formula.
Use this to count even lines:
=SUMPRODUCT((A:B=21)*(MOD(ROW(A:B),2)=0))

Resources