Excel - Find a date within a list of arrays - arrays

I need to enter the text 'AL' into cell E3 if the date in E2 is a date someone took as annual leave.
Cells A3:B11 list a start date and an end date someone took as annual leave. See below.
I need a way of checking if a date is between (and including) an array of those two dates, for each from in cells A3:B11.
Note: Cell A5 is one day someone took as annual leave and just requires a start date only.
EDIT: I can use the following algorithm for the first row (A3:B3)
=IF(SUMPRODUCT((ROW(INDIRECT(A3&":"&B3))=E3)*1)=1,"AL","")
I am still stuck however on applying for all possible rows

Using your example sheet, in cell E3 use the formula
=IF(AND($E$2>=A3,$E$2<=B3),"AL","-")
You can then apply this down as many rows as you need. If you need to drag it to the right, across columns, then be sure to switch the cell references (i.e. to hit different dates in cell F2, G2, H2, etc you would use (=IF(AND($F$2>=A3,$F$2<=B3),"AL","-")
The only issue with this method is that you'll need to fill in the End Date for leaves only lasting a day. So just copy that 7/7/2017 over into column B.
P.S. if you actually meant "Array" in the official excel array formula sense, then the solution is different.

I believe I've found a solution with the help of Hoejanson.
=IF(SUMPRODUCT(((A3:A11<=E3)*1),((B3:B11>=E3)*1))=1,"AL","")
It will mean ensuring that both start and end dates are filled for when there is just one day so cell B5 would have to equal 07/07/2018 for this to work.
EDIT: Found a way to allow just a date in the start column to be added.
=IF(SUMPRODUCT((A3:A11<=E3*B3:B11>=E3)+(A3:A11=E3*B3:B11=""))=1,"AL","")
What this is saying is if column A's dates are less than the value in E3, AND column C's date are larger than evaluate true or false. Then the + means 'OR', where column A's dates are equal to E3 AND the corresponding rows in column C are empty. Hope this helps anyone searching a similar answer.

Related

Can Excel Index-Match or something like it match 1 row but return another?

I have a chart that shows the salaries for various medical specialties by percentile (each row is a specialty and each column is a percentile).
I want to be able to take a separate chart of physicians and their salaries, and automatically fill in what percentile each of their pay is.
https://i.imgur.com/NCtHHAB.jpg
If the physicians were all in one specialty, then I could just use Index-Match like so:
=INDEX('[Percentiles Chart]'!$B$3:$F$4, 1, MATCH(K3,'[Percentile File]'!$B$4:$F$4,1))
This formula works because it's choosing the column based on just the salaries in that one row, and always returning the top row. If I wanted it to choose between different rows, how could I do that without writing an "If" formula for every single row?
In other words, I want excel to look down column A in the example picture to pick the right specialty, then compare the salaries across the row and return what's in row 2.
Thank you!
As you rightly mentioned, there is no easy way to accomplish what you are looking for since the combination of Index/Offset/Match functions will return the data from the row that is matched and not some other row. Here is a formula that I have tried and it works exactly like you want. It is slightly hacky and uses SUMPRODUCT but gets the job done.
In your spreadsheet, if you enter the below formula, you would see that it gets the correct percentile value.
=OFFSET($B$2,0,SUMPRODUCT(($A$3:$A$6=J3)*($B$3:$F$6<K3)),1,1)
Here is how it works. The first part Sumproduct basically matches the name of specialty in range A3 to A6 and returns true for a match. The second part in sumproduct checks how many values in the range B3 to F6 are less than the given value (for example K3). When these two results are multiplied, it gives the number of values less than given value in the row of matching specialty which is equivalent to the offset of the column in the range. So, the OFFSET function simply navigates to that column and returns the value of the percentile. The below screenshot should help you understand it better.
If my explanation confused you :), you may want to play around with this formula to see how exactly it works.
Note the last column that says 100 in the percentiles table. That is simply to show correct value in case salary is greater than 90 percentile value.

excel collect data rolling from month to month

I am currently using this array =SUMPRODUCT(--('sheet1'!$A:$A=C7),--('sheet1'!$G:$G="Lost")) to collect information on a 3rd sheet. I am trying to figure out how to only select data from the current month. The dates are all on sheet1 Column B. It would be appreciated some in site one how to move forward.
Thank you
Add the beginning and end dates
=SUMPRODUCT(('sheet1'!$A:$A=C7)*('sheet1'!$G:$G="Lost")*('sheet1'!$B:$B>EOMONTH(TODAY(),-1))*('sheet1'!$B:$B<=EOMONTH(TODAY(),0)))
One note:
I used full column references as you had, but with array type formulas one should confine the reference to the cells with data and not use full column references.
With Array type formulas it will iterate trough the entire column, so this formula will do over 4 million calculations, most unneeded. If you filled a column with this formula you would start to notice a lag in the calc times.

match, index, and concatenate to just one cell

I have a Google spreadsheet with two sheets, that I want to use to plan the calendar for my staff. One sheet is called "maquinas" (machines). The rows are the dates and the columns are the machines. Inside each cell there's the name of the operator of the machine. Like this:
Note that:
-some machines are inoperative some days (marked in black)
-there are special days when a machine that normally is operative has to close (cell H5)
-some operators have to operate several machines the same day
I have another sheet called "personas" (employees), where I want that each employee only has to look to one cell to know everything he has to do on each day (a list of all the machines that he must operate that day). This is an example of the desired result:
The order in which the machines appear in each cell is not important, as long as every one of them appears.
I have no idea about how to solve it. I have tried to bypass it creating a huge "tridimensional spreadsheet", with dates in the rows, employees in the columns, and machines in the sheets (in the third dimension), and concatenate towards the first sheet. It works, but then is very cumbersome and error-prone to make changes in the employees' daily work.
I have a bad feeling. Probably it will need code or array formulas, and the function concatenate doesn't work with arrays. And I have no idea of how to code in VBA, much less in Google Spreadsheets.
I think I have something you can try. Manually set up on your "personas" sheet,
enter the employee names in row 1 and the days in column A. Just as they are on
your example. Then paste this formula in cell B2:
=iferror(join(" ",(query(transpose(QUERY(maquinas!$B$1:$M$5 , "select * " )),"select Col1 where Col"&index(row())&" contains'"&B$1&"'"))))
Then drag the formula in B2 down as far as you need for days (If days are
not yet entered, they will show as blank.) Then highlight all the all the
cells with formulas in column B and drag it right to column J.
The "maquinas" is fine as is.
Let me know if you have a problem or need anything explained.
Here is a link to my working test spreadsheet. Make a copy and try it.
If you are using a different language, you may need to change the , to ;
in the formulas.
https://docs.google.com/spreadsheets/d/1jqDkYTy3rssqeKGJyLYzcMJ27c5X3a1P5osKkWPNOoM/edit?usp=sharing

Sumproduct formula returns a #VALUE! error when the last array refers to a column with formulas in every row. MS Excel 2010

I am trying to find an easy way to calculate commissions off of sales on multiple sheets within a workbook. Each month, I need to find the total net profit for only items sold within the specified month.
The formula I am currently using is:
=SUMPRODUCT((TEXT('Sheet Name'!$P$3:P24,"MY")=TEXT($G$4,"MY"))*'Sheet Name'!$M$3:M24)
Column P shows the Sold Date,
Column M includes a formula in each row to calculate the net profit, and
cell G4 is where I would enter the month & year I am currently working with.
I have come to the conclusion that it only gives me the #VALUE! error because of the formula in each row of Column M (example: =IF(OR(F15=0,G15=0)," ",(F15-L15)) ).
When I reference a different column (in place of Column M) that does not contain formulas it works perfectly (example: =SUMPRODUCT((TEXT('Sheet Name'!$P$3:P24,"MY")=TEXT($G$4,"MY"))*'Sheet Name'!$G$3:G24) ). Also, changing the astrisk to a comma causes the formula to calculate incorrectly and add the (--(TEXT double negative does not fix the problem.
How to I get this array to calculate without removing the formulas from Column M?
Thanks for your attention.
I presume it is giving you a #VALUE error because your formula results in text (a space) and it errors when trying to multiply a space by a number (aka True or False). I think you would be better served changing your M column formula to =IF(OR(F15=0,G15=0),0,(F15-L15)). Do you have a specific reason to not make it evaluate to 0? Also is there a reason you are converting to text to do your month/year check?
Try something like this: =SUMPRODUCT(--(MONTH('Sheet Name'!$P$3:P24)=MONTH($G$4)),--(YEAR('Sheet Name'!$P$3:P24)=YEAR($G$4)),'Sheet Name'!$M$3:M24). Of course this is dependent on entering the dates as actual dates. The -- is used to change a logical/boolean (true/false) into a 1 or 0. It won't do anything useful to text. For example, it should also work as =SUMPRODUCT((MONTH('Sheet Name'!$P$3:P24)=MONTH($G$4))*(YEAR('Sheet Name'!$P$3:P24)=YEAR($G$4))*'Sheet Name'!$M$3:M24) since the multiplication converts the truthy statements to numbers. The trick is to make sure when everything else evaluates, you have =sumproduct(numbers,numbers,numbers). Your instance is one array of =sumproduct(numbers/text).

Excel VBA FormulaArray Too Slow

I have a macro that populates start and complete dates based upon the accounting period. For example: Product X has sales in Jan12 - Dec12. The macro would use a vlookup/min array to find the start and a vlookup/max array to find the finish. The dates are in a YYYYMM format, so the vlookup is looking at a calendar tab that maps the corresponding YYYYMM to a start or finish date. The coding works fine, but in some instances there are 30,000 - 100,000 lines and it can take upward of 15-20 minutes to run. Does anyone have any ideas on how to make this run faster?
Here is the code:
Cells(Rcnt, 5).FormulaArray = "=VLOOKUP(MIN(IF('Normalized'!A:A= " & Cells(Rcnt, 1).Address(False, False) & ", 'Normalized'!J:J)),'Calendar'!A:C,2,FALSE)"
Any help would be greatly appreciated.
Don't use a formula in your macro. You can probably make the code much faster by writing the code in VBA yourself. You could loop through all values in a line and store the smallest and largest values (you can keep max and min so you only need one loop). Then write these values to wherever is appropriate. This should already be a speed up over the excel formula.
To get started with writing macros in VBA look here. You will specifically want to look at how to loop through the cells. You will want to set max = Jan 1 and min = Dec 31 and then if the value you are currently inspecting is greater than max you set max equal to the value and likewise for min. After looping through that row you will have the max and min values in that row. You can then write these values into some other column, reset max and min and move to the next row.
My understanding of your issue is that your data lists each product's sales in each month, so for each product, you are searching for the first and last months. Can you sort the data by product and by date? That would be the easiest way to implement a loop as Emschorsch described, because you'd only be dealing with one product at a time.
A couple other things to try to speed this up:
set the first line of your code to:
Application.Calculation = xlCalculationManual
and your last line to:
Application.Calculation = xlCalculationAutomatic
(you still have tons of lookups, but they will calculate all at once, not one at a time as you create each row's formula)
If sorting the data won't fly, you can Autofilter on each product in succession and use the SUBTOTAL() function, referencing the date column, to get the min and max. (You can place the SUBTOTAL() formula in an unused cell and reference that cell in your code, or use it directly in the code using Application.WorksheetFunction)
The other part that seems unnecessary (without seeing your data we can't be sure) is using a lookup to turn YYYYMM into a date, if that is truly the format all of your dates are in. That can easily be done without VBA using the DATE() formula, or if you need it inside a macro:
cells(Rcnt, 5).Value = DateSerial(Left(x, 4), Right(x, 2), 1) 'x is your date in YYYYMM format

Resources