I would like to use the result of a formula A in another cell that is a part of the formula A and avoid circular reference. Also, iterative calculation doesn't sound like what I need.
Lets say I have a table with a single column of which each cell uses a formula that evaluates the state of the whole table and it does so from the top most cell to the bottom.
For example, formula is =XXX+SUM($A$1:$A$4) where XXX is the content of each cell and the table looks like this initially:
A
--
1 | 3
2 | 5
3 | 1
4 | 6
Lets say I have a trigger for calculation start and the first cell starts calculation:
A1 is now 3 + (3+5+1+6) = 18
after that A2 starts calculation and A2 is now 5 + (18 + 5 + 1 + 6) = 35
after that A3 starts calculation and A3 is now 1 + (18 + 35 + 1 + 6) = 61
after that A4 starts calculation and A3 is now 6 + (18 + 35 + 61 + 6) = 126
So the final table would look like this:
A
--
1 | 18
2 | 35
3 | 61
4 | 126
Please understand that this is a simplified example, I am aware this calculation can be optimized but that is not what I need.
Is there a way to avoid VBA?
Only VBA will allow you to avoid hitting the circular reference problem.
If you are prepared to separate your output from your input then you can use Excel to replicate the calculation steps or with a bit of analysis you can simplify the calculation steps (though I suspect this is what you term as optimizing). Picture below shows both
Related
Suppose I have the following data in exce l:
For each row, I want to know what the average range between each unique pair of variables is.
Is there a way to do this in one go, without having to manually calculate the range between every number pair?
Taking row one as an example, the unique pairs and their ranges are as follows:
8 - 5 = 3
8 - 6 = 2
6 - 5 = 1
The average range is (3 + 2 + 1)/3 = 2.
So, the output should be 2, but I want to know if there is a way to do this all in one formula
Paste the following array formula into cell D1 and drag down as far as necessary:
= SUM(ABS(A1:C1-TRANSPOSE(A1:C1)))/(COLUMNS(A1:C1)*(COLUMNS(A1:C1)-1))
(Obviously, you'll have to change the formula above to whatever your cell ranges are.)
Note this is an array formula, so you must press Ctrl+Shift+Enter on the keyboard when entering this formula rather than just Enter.
See below for a demonstration that this formula works.
As in the example in your question, the result for the first row is 2.
Second row:
10 - 1 = 9
3 - 1 = 2
10 - 3 = 7
(9+2+7)/3 = 18/3 = 6
Also note, this formula works for variable column ranges. (It doesn't just have to be 3 columns.) See below for an example with 4 columns. (The formula is in cell E1 and is evaluating over cell range A1:D1.)
8 - 2 = 6
13 - 2 = 11
11 - 2 = 9
13 - 8 = 5
11 - 8 = 3
13 - 11 = 2
(6+11+9+5+3+2)/6 = 36/6 = 6
I am preparing a keyword ranking excel sheet.
To show rank change i am using simple subtraction i.e. 94 (previous ranking) - 74 (current ranking) = 20 (improvement).
Issue 1: Because the ranking has gone up i need to show +20.
Issue 2: for keyword that was not having ranking i am using 0.
0 (no ranking) - 54 (current ranking) = -54
how to show +54?
You can use
=IF(A1<>0,A1-B1,B1)
EDIT : 1
=TEXT(IF(A1<>0,A1-B1,B1),"+0;-0;0")
See image for reference.
EDIT 2 :
=IF(AND(A2<>0,B2<>0),TEXT(A2-B2,"+0;-0;0"),IF(A2=0,"+" & B2,"-" & A2))
Conditional Formatting:
You'll have to create two conditional formatting rules for Column C.
For negative numbers - =LEFT(C1,1)="-"
For positive numbers - =LEFT(C1,1)="+"
Follow following steps:
Select Column C
Click the Home tab and from the Conditional Formatting drop down (in the Styles group), choose New Rule
Choose the Use A Formula To Determine Which Cells To Format option from the upper pane
Enter =LEFT(C1,1)="+" in formula box (This is for positive numbers)
Click Format and then click the Fill tab
Choose a color from the palette (Choose green as you mentioned in comments)
Click OK twice
Repeat same steps for negative numbers except that the formula should be =LEFT(C1,1)="-" and in formatting select red color.
Suppose you have the following table:
Previous | Current
94 | 74
0 | 54
74 | 94
and put =IF(A2=0;CONCATENATE("+ ";B2);CONCATENATE(IF(A2-B2>0;"+ ";"- ");ABS(A2-B2))) into column C, than your result will be:
Previous | Current | Rank
94 | 74 | + 20
0 | 54 | + 54
74 | 94 | - 20
How can I prescribe which 6 of 8 cells excel uses to make an average?
e.g.:
A1 Art 86
A2 English 88
A3 Law 89
A4 Chemistry 83
A5 Biology 81
A6 Math 1 87
A7 Math 2 67
A8 PhysEd 72
e.g. Average 1 is A1:A6 / 6
e.g. Average 2 is [top 6 highest] / 6
e.g. Average 3 is Chemistry, English and the next top 4 highest / 6
I want to define the list where Average 1 = A1:A6/6, Average 2 = ?, Average 3 = ?
I assume the course descriptions are in column A and the scores are in column B and not Column A
B1:B6 =AVERAGE(B1:B6)
Top 6 =AVERAGE(LARGE(B1:B8,{1,2,3,4,5,6}))
Chemistry + English + top 4
=(SUM(SUMIF(A1:A8,{"Chemistry","English"},B1:B8))+SUM(LARGE((A1:A8<>"Chemistry")*(A1:A8<>"English")*B1:B8,{1,2,3,4})))/6
This last is an array formula and must be entered by holding down Ctrl + Shift while holding down Enter
A longer formula with the same result, but which can be normally entered:
=(SUM(AGGREGATE(14,4,((A1:A8="Chemistry")+(A1:A8="English"))*B1:B8,{1,2}))+SUM(AGGREGATE(14,4,(A1:A8<>"Chemistry")*(A1:A8<>"English")*B1:B8,{1,2,3,4})))/6
For #2, You can use Rank() to identify the top 6, then AverageIf() to average those <=6.
For #3, give Chem & English a value of 1, then use Rank() on the remaining 6 items. Then AverageIf() <=4. This is where it helps to put Chem & English at the top of the list.
Here's an example file showing this:
Click here for the file
Anyway, that's ONE way to solve it... hope it helps!
I want a summation of rates. Let me explain it: I would like to sum the numbers in column D that matches 2 conditions (green rows in excel). First one: column F equal to "closed". Second one: column C equal to those numbers which in turn matches the following condition: column F equal to "Partial Sold". At the same time, EACH number in the previous summation might be divided by the number of column D which matches "Partial Sold" in column F.
There is the example with the table/figure I attached: (4510 / 9820) + (6500 / 9820) + (9100 / 15400) + (2388 / 2995) + (12400 / 9820) + (2904 / 5855).
My cells would be: (D69 / D66) + (D70 / D66) + (D76 / D74) + (D82 / D78) + (D83 / D66) + (D84 / D72).
#Jeeped with your cells would be: (D6 / D3) + (D7 / D3) + (D13 / D11) + (D19 / D15) + (D20 / D3) + (D21 / D9)
.. C D E F
65 # Total Side Condition
66 1 9820 Buy Partial Sold
67 2 3850 Buy Closed
68 3 7151 Buy Partial Sold
69 1 4510 Sell Closed
70 1 6500 Sell Closed
71 4 8180 Buy Open
72 5 5855 Buy Partial Sold
73 6 2553 Buy Open
74 7 15400 Buy Partial Sold
75 2 4600 Sell Closed
76 7 9100 Sell Closed
77 8 7531 Buy Open
78 9 2995 Buy Partial Sold
79 3 3000 Sell Closed
80 10 8691 Buy Open
81 3 2500 Sell Closed
82 9 2388 Sell Closed
83 1 12400 Sell Closed
84 5 2904 Sell Closed
85 11 3848 Buy Open
86 12 7745 Buy Open
To do it in one step with an array formula you could use:
=SUM(IFERROR((D66:D86*(F66:F86="Closed"))/((C66:C86=TRANSPOSE(C66:C86))*TRANSPOSE(D66:D86*(F66:F86="Partial Sold"))),0))
This is an array formula and must be confirmed with Ctrl+Shift+Enter↵.
it will generate a 2D-array holding the original values for closed as rows and divides this 1D array by this:
buils up 2D-array by col C = transposed col C
multiply each row by col D
set all items in each row to 0 if not "Partial Sold"
for each div by 0 the IFERROR will set it to 0
and this all in the SUM will give you your output
I too would recommend using a helper column. You don't need to use array formulas to get to the answer though. You can use the following in the next available column:
=IF(F66="Closed",IFERROR(D66/SUMIFS($D$66:$D$86,$F$66:$F$86,"Partial Sold",$C$66:$C$86,C66),0),0)
This will return values for everything that matches your criteria, and zeroes for everything else. Then you can just take the sum of this helper column as your final summation of rates.
If you really don't want to use a helper column, you can wrap the helper column formula in a SUM and swap out the individual cell references for arrays (i.e. swap F66 for $F$66:$F$86, and so on), then enter it as an array formula with Ctrl+Shift+Enter↵. The whole thing would look like this:
=SUM(IF($F$66:$F$86="Closed",IFERROR($D$66:$D$86/SUMIFS($D$66:$D$86,$F$66:$F$86,"Partial Sold",$C$66:$C$86,$C$66:$C$86),0),0))
I do not see this being done without a helper column. In an unused column to the right of F66, put this array¹ formula.
=IF(AND(OR(C66=INDEX(C$66:C$86*(F$66:F$86="Partial Sold"), , )), F66="Closed"), D66/INDEX(D$66:D$86, AGGREGATE(15, 6, ROW($1:$21)/((C$66:C$86=C66)*(F$66:F$86="Partial Sold")), 1)), "")
Fill down as necessary. The result will be the sum of those 'helper' numbers.
Even if this could be done in a single formula, the calculation overhead would likely be prohibitive. Splitting a portion of the array calculations off to a helper column that can directly reference the value in column C for another lookup reduces this significantly.
¹ Array formulas need to be finalized with Ctrl+Shift+Enter↵. Once entered into the first cell correctly, they can be filled or copied down or right just like any other formula. Try and reduce your full-column references to ranges more closely representing the extents of your actual data. Array formulas chew up calculation cycles logarithmically so it is good practise to narrow the referenced ranges to a minimum. See Guidelines and examples of array formulas for more information.
I have a list in excel and I'd like it to select the higher 3 results, and only 3. It seems easy to do with conditional formatting in this example:
1 | 2 | 3 | 4 | 5 | 6
44 | 78 | 98 | 45 | 52 | 98
Where the 2nd, 3rd and 6th number will be highlighted.
The problem appears with something like this:
1 | 2 | 3 | 4 | 5 | 6
44 | 78 | 78 | 45 | 87 | 98
Excel will highlight the 2nd, 3rd, 5th and 6th number, because the first two (the third on a sorted list) are equal.
How can I make Excel select only one of them?
(the solution doesn't need to use conditional formatting, any tools available on Excel can be used, from formulas to VB, but simplicity it's desirable).
for your conditional formatting, we need to break the tie. One way to do this is to count the number of times a value appears in the previous comparisons.
This would change your conditional formula to
=(RANK(A2,$A$2:$F$2)+COUNTIF($A$2:A$2,A2)-1)<=3
Note that absolute positions are used in some cases, and relative in others.
Breakdown:
RANK(A2,$A$2:$F$2) - Rank formula. You know this one, as you're using it now
COUNTIF($A$2:A$2,A2) - count the number of times the value appears - note that the reference does not have a $ in front of the A after the colon - this is to ensure that the range gets bigger as we process the formula along the row (1st count: A2:A2, 2nd count: A2:B2, etc)
-1 - as the count will always match one number (itself)
so, for your second example,
44 78 78 45 87 98
The new ranks are
6 3 4 5 2 1
and the formulas convert to
=RANK(A2,$A$2:$F$2)+COUNTIF($A$2:A$2,A2)-1
=RANK(B2,$A$2:$F$2)+COUNTIF($A$2:B$2,B2)-1
=RANK(C2,$A$2:$F$2)+COUNTIF($A$2:C$2,C2)-1
=RANK(D2,$A$2:$F$2)+COUNTIF($A$2:D$2,D2)-1
=RANK(E2,$A$2:$F$2)+COUNTIF($A$2:E$2,E2)-1
=RANK(F2,$A$2:$F$2)+COUNTIF($A$2:F$2,F2)-1
for the conditional formatting
I couldn't think of one cell solution, but here is my take with a helper column:
Rank_Row column, check if the Input is duplicated, if yes then add fraction of row number. C2=IF(COUNTIF($B$2:$B$7,B2)>1,RANK(B2,$B$2:$B$7)+ROW()/100,RANK(B2,$B$2:$B$7))
Filter column is using simple RANK in ascending order, you can use this column to filter top 3. D2=RANK(C2,$C$2:$C$7,1)
Drag down the both formulas to copy down.