In the following picture I have a total time taken to fix an issue by Cell B2 and C2 being filled in. They post a time stamp when they are changed. Cell M2 is the total time between the two actions.
In the next picture I have a Macro that adds a new row every time the button is pressed. For this question I only need to use Columns A,B,C,J. A&B are just the time stamp of when the marco was ran. Column C is the new "layer total" so that value will increase to the nearest multiple of 20 (B7). Column J is the average time per layer between the last two rows. Example is that it takes 1.5 min(J20) per layer between layers 201(C20) and 185(C19).
My question is (after all this time) if there is a way to use the LOOKUP function to find all the pause times in Picture 1 between two layer values from Picture 2. Example: Find all the pause times between layers 140 and 162. Then add those up pauses up into a single value?
Look at SUMIFS.
Example:
=SUMIFS(PausesSheet!M4:M100,PausesSheet!C4:C100,">=140",PausesSheet!C4:C100,"<=162")
The ">=140" and "<=162" (from your example) can be replaced with formula, e.g. ">=" & C8, ... "<=" & C9 , which you can use all the way down on your second worksheet.
Related
I have list of IDs with warehouse stocks and list of shipments to customers which might have same ID.
Attached screen with example, so for 29.08.2022 with hour 08:00 we need to have 100 carrots, on warehouse we have 375pcs = 275pcs are left. Then few hours later we have shipment to other customer which requires 500pcs of carrots, 275-500 = -225pcs -> it shows info we need to harvest that much more untill 11:00.
needed vlookup for value from stock
then subtract every repeated value from top to bottom
carrots example screen
Looking for formula or vba which could handle this calculation without manual addition of many columns - currently I have something done with countif for as much as 10 duplicate ID - it just adds "1-"&ID then subtract this and takes it as "2-"&ID.. etc. It's very slow on performance.
As for VBA there is probably no possibility to dynamically declare ID from range as variable from stocks and then simply subtract in loop?
Something like this should work (paste in B2 and use autofill) :
=VLOOKUP($B2,$K$3:$L$17,2,FALSE)-SUMIF(INDIRECT("$B$2:$B$" & ROW()),$B2,INDIRECT("$C$2:$C$" & ROW()))
VLOOKUP($B2,$K$3:$L$17,2,FALSE) return the stock value of the item of the current row (777 for row 2)
SUMIF(INDIRECT("$B$2:$B$" & ROW()),$B2,INDIRECT("$C$2:$C$" & ROW())) return the sum of qty ship (of the current row and rows above) of the item of the current row (250 for row 2, 350 for row 5)
what about simple sumifs formula like below?
=L3-SUMIFS(C:C,A:A,J3)
place in cell M3 add drag/copy to the bottom
I have a list of values that looks like this. Every 30min the top row in my data is shifted down and a new latest value is inserted. I'd like to be able to take the average of all the values in the model column from 18:30 to the top most cell each day (so just the latest cell that has an 18:30 value to the top most cell)
Any help would be greatly appreciated
I've been able to find the row that contains the date I need using this:
=MATCH(DATE(YEAR(TODAY()),MONTH(TODAY()),DAY(TODAY()-1))+TIME(18,30,0),AF47:AF4595,0)
So now I just need to able to average from row 1 to the output of that formula. I've tried Index(NamedRange,1:3,0) but that didn't work
=INDEX(AF:AF,1):INDEX(AF:AF,MATCH(DATE(YEAR(TODAY()),MONTH(TODAY()),DAY(TODAY()-1))+TIME(18,30,0),AF47:AF4595,0))
Although I would change your formula just to shorten it...your formula is more readable. I would change your formula to:
MATCH(INT(TODAY())-1+TIME(18,30,0),AF:AF,0)
I was assuming your data was all in AF based on your formula. Adjust AF to match the column of your needs.
Since INDEX returns a cell address, you just need to wrap the range defined by the two indexes in an AVERAGE function:
=AVERAGE(INDEX(AF:AF,1):INDEX(AF:AF,MATCH(DATE(YEAR(TODAY()),MONTH(TODAY()),DAY(TODAY()-1))+TIME(18,30,0),AF47:AF4595,0)))
This is pretty ugly and a roundabout way of doing it, but you can first identify the last row you care about using sumproduct() and some sneakiness. And then pump that into your =Average() formula using Indirect:
=AVERAGE(INDIRECT("B1:B" & SUMPRODUCT((HOUR(A:A)=18)*(MINUTE(A:A)=30)*ROW(A:A))))
It's going to be SLOW though hitting up all of A:A so maybe narrow that range down like A1:A1000 or whatever row is likely to be the max possible row to hold that 18:30 time.
Here is another way using AVERAGEIF:
=IF(NOW()-TODAY()<5.5/24,AVERAGEIF(A:A,">" & (TODAY()-5.5/24),B:B),AVERAGEIF(A:A,">" & (TODAY()+18.5/24),B:B))
It first checks if the current time is before 18:30 then calculates the average as described (from the last 18:30 to now)
An AVERAGEIF/AVERAGEIFS can solve your problem but I see at least three problematic areas.
The 18:30:00 time you want to stop at may or may not be in the same day as the day in the top of the Prediction Area column. This means that you cannot construct a limiting date time from the day at the top of column AF and add TIME(18, 30, 0). You might need to subtract a day if the top of column AF is after midnight and before 18:30:00. A TRUE is considered 1 in a worksheet formula and FALSE is considered zero so taking the date at the top of column AF and subtracting
'Is the time of the datetime in AF47 less than 18:30:00?
(MOD(AF47, 1)<TIME(18, 30, 0))
will make the deciding date today or yesterday depending on the time in AF47.
Your program is inserting Prediction Area datetimes and Model numbers at the top of the list. Depending on the method, this can disrupt conventional formula range addressing, even when using absolute row references. While INDIRECT can be used to 'lock' a cell address by converting from a text string, INDEX is a more efficient method.
'cell address with 'absolute' row (will change with inserted rows)
AF$47
'INDIRECT method (will not change with inserted rows)
INDIRECT("AF47")
'better INDEX method (will not change with inserted rows)
INDEX(AF:AF, 47)
'range of datetimes in column AF
INDEX(AF:AF, 47):INDEX(AF:AF, 95)
Time values typically resolve to pseudo-irrational numbers (aka *repeating decimals') that cannot be relied upon in Excel's 15 significant digit floating point mathematics. For this reason you should use the 00:30:00 interval to ensure true comparity by avoiding >= and <= in favor of > and < against a time value offset by a second. IOW, 18:30:00 is not equal to either 18:29:59.999 or 18:30:00.001.
So if your datetimes (e.g. 04/25/2019 15:00) start in AF47 and are incremented every thirty minutes then the furthest cell you need to examine is AF95 (47 + 24*2).
With Prediction Area in AF46 and and Model in AG46 this is my effort.
' |<----------AG47:AG95---------->| |<----------AF47:AF95---------->| |<----AF47---->| |<----AF47---->|
=AVERAGEIFS(INDEX(AG:AG, 47):INDEX(AG:AG, 95), INDEX(AF:AF, 47):INDEX(AF:AF, 95), ">"&INT(INDEX(AF:AF, 47))+TIME(18, 29, 59)-(MOD(INDEX(AF:AF, 47), 1)<TIME(18, 30, 1)))
Truth be told, the AVERAGEIFS function does suffer significantly by using full column references so if there are no rogue values that could produce false positives above or below the ranges referenced, full column references could be used for the average_range and criteria1_range cell range references. Full column references would not be affected by row/data insertion.
Currently. I have it set up when someone enters information in column E (Action Taken) then the whole row will turn yellow so it is easily seen that that item is being dealt with.
Another conditional format that I have set up is that once 5 working days pass on the date entered into column F (Date Actioned) then the row will turn red alerting the user to chase up the issue again.
Every week the user will contact more suppliers on the list regarding the listed product, and fill in their action taken and date actioned.
What I am looking to do is to add up all the suppliers contacted in one week (i.e. week 1 , 05.02.18 to 09.02.18) Which I know can be done by using the formula;
=COUNTIFS(F4:F18,">=5/2/18",F4:F18,"<=9/2/2018")
HOWEVER I only want to count each company once! So even though between the date 05.02.18 to 09.02.18, 8 actions were carried out, they only contacted 4 suppliers.
Is this possible? (FYI the screenshots attached are just a quick mock-up of the real document which contains thousands of products and more in-depth information).
If you don't mind adding a couple of working columns, the following is a possible solution:
Step 1
Set up two cells to contain the min and max dates for your range that you used in your formula =COUNTIFS(F4:F18,">=5/2/18",F4:F18,"<=9/2/2018"). This will allow you to up date things without having to recopy the formula each time. I used cells E1 and G1 for min and max date respectively.
Step 2
In a new column generate a list of supplier IDs that match your criteria. I arbitrarily chose column H. I placed the following formula in H4 and copied down:
=IF(AND(F4>=$E$1,F4<=$G$1),A4,"")
Step 3
In a new column generate a list of the count of the first time a supplier ID occurs from column H and do not count blank spaces. I arbitrarily chose column I. I placed the following formula in I4 and copied down:
=--(AND(COUNTIF($H$4:H4,H4)=1,H4<>""))
Step 4
Take the sum of the results from step 3. I arbitrarily chose to place the following formula in I19:
=SUM(I4:I18)
The "cop out" route, if you were only doing the calculation for 1 week would be to have a Pivot Table, with the Company as the Rows and the Date as the Columns. Then filter your columns, and you get a row per Company that week.
The Full route means looking into Array Formulae - you type one of these like normal, but instead of pressing [Enter], you press [Ctrl]+[Shift]+[Enter], and the equation will show in curly braces. (This is why they are sometimes called "CSE Formula" for "Control, Shift, Enter")
~Warning - This is a long walk through how I calculated the final formula. Hopefully it will make sense though!~
An array formula lets you iterate through every row in a range, calculate them seperately, and then add them all together at the end. This gives us the outside term - everything goes inside a =SUM(..). Press [Ctrl]+[Shift]+[Enter], and this will display as {=SUM(..)}
Now, what calculation do we want to be doing per row? Well, for every row where column F is within date, you want 1 per company within date. Well, another was to say "per" is "divided by" (hence the "Percentage" symbol being "0 / 0" or "%", and the lesser knows "Permille" symbol being "0 / 00" or "‰")
For the sake of reproducibility, I am going to assume that your Count is being done in Cell J2, and you have the Start/End of week dates in Cells H2 and I2
The formula for Row 4 would start out as =IF(AND(F4>=$H2,F4<=$I2), 1/???, 0), where ??? is how many times the Company on row 4 appears. Unfortunately, the AND function does not work with Array Formula. Fortunately there is an easy workaround - since boolean True/False can be treated as binary 1/0, the AND operator is the same as multiplication. Converting from boolean to binary is fastest by double-negation, so AND(F4>=H2,F4<=I2) can be rewritten as --(F4>=H2)*--(F4<=I2), which will work fine with array formula, giving us =IF(--(F4>=H2)*--(F4<=I2), 1/???, 0)
Now, before we work out what ??? should be, I'm going to skip down to row 18. There is method to this madness, I promise! Following the rules laid out above, the formula for row 18 is =IF(--(F18>=H2)*--(F18<=I2), 1/???, 0) - fairly simple? Now, if we want to run this for all rows from 4 to 18, we just need to join the ranges. So, you would get =IF(--(F4:F18>=H2)*--(F4:F18<=I2), 1/???, 0) Turning this into an Array Formula would get you an array of "1/???"s and "0"s, so add it together with SUM to get a single 'flat' number: =SUM(IF(--(F4:F18>=H2)*--(F4:F18<=I2), 1/???, 0))
Remember that "method" I mentioned earlier? Well, if we were looking for a straight Count of actions taken, ignoring the Unique Companies constraint, we could make ??? = 1, to get =SUM(IF(--(F4:F18>=$H2)*--(F4:F18<=$I2), 1, 0)) and hit [Ctrl]+[Shift]+[Enter] - which would give the same result as =COUNTIF(F4:F18, ">="&H2, F4:F18, "<="&I2) - and changing the 1 to D4:D18 would be a SUMIF on Products. (Incidentally, you can remove the IF statement from the CountIf, since the Condition returns 1 or 0 already)
So, last step! What is ??? Well, it's a Count of rows where Date Actioned is within our date bounds, and Company is the same as the current row. So, for Row 4 you have COUNTIFS(B4:B18, B4, F4:F18, ">="&H2, F4:F18, "<="&I2), and for Row 18 you get COUNTIFS(B4:B18, B18, F4:F18, ">="&H2, F4:F18, "<="&I2), making the final ??? become COUNTIFS(B4:B18, B4:B18, F4:F18, ">="&H2, F4:F18, "<="&I2) (The trick here is that the Range arguments are treated as all the cells at once, but the Condition arguments are treated as an array of each cell one-at-a-time)
Now, some people might argue that you need to put your 1/COUNTIFS(B4:B18, B4:B18, F4:F18, ">="&H2, F4:F18, "<="&I2) inside an IFERROR to be safe - however, this is in the TRUE part of an IF statement referrring to the same row, so we know that if the COUNTIF is being evaluated then there will always be at least 1 row that matches.
So, if we stick it all together, and add a load of $ symbols to lock the rows/columns in place (so that you can drag down column J to calculate for different weeks/dates in columns H and I) you get the (slightly unwieldy) formula as follows:
=SUM(IF(--($F$4:$F$18>=$H2)*--($F$4:$F$18<=$I2), 1/COUNTIFS($B$4:$B$18, $B$4:$B$18, $F$4:$F$18, ">=" & $H2, $F$4:$F$18, "<=" & $I2), 0))
And, one last time - Don't forget to press [Ctrl]+[Shift]+[Enter]
(The 2 Date cells, $H2 and $I2 are the only terms I have left 'unlocked', and even then only on the Row)
I have a long row of data that I am averaging week-by-week. I would like to grab the first 7 cells with data and be able to drag my formula over so that it grabs the next 7 days of data. Every time that I try this it always grabs the adjacent cell and averages numbers that I have already averaged in the previous formula:
So what happens is that when I drag to the right it grabs D60:K60 and I want it to grab L60:R60 instead.
How would I accomplish this?
This formula uses OFFSET to both stagger and shape the range which is calculated by AVERAGE.
=AVERAGE(OFFSET($C60, 0, (COLUMN(A:A)-1)*7, 1, 7))
Fill right as necessary. It will process AVERAGE(C60:I60) then AVERAGE(J60:P60), etc.
EDIT:
As OFFSET is a volatile function that re-calculates whenever any calculation cycle occurs within the workbook, here is a non-volatile equivalent.
=AVERAGE(INDEX(6:6, 1, (COLUMN(A:A)-1)*7+3):INDEX(6:6, 1, (COLUMN(A:A)-1)*7+9))
This may have a simple solution which I haven't found yet. but here's the situation.
I have a data in Excel sheet:
This is a log file generated from simulations. The simulation is run tens of times (variable) and each run generates one block starting at "-------------------" and ending before the next "-----------------" divider. The number of rows between these dividers is variable but certain things are fixed. the number and order of columns and the first row & cell being the divider, the next row in the same column having date stamp, the next row having column headings. the divider and date stamp are contained in only 1 cell.
What I need to do is mind the MAX of CNT & SIM_TIME for each simulation run. I will then take the average of these. I only need to do this for the "Floor 1" table from the screenshot.
What's the best way to proceed? which functions should I use? (I have Office 2010 if that has new functions not present in 2007)
General approach, by example:
Data sheet: Sheet1
Results on seperate sheet: Sheet2
Number of rows in data: Cell F2
=COUNTA(Sheet1!B:B)
Intermediate result, Row of data set Cell A3
=MATCH(Sheet1!$B$1,OFFSET(Sheet1!$B$1,A2,0,$F$2),0)+A2
Intermediate result, row of next data Cell B3
=IF(IFERROR(N(A4),0)=0,IF(ISNA(A3),"",$F$2),A4)
Max of CNT data set, Cell C3
=IF(B3<>"",MAX(OFFSET(Sheet1!$B$1,$A3+2,0,$B3-$A3-3)),"")
Max of SIM_TIME, Cell D3
=IF(C3<>"",MAX(OFFSET(Sheet1!$B$1,$A3+2,3,$B3-$A3-3)),"")
Date from data set
=IF(D3<>"",OFFSET(Sheet1!$B$1,$A3,),"")
To expand to give results for all available data, copy range C3:E3 down for as many rows as are in data. any extra rows will show N/A in column A and blanks in others
Screen shot of results:
Screen Shot of formulas:
I am not sure i got what you want to do.
Perhaps something like this would work, although it is not automatic. I am making the assumption that the last value of each simulation is the MAX value.
Put the following formula at cell "I4" =if(B5 = "---------" ; B4 ; "")
Pull the cell formula down till the last row of "Floor 1"
Calculate the average =average(I:I). Don't put this type on column I!!!
Notes
use as many "-" as there are at cell B22
you may want to insert a new column between I and J, in order to average SIM_TIME. The procedure is the same. Only the cells change.
You could easily automate this procedure a little bit with macros.