Increment column value when certain conditions are met in Excel - excel

I am trying to create a formula that increments values for 2 columns based on the previous row, the caveat being that it should increment by 1 when a certain value is present and increment by 2 when another value is present.
I have shown the expected output in columns ID and NUMBER.
You can see 3 sets of data that repeat, this is highlighted by the ID column, this value should increment by 1 every 24 rows - 63, 64, 65 - this can be done manually but if there is a formula for this it that would be very useful.
The main part of this question is column NUMBER, when column C changes to 'emr_p_file' the NUMBER column should increment by 2 but when the next row changes to 'L2_*' then it should only increment by 1.
Row 1 values for ID and NUMBER can be static, from row 2 onwards they should be calculated by a formula of some sort.
Is something like this possible in excel, if so please help.
CSV export:
link:https://pastebin.com/zkjsB9L7

The starting ID and NUMBER in cell F1 and G1 will be static, in cell F2 enter the following formula and drag it down:
=F1+(MOD(ROW(1:1),24)=0)
the logic is to use ROW function to return the row number from previous row, and use MOD function to find out if it is fully divisible by 24, if so increase the previous ID by 1 (which is TRUE returned by the equation in the brackets).
in cell G2 enter the following formula and drag it down:
=G1+IF(C2=C1,0,IF(FIND("_",C1)=3,2,1))
the logic is to use nested IF functions to find out if the data set is the same as the previous data set, if so returns 0, if not means there is a change of data set. The next IF will find out if the old data set starts by LR or emr, if former return 1 otherwise 2.
I notice that your example starting Row 49 is NOT increasing the values in Column G: NUMBER as prescribed. Can you please clarify if you provided incorrect expected outcome for those rows or if there is any missing criteria you did not mention in your post?

Related

Copy and Paste an array of cells with information dependent on a lock cell (from a reference cell) with relative value

I am having the following problem:
I have a list of items number and descriptions starting at A5 and going down, at B5 I have the total sold quantity over a year, C5 corresponds to sales price per unit and D5 to its COGS per unit.
Further down, starting in cell A12 I have a specific item number and its description. I have then the quantity sold of this item each month (cells B13:D13) and underneath I want to have the sales quantity per month times the unit sales price of that item (that is in cells B14:D14).
To do so, from B14 I look up the item number and description in A12, in the list of items I mentioned before ($A$5:$D$7) in order to get the price for that item and then multiply it by that months sold quantity.
The problem with this approach is that when I drag that result along, over the following months, it stops searching the value at A12 and instead looks for the item value at B12, then C12 etc etc.
So in order to fix that I locked the value at A12 using the formula '=B13*VLOOKUP(INDIRECT(ADDRESS(ROW(Artikel)+ROWS(Artikel)-4;COLUMN(Artikel)+COLUMNS(Artikel)-4);TRUE);ItemSales;3;FALSE). Thanks to that, I am able to drag the result of the first month over the next months and to get a right result.
However, I would like to copy the table with the monthly results ( $B$13:$D$15 ) and paste it some rows bellows, and that the item referenced is not anymore the previous one at A12, but a new one let’s say in A26.
I achieve that with the formula k=VLOOKUP(OFFSET(INDIRECT(ADDRESS(ROW();COLUMN()));-2;-1;1;1);ItemSales;3;FALSE)*B27 but this formula doesn’t hold the item number and description value when dragged along, so I don’t get to combine them both
Any ideas how I can make it happen??
I have designed two formulas for you. The first one is for column A. Enter it in A12 and copy down, 6 rows for each row in your Item_Sales range.
=IF(MOD(ROW(),6)=0,INDEX(Item_Sales,INT((ROW()-12)/6)+1,1),IFERROR(INDEX({"Total quantity","Total Sales","Total COGS"},MOD(ROW(),6)),""))
Note that the number 12, wherever it occurs in the formula refers to row 12, where your named range "Artikel" starts. It's the first row where the first item in "Item_Sales" must appear. The number 6 refers to the number of rows in one data set, essentially Rows(12:17) for the first set, Rows(18:23) for the second etc. Your row 16 is hidden, row 17 blank. If you want the formula to write anything there expand the array {"Total quantity","Total Sales","Total COGS"}
The other formula is for cell B13. From there you can copy it to B14:B15. You can also copy B13:B15 to B19 but in its present form the formula will throw an error in B16:B18.
=INDEX(Item_Sales,INT((ROW()-12)/6)+1,MOD(ROW(),6)+1)*IF(ISNUMBER(B12),B12,1)
Again, the meaning of numbers 12 and 6 is as explained above. You would need to modify them if your data or display format changes in the future.
For your better understanding, I used the INDEX function which takes a 2D range and extracts values from it based on coordinates. INDEX(Item_Sales, 1, 2) returns the value of the cell in the first row, second column of the range defined as "Item_Sales". Of course, these numbers can be calculated.
The other functions I use are INT() and MOD(). Int(5/6) returns 0, as does INT(1/6). This function can be used to locate the first row in a set the repeats every 6 rows. INT(13/6) returns 2, INT(19/6)=3. These calculations identify the row numbers in Item_Sales referenced in Artikel.
MOD returns the modulus of a division. MOD(5, 6) returns 5, MOD(13,6) returns 1. If there is no modulus the return is 0. With the help of this information you can repetitively count from 0 to 6 and restart with 0.

Increment by 2 for n rows, increment by 4 once and repeat when referencing data from one sheet to another

thank you for taking the time to look at this question.
I'm looking for an equation that can easily take the numerical values from Sheet 1 (the first picture) which has 2 blank cells in between values for four values and then has 4 blank cells and then the other four values. I'm not sure if I am making sense but hopefully the picture I have attached helps.
Notice 2 blank rows between first 4 rows with values (Rows 2-11) and same between rows 16 and 25.
Also notice the 4 blank rows between the two sets of values.
For me, this is repeated for 700 values, same set up of 2 blank rows for 4 sets of values and then 4 blank rows and then four sets of values with 2 blank rows. I'm sure there is an easier way to do this.
I'm trying to recreate Sheet 2 from Sheet 1 using an equation. Is this possible?
Apologies in advance, English isn't my first language.
If the numbers are going to start in B2 and the intervals and offset staggers are static then,
=INDEX(B:B, 2+(ROW(1:1)-1)*3+INT((ROW(1:1)-1)/4)*2)
If the first number is in S6 then,
=INDEX(S:S, 6+(ROW(1:1)-1)*3+INT((ROW(1:1)-1)/4)*2)
Put this in D2:
=IFERROR(INDEX(Sheet1!B:B,AGGREGATE(15,6,ROW(Sheet1!$B$2:INDEX(Sheet1!B:B,MATCH("ZZZ",Sheet1!A:A)))/(Sheet1!$B$2:INDEX(Sheet1!B:B,MATCH("ZZZ",Sheet1!A:A))<>""),ROW(1:1))),"")
And copy down till you get blanks.
This will return the numbers in order that they appear on sheet 1.
The Sheet1!$B$2:INDEX(Sheet1!B:B,MATCH("ZZZ",Sheet1!A:A)) set the data set bounds. This being an array type formula it needs to reference the smallest possible data set. This part finds the last cell in Column A and sets that as the extent of the data set so we do not do unnecessary iterations.
The MATCH part will return the last row that has text in it, if Column A has numbers then we need to change the "ZZZ" to 1E+99 to get the last row in column A with a number.
The AGGREGATE is working like a small in that it will create an array of row numbers and Errors. It will return ROW Numbers where (Sheet1!$B$2:INDEX(Sheet1!B:B,MATCH("ZZZ",Sheet1!A:A))<>"") return true. And an Error where it returns FALSE.
The second criterion 6 in Aggregate tells it to ignore the errors, so it is only looking at the returned row numbers.
The ROW(1:1) is a counter. As the formula is dragged down it will iterate to 2 then 3 and so on. This tells the Aggregate that you want the 1st then the 2nd then the 3rd and so on.
The chosen row number is then passed to the INDEX and the correct value is returned.
If your numbers are in order (smallest to largest like your example) or you want the output in order(smallest to largest) then you can use this simple equation in D2:
=IFERROR(SMALL(Sheet1!B:B,ROW(1:1)),"")
Then copy down till you get blanks.
Here is another formula you might use.
=INDIRECT(ADDRESS((INT((ROW()-ROW($A$2))/4)*14+ROW(A$2))+(MOD(ROW()-ROW($A$2),4)*3),COLUMN($A$2),1,1,"Sheet1"))
You can paste it to the first cell where you want the result and copy down.
Note that $A$2 is the cell from where all the counting starts. If your data start from A3 you can change the references accordingly. Note further that ROW($A$2) is long for 2. I chose this syntax to enable you to identify the meaning.
COLUMN($A$2), on the other hand, just identifies Column A as the source of the data to be lifted. Row 2 in this formula is insignificant. It's the A that counts. However, COLUMN($A$2) is long for just 1, meaning column No. 1, meaning A. Once you get your bearing in the formula you can replace COLUMN($A$2) with 1.

extract the row number of a function result

I have a simple table with 5 names and 5 grades if you will.
In another column I order the grades using the LARGE function.
Now is there a way to know the row of each of the "ordered" grades to obtain something like that?
White 23 31 5
Red 15 23 1
Green 23 23 3
Blue 18 18 4
Grey 31 15 2
The column I can't calculate is the last one!
You should use the rank() function if you want to rank these grades. Not large().
=RANK(D2,$D$2:$D$6,1)
You can try this
=MATCH(LARGE(B1:B5,1),B1:B5,0)
The result is a number of row...
In Cell D1 Put =INDEX($A$1:$A$5,MATCH(C1,$B$1:$B$5,0))
Then in Cell D2 put =IF(D1<>INDEX($A$1:$A$5,MATCH(C2,$B$1:$B$5,0)),INDEX($A$1:$A$5,MATCH(C2,$B$1:$B$5,0)),INDEX($A$1:$A$5,MATCH(C2,$B$1:$B$5,0)+MATCH(C2,INDIRECT("$B$"&MATCH(C2,$B$1:$B$5,0)+1&":$B$5"),0)))
This will also work when duplicate Grades are present
But I Strongly Suggest using Sort as Follows:
*****Also: ***** Here is the explanation on the above Formulas.
To get the Row that contains the Number we are looking for (the number in Column C) you need yo use the Match() Function. We enter =MATCH(C1,B1:B5,0) in D1:
What this is doing: IS looking to the value in C1, this is 31
It is looking in Range("B1:B5"), And 0 is for an Exact match.
So when look for a match to C1 or 31 we get 5. This tells us that 31 is in Row 5
Now, to get the Value of Column A on Row 5 we use INDEX() Function as Follows:
We add to the =MATCH(C1,B1:B5,0) in D1 as =INDEX(A1:A5,MATCH(C1,B1:B5,0))
This will look in Range("A1:A5") for Row 5 (This is because =MATCH(C1,B1:B5,0) = 5)
And the result will be Grey
Now if we drag this formula down we will find the first problem:
Here are our 2 Issues:
1) We get an `N/A` error in the last row.
2) Although `Green` is only in `Range("A1:A5")` one time we see it twice
even though it would seem that `White` should be twice.
These are cause because:
1) We need to add `$` to the range that will remain the same so when we drag down
the formula is won't shift the range. As is the formula in `D5` is
`=INDEX(A5:A9,MATCH(C5,B5:B9,0))` and we receive the error *because*
`Range("A5:A9")` does not contain `15`, but the issue is we meant
to look in `Range("A1:A5")`
So we change the Formula as so: =INDEX($A$1:$A$5,MATCH(C1,$B$1:$B$5,0))
Take note that we do not use the $ on C1 in the formula cause we WANT this value to change as we move down.
But we still have the issue of double values when they shouldn't be there.
Because D1 is the first cell we won't change the formula in it. As anything that is equal to the greatest value is simply tied with it and I don't see any reason why the order of the tie would matter.
Instead we will start in D2 and enter =IF(D1<>INDEX($A$1:$A$5,MATCH(C2,$B$1:$B$5,0)),INDEX($A$1:$A$5,MATCH(C2,$B$1:$B$5,0)),INDEX($A$1:$A$5,MATCH(C2,$B$1:$B$5,0)+MATCH(C2,INDIRECT("$B$"&MATCH(C2,$B$1:$B$5,0)+1&":$B$5"),0)))
What this is doing is checking if the value of =INDEX($A$1:$A$5,MATCH(C2,$B$1:$B$5,0))
is not equal to the value in the row above. (being a sorted list means all double values would be on top of each other) and If it is NOT the same then use the value, but if it is the same we need to do a little more work.
If the value is not the same we use the Formula INDEX($A$1:$A$5,MATCH(C2,$B$1:$B$5,0)+MATCH(C2,INDIRECT("$B$"&MATCH(C2,$B$1:$B$5,0)+1&":$B$5"),0)))
Now to explain it I will use our example of double values. In D3 we find the formula: =IF(D2<>INDEX($A$1:$A$5,MATCH(C3,$B$1:$B$5,0)),INDEX($A$1:$A$5,MATCH(C3,$B$1:$B$5,0)),INDEX($A$1:$A$5,MATCH(C3,$B$1:$B$5,0)+MATCH(C3,INDIRECT("$B$"&MATCH(C3,$B$1:$B$5,0)+1&":$B$5"),0)))
And because we know that INDEX($A$1:$A$5,MATCH(C3,$B$1:$B$5,0)) will be equal to the above cell (White), and we have gone over how the if true works, I will focus on the if false value of: INDEX($A$1:$A$5,MATCH(C3,$B$1:$B$5,0)+MATCH(C3,INDIRECT("$B$"&MATCH(C3,$B$1:$B$5,0)+1&":$B$5"),0))
We know MATCH(C3,$B$1:$B$5,0) is the Row that contains the first instance of C3 in this case 23 and the row is Row 1 so we need to look for 23 in the row Under Row 1. So we use MATCH(C3,INDIRECT("$B$"&MATCH(C3,$B$1:$B$5,0)+1&":$B$5"),0) which is equal to MATCH("23", B2:B4,0) because we are adding a 1 to the row that has the 1st match for 23 or C3.
that will now return us the Value of 2 as, the value 23 is in the second row of Range("A2:A5"), Red is in Row 1 and Blue in Row 3 of that range as shown:
but we don't want Row 2 we know that 23 relates to Green and that Green is in Row 3 So we add the row the we last found the value 23 (1 or MATCH(C3,$B$1:$B$5,0))to the row we currently found it (2) and get Row 3.
Here is a formula approach based on the methodology outlined in this link. The final layout of this approach is shown below.
I have assumed that there is 1 header row and I use 2 helper columns (D & E). While additional rows can be added to the header, the table must begin in column A in order for the formulas in column E to work correctly.
Although the helper columns could be eliminated by consolidating their formulas into the formulas in column F, I do not recommend it: the resulting formulas would be a pain to maintain.
Formulas Needed
Cell C2: =LARGE(B:B,ROW(A2)-ROW($A$1)) [Copy down to bottom of data]
Cell D2: =MATCH(C2,B:B,0) [Copy down to bottom of data]
Cell E2: =D2
Cell E3: =IF(D3<>D2,D3,E2+MATCH(C3,INDIRECT("B"&(E2+1)&":B"&COUNTA(A:A)),0))
[Copy down to bottom of data]
Cell F2: =OFFSET($A$2,E2-ROW($A$2),0) [Copy down to bottom of data]
Explanation of Answer
There are four steps to getting the answer:
Sort the grades from highest to lowest (as you showed in your example data)
Create a partial ordering of the row numbers for the sorted grades
Get the row numbers for duplicate grades
Use that ordering to show the name for each sorted grade
Sort the grades from highest to lowest
As you have done, my sort uses the LARGE function, which returns the nth largest value in a range or array. As shown, the LARGE function in cell C2 takes the grades in column B. The "n" for LARGE is calculated as the current row number minus the number of rows in the header, in this case the 1 row for cell A1. When the formula is copied down, "n" progresses from 1 to 2 to 3, etc.
Partially order the grade row numbers
The next step is to determine the row numbers for the unsorted grades that correspond to the sorted grades.
To do that, I use the MATCH function to find where each of the sorted grades lies in the list of unsorted grades in column B. MATCH takes three arguments--the value to be matched, the range in which to make the match, and optionally, the type of match, with a value of 0 or FALSE for an exact match--and returns an index number which represents where in the lookup range the match is found (1 for the first row in the match range, 2 for the second row, etc.).
In the formula for cell D2 shown above, the MATCH function on the grade 31 returns 6 since 31 is in the sixth row of column B.
The result for cell D4 shows why it is only possible to get a partial ordering with this formula. While we are trying to lookup the row for the second instance of a grade of 23, the formula returns a value of 2, which corresponds to the row for the first instance of 23. That's because MATCH will always return the first match for 23 it finds, which is on row 2!
Get correct row numbers for duplicate grades
The next step is to get the correct row references for the duplicated row numbers in column D. The formulas that accomplish this are shown for the first three cells in column E of the table.
There are three cases that have to be dealt with in column E:
For the first (and possibly only) instance of the highest grade, it is possible to just use the row number calculated in cell D2.
The second case deals with the first instances of the row references of the remaining grades. For these the rows numbers calculated in column D can again be used (via the TRUE branch of the IF statement in the column E formulas). For example, in cell E2 -- which corresponds to the first instance of grade 23 -- the row number in cell D3 can be used.
The final case is the rows for duplicate grades. Here, the MATCH for each duplicate in column B is recalculated using a sliding range that excludes the previous matches for that grade. For example, for the duplicated grade of 23 in column C, the match is on the range B3:B6, rather than the range of B2:B6 used in the column D calculation.
Diplay the names in sorted order
This final step is straight forward: Get the name corresponding to the sorted grade. Here the OFFSET function is used; its arguments are a cell reference and the number of rows and columns from that reference that the desired value is to be found.

Repeating nested functions in Excel

I am trying to use one single formula across multiple cells for calculating a value, dependent on the specific row and column of which the formula is applied, but relative to the row itself. Sounds a little cryptic, so an example:
I have the following three rows,
Row 91: 10|Wheat|60,00|0,00
Row 92: 11|Banana|91,20|1,00
Row 93: 12|Milk|200,00|182,00
Where the | represents a separation between each column, which are named by letter (as Excel does by default). So the value of cell A92 would be 11. Now, column D is generated using the following formula: =((C92/100)*D11), basically taking the value of cell C92 (91,20) dividing it by 100, and then multiplying it by whatever value is held in cell D11 (the same column as the one I am generating a value in, but using the value from column A for reference of what value to multiply by).
Now, seeing as I need to use this formula in many rows, I want to basically to something like this: =VALUE(=CONCATENATE("D"; ROW();)/100)*CELL("address")), but this is not a valid formula. To put it in words:
Get the value of cell D+current row number (for example D9 at row 9 etc.)
Divide this by 100
Multiply this by the value of current column letter+current row number (E69 at cell E69 etc.)
I hope someone has an idea of how to achieve this.
You can do this with OFFSET, but you may very well get circular references or errors if your data is not clean.
=(C92/100)*OFFSET(D92,$A92-ROW(),0,1,1)
The OFFSET says: Get the value of a 1 row 1 column range that is (the value in A92 - current row number) rows offset from this row, but in the current column), which for your data is D11
I think this should do your job:
Sub Test()
Cells(ActiveCell.Row, "D").FormulaR1C1 = "=RC" & ActiveCell.Column & "*RC3/100"
End Sub

Count rows until the sum value of the rows is greater than a value

I want to count how many rows have the sum value no greater than X.
Same as this Sum until certain point - MySql but just with an excel formula and only the row count.
Using the same examples as in the above, first limit should give the value 2 and the second 4.
It's easy to do by adding an extra column. In that column you would keep a running total by filling down the a formula like this
Imagining your data has a header row in row 1 and is in A1 to C6 put this in D2 and fill down
=SUM($C$2:C2)
Then in E2 put this
=COUNTIF(D2:D6,"<500")
Changing the number 500 will give you a different limit.

Resources