I am trying to get a formula that will help count cells that fall within a time window. I came up with a formula but it only works when the time is from AM to PM and not for PM (previous day) to AM (next day). As shown in the image, I want to be able to count the number of Korea trades (from Table 2) within trading window (Table 3). I was trying to use the highlighted formula but apparently it's not working on Table 1.
Formula: =COUNTIFS(D13:D16, "Korea", E13:E16, ">="&H4, E13:E16, "<="&I4)
Is there a way to achieve this?
When the times cross midnight for Korea, you'll need to do an OR condition rather than an and condition. You could do this by making two countifs functions or use Sumproduct as shown below:
=SUMPRODUCT((D13:D16="Korea")*((E13:E16>=H3)+(E13:E16<=I3)))
If you have access to a version of Excel that supports the Lambda function I’d suggest creating a lambda that does the within checking so it’s not done through the formulas on your sheet. Unfortunately I don’t think there are Ifs functions that take a lamdba as a criteria but you might be able to use Map to generate an array of booleans and get the product similar to the other reply.
So I started by creating a lambda for determining if the value is in the range. The formula I used is:
=LAMBDA(s,e,IF(s<e,LAMBDA(x,AND(x>=s,x<e)),LAMBDA(x,OR(x<e,x>s))))
That basically takes 2 parameters - your starting time and the ending time for the range. It will return a lambda that will take the time to compare. And I added that as a namedreference named “IsWithin”
Then I created another lambda that would do the overall count.
=LAMBDA(rangeMatch,textMatch,rangeTime,start,end,SUM(MAP(rangeMatch,LAMBDA(x,ISNUMBER(SEARCH(textMatch,x))))*MAP(rangeTime,IsWithin(start,end))))
The function takes 5 parameters:
the range for which you are searching for the country name
the text to match within the range
the range containing the times to evaluate
the start time for the valid range (e.g. H3)
the end time for the valid range (e.g. I3)
It uses the Map function to evaluate the items in the range using lambdas. The first part of the evaluate creates an array of the items that have the matching text so either TRUE or FALSE. The second part creates an array of items that are within the specified time range - again either TRUE or FALSE. And then it just multiplies those arrays and sums the values essentially getting those where both values are true. Then to use it you just call that named reference:
=CountMatch(D13:D16,"Korea",E13:E16,H4,I4)
You can try this
=SUMPRODUCT(--(LEN(D13:D16)<>LEN(SUBSTITUTE(D13:D16,"Korea","")))*((E13:E16>=H4)+(E13:E16<=I4)))
Related
I'm trying to make my monthly transaction spreadsheet less work-intensive but I'm running up against problems outputting my category lookups as an array. Right now I have a table with all my monthly transactions and I want to create another table with monthly running totals. What I've been doing is manually summing each entry from each category, but I'd love to automate the process. Here's what I have:
=SUM(INDEX(Transactions[Out], N(IF(1,MATCH(I12,Transactions[Category],FALSE)))))
I've also tried using AGGREGATE in place of SUM but it still only returns the first value in the category. The N(IF()) was supposed to force INDEX to return all the matches as an array, but it's not working. I found that trick online, with no explanation of why it works, so I really don't know how to fix it. Any ideas?
Just in case anyone ever looks at this thread in the future, I was able to find a simpler solution to my problem once I implemented the Transactions[Category]=I12 method. SUM, itself will take an array as an argument, so all I had to do was form an array of the values I wanted to keep from Transactions[Out] range. I did this by adjusting the method Ron described above, but instead of using 1/(Transactions[Category]=I12 I used 1/IF(Transactions[Category]=I12, 1,1000) and surrounded that by a FLOOR(*resulting array*, .01) which rounded all the thousandth's down to zero and didn't yield any #DIV/0! errors.
Then! I realized that the simplest way to get the actual numbers I wanted, rather than messing with INDEX or AGGREGATE, was to multiply the range Transactions[Out] by the binary array from the IF test. Since the range is a table, I know they will always be the same size. And SUM automatically multiplies element by element and then adds for operations like this.
(The result is a "CSE" formula, which I guess isn't everyone's favorite. I'm still not 100% clear on what it means: just that it outputs data in a single cell, rather than over multiple cells. But in this context, SUM should only output a single number, so I'm not sure why I need CSE... A problem for another day!)
In your IF, the value_if_true clause needs to return an array of the desired row numbers from the array.
MATCH does not return an array of values; it only returns a single value which, with the FALSE parameter, will be the first value. That's why INDEX is only returning the first value.
One way to return an array of values:
Transactions[Category]=I12
will return an array of {TRUE,FALSE,FALSE,TRUE,...} depending on if it matches.
You can then multiply that by the Row number to get the relevant row on the worksheet.
Since you are using a table, to obtain the row number in the data body array, you have to subtract the row number of the Header row.
But now we are going to have an array which includes 0's for the non-matching entries, which is not good for us as a row number argument for the INDEX function.
So we get rid of that by using the AGGREGATE function with the ignore errors argument set after we do change the equality test to 1/(Transactions[Category]=I12) which will create DIV/0 errors for the non-matchers.
Putting it all together
=SUM(INDEX(Transactions[Out],AGGREGATE(15,6,1/(Transactions[Category]=I12)*ROW(Transactions)-ROW(Transactions[#Headers]),ROW(INDIRECT("1:"&COUNTIF(Transactions[Category],$I$12))))))
You may need to enter this with CSE depending on your version of Excel.
Also, if you have a lot of these formulas, you may want to change the k argument for AGGREGATE to use the INDEX function (non-volatile) instead of the volatile INDIRECT function.
=SUM(INDEX(Transactions[Out],AGGREGATE(15,6,1/(Transactions[Category]=I12)*ROW(Transactions)-ROW(Transactions[#Headers]),ROW(INDEX($A:$A,1,1):INDEX($A:$A,COUNTIF(Transactions[Category],$I$12),1)))))
Edit
If you have Excel/O365 with dynamic arrays and the FILTER function, you can greatly simplify the above to the normally entered:
=SUM(FILTER(Transactions[Out],Transactions[Category]=I12))
Excel data table
I am new to here. If I have any mistake in making new post, Please tell me and I am ready to correct my mistake.
For above pic, I want to extract the 2 smallest values in column D respectively between row 77 and row 84, and between row 84 and 97. The resulting values are shown in P77 and P84 respectively.
How should I write the excel formula for it? Or it needs VBA to code it?
Thanks a lot for your sincere help!
(Update)
data set
above pic is another capture of my data set which filtered the day with "Bullish breaking candle/bearish breaking candle" only.
Thanks
There are lots of functions/ways to calculate Minimum in addition to the MIN function and it is worth being familiar with them as you will require different ones according to your data.
So quick rundown of some of the main offerings:
SMALL function:
I would consider also the more versatile SMALL function
=SMALL(D77:D84,1) in cell P77
=SMALL(D84:D97,1) in cell P84
You put the array (the range of cells to compare) then the k-th smallest item in that range that you want to retrieve e.g. put 1 to get the smallest, as above, comparable to MIN function, or 2 to get the second smallest etc.
Official blurb below:
Description
Returns the k-th smallest value in a data set. Use this function to
return values with a particular relative standing in a data set.
Syntax
SMALL(array, k)
The SMALL function syntax has the following arguments:
Array Required. An array or range of numerical data for which you
want to determine the k-th smallest value.
K Required. The position (from the smallest) in the array or range
of data to return.
AGGREGATE Function:
Consider the even more versatile AGGREGATE function which can cope with hidden rows in the range, errors etc. You can specify a host of additional requirements whilst still getting the minimum value
General syntax for first form:
AGGREGATE(function_num, options, ref1, [ref2], …)
Function 5 is Minimum. Options are viewable at link I gave but 7 is ignore errors and hidden rows. So, you could use:
=AGGREGATE(5,7,D77:D84)
The AGGREGATE option above is the only version that will still return the minimum correctly if there is an error in the range D77:D84 e.g. a DIV/0 error.
SUBTOTAL Function:
Similar to the AGGREGATE function is the SUBTOTAL function.
You can use SUBTOTAL(5, D77:D84) where 5 specifies you want the minimum for the range. This will not ignore errors. SUBTOTAL(105,D77:D84) will ignore hidden rows though.
Simply put the formula '=Min(D77:D84)' in cell P77
and '=Min(D84:D97)' in cell P84
Basically I am trying to improve a spreadsheet that current uses fixed IF functions within IF functions to determine where to find data, then originally used the VLOOKUP function to return the appropriate cable cleat size. Where "Cleat Diameter">"Cable Diameter".
I've been using this for a while, however excel quickly runs out of resources with all the remaining calculations being performed. As a result, I've opted to put all data a single table, and try to use the match function to retrieve the necessary row. Then Simply use the =INDIRECT function to retrieve data from the appropriate column of the associated row.
Unfortunately I believe the issue relates to the fact that I first need to perform at MATCH Type 0 (exact match), followed by a type -1 for the size to identify the next size up that can accommodate a specific cable size.
I've managed a simple lookup on another dataset using (for exact matches):
=MATCH($B3,'Current Raw Data'!A:A,0)+ROW('Current Raw Data'!A:A)-1
However when I attempt the same thing with two types of matches I get errors. The closest I get it using the following array formula, but it does not work unless the data set is arranged so that the contents of Cell C3 is the first occurring item in the dataset in column A:A:
{=MATCH(C3,($B3='Lookup - Cleats'!A:A)*('Lookup - Cleats'!B:B),-1)}
Main sheet:
Dataset Example:
With this array formula (click Ctrl + Shift + Enter together inside formula bar), you should be able to get your results:
=IFERROR(INDEX('Lookup - Cleats'!C$3:C$26,MATCH($B3&$C3,'Lookup - Cleats'!$A$3:$A$26&'Lookup - Cleats'!$B$3:$B$26,0)),"")
I tried my best to use your data setup but maybe miss one or two things that you will need to adjust accordingly. Let me know if this is not working.
I am trying to implement an IF function for a simple pricing database where if a cell is equal to one of 3 time durations, the cell automatically generates the correct price based on length of time. Here's what I have so far based on what other examples have of nested Excel functions:
=IF(F4=12;"$60";IF(F4=6;"$40";IF(F4=3,"$30")))
My primary issue is that the second condition has a red bracket, indicating an error. If I then swap the ";" for a ",", I have the same result.
As there are only 3 conditions, I have also tried the following:
=IF(F4=12;"$60",IF(F4=6;"$40","$30")
But again I have the same issue with the bracket being red on the second condition.
Any ideas?
First time asking a question after reading a lot in the past.
I'm running the following array function excel:
INDEX('Available Options'!$A$1:$CM$137,$B$1,
SMALL(
IF(
INDIRECT("'Feasibility Options'!"&ADDRESS($B$1,COLUMN('Feasibility Options'!$G$1),1,1)&":"&ADDRESS($B$1,COLUMN('Feasibility Options'!$O$1),1,1))=2,
COLUMN(INDIRECT("'Feasibility Options'!"&ADDRESS($B$1,COLUMN('Feasibility Options'!$G$1),1,1)&":"&ADDRESS($B$1,COLUMN('Feasibility Options'!$O$1),1,1)))),
ROW('Available Options'!1:1)))
The idea behind this is that there are a number of cells which either have 1s, 2s or 3s in (1 means default, 2 means an alternative and 3 means inactive) in a separate tab called 'Feasibility Options', and the prices for these options are held in the 'Available Options' tab. $B$1 contains a row number produced through a separate calculation.
Evaluating this formula gives a value error when resolving the Indirect part of the function, but the function works if I replace the column number formulae with column numbers as below:
INDEX('Available Options'!$A$1:$CM$137,$B$1,
SMALL(
IF(INDIRECT("'Feasibility Options'!"&ADDRESS($B$1,7,1,1)&":"&ADDRESS($B$1,15,1,1))=2,COLUMN(INDIRECT("'Feasibility Options'!"&ADDRESS($B$1,7,1,1)&":"&ADDRESS($B$1,15,1,1)))),ROW('Available Options'!1:1)))
Could someone explain why this would happen and how to fix it? I ideally need to use cell references rather than hardcoded column numbers as I will likely need to add more columns in at a later date.
Thanks for any help you can give and apologies if I've missed a previous thread which answers this sort of question.
I haven't tested this but I suspect the problem is caused by the COLUMN function which returns an array (even for a single value) and sometimes Excel has trouble processing this:
You can normally make it work by wrapping COLUMN in a SUM or MAX function, e.g.
MAX(COLUMN('Feasibility Options'!$G$1))
or using COLUMNS function instead, something like
COLUMNS('Feasibility Options'!$G$1:G1)
which can be dragged to increment
Better still would be to replace the whole INDIRECT/ADDRESS parts with INDEX, which should be simpler, shorter and more efficient. I can give you more detail on that if you're interested