I have a timeshift table, where 0 means no activity (or day off) and values > 0 are different activities.
I can find the start hour of the first shift and the end hour of the last shift, but i'm struggling to find the last hour of the first shift and the first hour of the second shift.. The table should look like this:
EXCEL
Taking in account the example above, what i exactly want is a formula to determine that:
On row 3, the end of the first shift is column S (or 14:00) and the beginning of the second shift is column V (or 15:30)
On row 6, the end of the first shift is column U (or 15:00) and the beginning of the second shift is column X (or 16:30), and so on...
Here's a possible approach. Since there aren't too many columns, you could join them all together and use Find to get the transitions from 0 to 1 and 1 to 0:
=LET(join,TEXTJOIN("",,D3:AY3),start1,FIND("01",join)+1,finish1,FIND("10",join,start1),start2,FIND("01",join,finish1)+1,finish2,FIND("10",join,start2),INDEX(D2:AY2,1,HSTACK(start1,finish1,start2,finish2)))
Then you would need to add error handling for the case where the person worked no shifts or only one shift and also allow for the case where a shift started at exactly 6:30 or finished at exactly 6:00.
EDIT
An improved formula could look like this:
=LET(join,TEXTJOIN("",,D3:AZ3)&0,
LC,COLUMNS(D3:AZ3),
start1,IFERROR(FIND("1",join),LC),
finish1,IFERROR(FIND("10",join,start1),LC),
start2,IFERROR(FIND("1",join,finish1+1),LC),
finish2,IFERROR(FIND("10",join,start2),LC),
INDEX(D$2:AZ$2,1,HSTACK(start1,finish1,start2,finish2)))
where AZ2 contains a suitable character string to indicate missing data.
Related
I have a column of time data formatted like this: Machine_Usage
I want to make an IF statement that returns 1, 2 or 3 corresponding to first, second or third shift if the times fall between certain values.
I already tried many times but not worked, please help me.
I want to find the right formula/syntax that can solved this problem for length of use of the machine based on the shift.
This is a possible approach, but not an answer because the question needs clarification on how to handle the following situations:
The interval [Start, End] is not within a single shift. According to some input data, it starts in one shift and ends in another one.
When End corresponds to a day after Start. This only can apply for shift 3, but based on the data there is no such scenario
In cell F2 put the following formula (the result is spilled, no need to drag down the formula)
=LET(start, C2:C20, end, D2:D20, lkup, H2:J4, shift, INDEX(lkup,,1),
lkStart, INDEX(lkup,,2), lkEnd, INDEX(lkup,,3),
MAP(start, end, LAMBDA(ss,ee, LET(startI, INT(ss) + lkStart,
endI, INT(ss) + lkEnd,
result, FILTER(shift, (ss >= startI) * (ee < endI), "Shift not found"),
IF(ROWS(result) > 1, "Overlap", result)
)))
)
Here is the output:
As you can see based on the data issue mentioned before no shift was found for any of the rows. Probably after data clean-up or more clarification, the formula should return a more realistic result.
Even the Shift information is represented in hh:mm format (see the previous screenshot). The end date of the last shift corresponds to the next day. Therefore the numeric values associated with the hours are the following:
Shift Start End
1 0.25 0.58
2 0.58 0.92
3 0.92 1.25
The logic of the formula is based on the above settings.
I have been working for several days on this and have researched everything looking for this answer. I'd appreciate any help you can give.
In Excel I am searching a string of text in column A:
Bought 1 HD Sep 3 2021 325.0 Call # 2.75
I am detecting the first word (in this case "Bought") and detecting the last word before "#" symbol (in this case "Call").
I am then detecting the price following the "#" symbol (in this case "2.75"). This number will go into column B (header "Open") or column C (header "Close") depending on the combination of words found:
Sold/Put=Close
Sold/Call=Open
Bought/Put=Open
Bought/Call=Close
Sold (by itself)=Open
Sold (by itself)=Close.
Bought 1 HD Sep 3 2021 325.0 Call # 2.75
The combination found in the above string is: "Bought Call". Therefore the number at the end ("2.75"), goes into "Open" column.
Here's another example:
Sold 4 AI Sep 17 2021 50.0 Put # 1.5
The combination found in the above string is: "Sold Put". Therefore the number at the end ("1.5") goes into "Close" column.
I am currently using this formula to determine if the string contains "Sold" and "Call" and get the desired number and it does work:
=IF(AND(
ISNUMBER(SEARCH({"Sold","Call"},A10))),
TRIM(MID(A10,SEARCH("#",A10)+LEN("#"),255))," ")
But, I don't know how to search for all the other possible combinations.
The point behind this is to be able to paste the transaction from the broker and have most of the entry process automated. I'm sure many will benefit from this as I've not found anything like this.
I'd appreciate any help and if possible, an explanation of the formula so I can better learn.
Thanks!
I think you have the right idea, but would just extend the IF statement.
Something like the below might work for you:
=IF(ISNUMBER(SEARCH("Call", $A1)),
IF(ISNUMBER(SEARCH({"Bought","Sold"}, $A1)),
NUMBERVALUE(RIGHT($A1, LEN($A1)-SEARCH("#", $A1))),""),
IF(ISNUMBER(SEARCH({"!!!","!!!","Bought","Sold"}, $A1)),
NUMBERVALUE(RIGHT($A1, LEN($A1)-SEARCH("#", $A1))),""))
Just enter in column B and drag down; columns B through E should fill as needed.
For example:
Note that the search for "!!!" is just random characters, it can be anything that you don't think has a good chance of appearing in the string.
Here/screenshots refer:
(requires Office 365 compatible version Excel)
Main lookup
=LET(fn_1,MATCH("*"&$H$7:$H$12&"*",B4,0),fn_2,MATCH("*"&$I$7:$I$12&"*",B4,0),IFERROR(INDEX($J$7:$J$12,MATCH(1,IF($I$7:$I$12="",fn_1*ISNUMBER(fn_2),fn_1*fn_2),0)),))
EDIT:
Other Excel versions:
=IFERROR(INDEX($J$7:$J$12,MATCH(1,IF($I$7:$I$12="",MATCH("*"&$H$7:$H$12&"*",B4,0)*ISNUMBER(MATCH("*"&$I$7:$I$12&"*",B4,0)),MATCH("*"&$H$7:$H$12&"*",B4,0)*MATCH("*"&$I$7:$I$12&"*",B4,0)),0)),)
(all that falls away is the 'Let' formula, replacing fn_1 and fn_2 with respective functions in index formula within the let making first equation somewhat longer, but otherwise identical)
Example applications
Have provided 2 examples of how one might customize to insert numeric in one of the columns (the key part to this question is really how to do lookup in first instance, from thereon it's a matter of finetuning/taking appropriate action)...
Assuming calls/buys are "long" position and strike price go in first col (here, D), and puts/sales are "short" position with strike price going in 2nd col (here, E):
Long - insert strike price col D
=IF(LET(fn_1,MATCH("*"&$H$7:$H$12&"*",B4,0),fn_2,MATCH("*"&$I$7:$I$12&"*",B4,0),IFERROR(INDEX($K$7:$K$12,MATCH(1,IF($I$7:$I$12="",fn_1*ISNUMBER(fn_2),fn_1*fn_2),0)),))=1,MID(SUBSTITUTE(B4," ",""),SEARCH("#",SUBSTITUTE(B4," ",""))+1,LEN(SUBSTITUTE(B4," ",""))),"")
EDIT
Other Excel versions:
=IF(IFERROR(INDEX($K$7:$K$12,MATCH(1,IF($I$7:$I$12="",MATCH("*"&$H$7:$H$12&"*",B4,0)*ISNUMBER(MATCH("*"&$I$7:$I$12&"*",B4,0)),MATCH("*"&$H$7:$H$12&"*",B4,0)*MATCH("*"&$I$7:$I$12&"*",B4,0)),0)),)=1,MID(SUBSTITUTE(B4," ",""),SEARCH("#",SUBSTITUTE(B4," ",""))+1,LEN(SUBSTITUTE(B4," ",""))),"")
Short - insert strike price col E
=IF(LET(fn_1,MATCH("*"&$H$7:$H$12&"*",B4,0),fn_2,MATCH("*"&$I$7:$I$12&"*",B4,0),IFERROR(INDEX($K$7:$K$12,MATCH(1,IF($I$7:$I$12="",fn_1*ISNUMBER(fn_2),fn_1*fn_2),0)),))=2,MID(SUBSTITUTE(B4," ",""),SEARCH("#",SUBSTITUTE(B4," ",""))+1,LEN(SUBSTITUTE(B4," ",""))),"")
EDIT
Other Excel versions:
Follow same routine in previous Edits (remove Let, replace fn_1 & fn_2 with respective formulae...)
Note similarity in all 3 equations above: 2nd and 3rd contain 1st (effectively they just wrap a big old 'if' statement around 1st, use lookup_2 col (here, col K), and use mid/search to extract rate after the hashtag.
Assumes you don't have other hashtags in the sentence..
Customize as required.
EDIT: Forgot to add the current formula (see bottom of post)
I have multiple columns that store time as interval values (e.g. 10PM stored as 22, 6AM stored as 06) - see image
I need to check if a certain time is between all the different time intervals
How do I write an Excel formula that checks if a time is between
multiple time intervals (e.g. is 2:30AM in between 10PM and 4AM?)?
My time intervals are stored in columns:
J5&K5 [i.e. J5 is the start (value: 02) and K5 is the end (value: 12)]
L5&M5
N5&O5
P5&Q5
R5&S5 [i.e. R5 is the start (value: 06) and K5 is the end (value: 18)]
The times I would like to check are in T1:AE5
e.g. T1 = 6:30AM
e.g. U1 = 8:30AM
e.g. AD1 = 02:30AM
e.g. AE1 = 04:30AM
Example (see image):
Count the number of times AD1 is in between:
J5&K5
L5&M5
N5&O5
P5&Q5
R5&S5 (i.e. R5 is the start and K5 is the end)
In this example, the count should be 3 and stored in AD5 (it's in between J5&K5,
L5&M5, N5&O5)
Things to consider:
00:00 and 24:00 are both stored as 24
Sometimes the start time is at night (e.g. 22, 24) and the end time is in the morning (e.g. 02, 04, 06)
Sometimes the start time is in the morning (e.g. 02 or 04) and the end time is in the afternoon (e.g. 14 or 16)
Current formula in AD1 (which can't account for the fact that 2.5 is actually in between 24 and 06)
=SUMPRODUCT(($AD$1>INDEX(J4:S4,1,N(IF(1,{1,3,5,7,9}))))*($AD$1<INDEX(J4:S4,1,N(IF(1,{2,4,6,8,10})))))
^Note this is a formula provided by another Stackoverflow member when I had a somewhat simpler problem to tackle before the requirement changed
Breaking down the formula you have:
=SUMPRODUCT(($AD$1>INDEX(J4:S4,1,N(IF(1,{1,3,5,7,9}))))*($AD$1<INDEX(J4:S4,1,N(IF(1,{2,4,6,8,10})))))
$AD$1>INDEX(J4:S4,1,N(IF(1,{1,3,5,7,9}))) checks if AD1 is greater than the start time
$AD$1<INDEX(J4:S4,1,N(IF(1,{2,4,6,8,10}))) checks if AD1 is less than the end time
Then the results are multiplied. Since True evaluates to 1 and False to 0, the multiplication only results in 1 where both conditions are met.
In logical terms:
AD1 is greater than the start time
AND
AD1 is less than the end time
The additional logic required is to count the instances where:
AD1 is greater than the start time
OR
AD1 is less than the end time
WHILE
the start time is greater than the end time
This is accomplished with:
=SUMPRODUCT((($AD$1>INDEX(J4:S4,1,N(IF(1,{1,3,5,7,9}))))+($AD$1<INDEX(J4:S4,1,N(IF(1,{2,4,6,8,10})))))*(INDEX(J4:S4,1,N(IF(1,{1,3,5,7,9})))>INDEX(J4:S4,1,N(IF(1,{2,4,6,8,10})))))
$AD$1>INDEX(J4:S4,1,N(IF(1,{1,3,5,7,9}))) checks if AD1 is greater than the start time
$AD$1<INDEX(J4:S4,1,N(IF(1,{2,4,6,8,10}))) checks if AD1 is less than the end time
This time these get added together (OR'd)
INDEX(J4:S4,1,N(IF(1,{1,3,5,7,9})))>INDEX(J4:S4,1,N(IF(1,{2,4,6,8,10}))) checks that the start time is greater than the end time
This third check gets multiplied (AND'd) with the result of the prior addition. This results in only counting situations in which the start time is at a later time than the end time (overnight) and for which AD1 is during the time period.
So to count all the desired situations, you should use the sum of both the original and the new parts:
=SUMPRODUCT(($AD$1>INDEX(J4:S4,1,N(IF(1,{1,3,5,7,9}))))*($AD$1<INDEX(J4:S4,1,N(IF(1,{2,4,6,8,10})))))+SUMPRODUCT((($AD$1>INDEX(J4:S4,1,N(IF(1,{1,3,5,7,9}))))+($AD$1<INDEX(J4:S4,1,N(IF(1,{2,4,6,8,10})))))*(INDEX(J4:S4,1,N(IF(1,{1,3,5,7,9})))>INDEX(J4:S4,1,N(IF(1,{2,4,6,8,10})))))
Well, not the cleanest formula in the world, but at least it works. I'm sure there is a way to resume this formula, but I'm such a noob with SUMPRODUCT and I could not find a way.
I got this:
The formula I've used in cell A3 is:
=SUM(IF(B7<A7;IF(Y(A1+24>=A7;A1+24<=B7+24);1;0);IF(Y(A1>=A7;A1<=B7);1;0));IF(D7<C7;IF(Y(A1+24>=C7;A1+24<=D7+24);1;0);IF(Y(A1>=C7;A1<=D7);1;0));IF(F7<E7;IF(Y(A1+24>=E7;A1+24<=F7+24);1;0);IF(Y(A1>=E7;A1<=F7);1;0));IF(H7<G7;IF(Y(A1+24>=G7;A1+24<=H7+24);1;0);IF(Y(A1>=G7;A1<=H7);1;0));IF(J7<I7;IF(Y(A1+24>=I7;A1+24<=J7+24);1;0);IF(Y(A1>=I7;A1<=J7);1;0)))
The idea is just check if End is less than Start. If true, because you are working with periods of 24 hours, then sum 24 to End and also to value being checked.
After that, it just check if the value is between Start and End.
But yeah, pretty dirty. I'm posting the formula, hoping somebody can resume it.
But as I said, at least it works.
Here is one way solving the issue by using two helper rows (if that's an option):
The purpose of the helper rows is to find out the "true" end and start time for each start and end section using mid-day 12 as a judgement point. In other words, I have divided the time periods from 5 pairs to 10 unique time periods with its own start and end time.
To find Start time, enter the following formula in Cell J6 and drag it across;
=IF(LEFT(J3,5)="Start",J5,IF(J5<12,0,12))
To find End time, enter the following formula in Cell J7 and drag it across;
=IF(LEFT(J3,3)="End",J5,IF(J5>12,24,12))
An optional step, you can give a name to range J6:S6 as Start, and give a name to range J7:S7 as End, then you can enter the following formula in cell T5 to count the occurrences of each given starting time:
=SUMPRODUCT((T$1>=Start)*(T$1<=End))
EDIT#2
It is actually possible to combine the above into one array formula (so avoid using actual helper rows) which needs to be confirmed by pressing Ctrl+Shift+Enter upon finishing the formula in the formula bar.
=SUMPRODUCT((T$1>=IF(LEFT($J$3:$S$3,5)="Start",$J5:$S5,IF($J5:$S5<12,0,12)))*(T$1<=IF(LEFT($J$3:$S$3,3)="End",$J5:$S5,IF($J5:$S5>12,24,12))))
Enter the above in cell T5 and drag it across.
Let me know if you have any questions. Cheers :)
I have data among M8-V68, users are input their availability as 'Y' or 'N'. It includes 10 days in a row, the days are shifting everyday (by function =TODAY()) I need to shift the data provided by users as the days are shifting.
So, the idea is like following,
02/11 03/11 04/11
Mark Y Y N
Kate N Y Y
When I open the document tomorrow, I would like to see following,
03/11 04/11 05/11
Mark Y N
Kate Y Y
So, data for 02/11 is deleted and others are shifted. As I noted, dates are already shifting as I want, so all I want is data to shift left and the new column for upcoming date will be blank.
If you're open to VBA, this would do the trick:
Sub AddNewDate()
Columns("M:M").Delete Shift:=xlToLeft
Range("V8").Value = Int(VBA.Now + 10)
Range("V8").NumberFormat = "DD/MM"
End Sub
It will overwrite the formulas in your header eventually, which may or may not be okay with you. If not, you can do this:
Range("M9:M69").Delete Shift:=xlToLeft
I'm assuming your dates are in row 8. If not, you will need to adjust accordingly.
i need to know how can i exclude 0 from rows and get the MIN Value.
But also i need to exlude the F1 Cell.
Ex:
A B C D E F
1 0 18 20 0 150 = 18
but if i do this In excel with =MIN(A1,B1,C1,D1,E1) return 0.
Any help is appreciated.
Try this formula
=SMALL((A1,C1,E1),INDEX(FREQUENCY((A1,C1,E1),0),1)+1)
Both SMALL and FREQUENCY functions accept "unions" as arguments, i.e. single cell references separated by commas and enclosed in brackets like (A1,C1,E1).
So the formula uses FREQUENCY and INDEX to find the number of zeroes in a range and if you add 1 to that you get the k value such that the kth smallest is always the minimum value excluding zero.
I'm assuming you don't have negative numbers.....
Enter the following into the result cell and then press Ctrl & Shift while pushing ENTER:
=MIN(If(A1:E1>0,A1:E1))
Not entirely sure what you want here, but if you want to discount blank cells in the range and pass over zeros then this would do it; if a little contrived:
=MIN(IF(A1:E1=0,MAX(A1:E1),A1:E1))
With Ctrl+Shift+Enter as an array.
What I'm doing here is replacing zeros with the maximum value in the list.
if all your value are positive, you can do -max(-n)
Solutions listed did not exactly work for me. The closest was Chief Wiggum - I wanted to add a comment on his answer but lack the reputation to do so. So I post as separate answer:
=MIN(IF(A1:E1>0;A1:E1))
Then instead of pressing ENTER, press CTRL+SHIFT+ENTER and watch Excel add { and } to respectively the beginning and the end of the formula (to activate the formula on array).
The comma "," and "If" statement as proposed by Chief Wiggum did not work on Excel Home and Student 2013. Need a semicolon ";" as well as full cap "IF" did the trick. Small syntax difference but took me 1.5 hour to figure out why I was getting an error and #VALUE.
Throwing my hat in the ring:
1) First we execute the NOT function on a set of integers,
evaluating non-zeros to 0 and zeros to 1
2) Then we search for the MAX in our original set of integers
3) Then we multiply each number in the set generated in step 1 by the MAX found in step 2, setting ones as 0 and zeros as MAX
4) Then we add the set generated in step 3 to our original set
5) Lastly we look for the MIN in the set generated in step 4
{=MIN((NOT(A1:A5000)* MAX(A1:A5000))+ A1:A5000)}
If you know the rough range of numbers, you can replace the MAX(RANGE) with a constant. This speeds things up slightly, still not enough to compete with the faster functions.
Also did a quick test run on data set of 5000 integers with formula being executed 5000 times.
{=SMALL(A1:A5000,COUNTIF(A1:A5000,0)+1)}
1.700859 Seconds Elapsed |
5,301,902 Ticks Elapsed
{=SMALL(A1:A5000,INDEX(FREQUENCY(A1:A5000,0),1)+1)}
1.935807 Seconds Elapsed |
6,034,279 Ticks Elapsed
{=MIN((NOT(A1:A5000)* MAX(A1:A5000))+ A1:A5000)}
3.127774 Seconds Elapsed |
9,749,865 Ticks Elapsed
{=MIN(If(A1:A5000>0,A1:A5000))}
3.287850 Seconds Elapsed |
10,248,852 Ticks Elapsed
{"=MIN(((A1:A5000=0)* MAX(A1:A5000))+ A1:A5000)"}
3.328824 Seconds Elapsed |
10,376,576 Ticks Elapsed
{=MIN(IF(A1:A5000=0,MAX(A1:A5000),A1:A5000))}
3.394730 Seconds Elapsed |
10,582,017 Ticks Elapsed
min() fuction exlude BOOLEAN and STRING values.
if you replace your zeroes with "" (empty string) - min() function will do its job as you like!
In Microsoft 365 you can use the new function MINIFS
=MINIFS(A1:E1;A1:E1;">0")
gives 1
=MINIFS(A1:E1;A1:E1;">1")
gives 18
*replace ; with , if using english version
All you have to do is to delete the "0" in the cells that contain just that and try again. That should work.