My formula gives #DIV/0 if range is empty/blank. Instead, I would like result to be "" or "0" instead.
=IFERROR("Total = $"&FIXED(SUBTOTAL(9,L3:L85),0,0)&"
≥ $10K Count = "&COUNTIF(L3:L85,">=10000"),"≥ $10K Count = 0")&" or "&FIXED(SUM(COUNTIF(L3:L502,">=10000")/COUNTA(L3:L502)*100),0)&"%"
Can anyone suggest how to improve the formula?
This section of your formula has the risk of an error of divide by zero:
COUNTIF(L3:L502,">=10000")/COUNTA(L3:L502)*100
So you just need to wrap that in another IFERROR function:
IFERROR(COUNTIF(L3:L502,">=10000")/COUNTA(L3:L502)*100,0)
And insert that back into the overall formula:
=IFERROR("Total = $"&FIXED(SUBTOTAL(9,L3:L85),0,0)&"
≥ $10K Count = "&COUNTIF(L3:L85,">=10000"),"≥ $10K Count = 0")&" or "&FIXED(SUM(IFERROR(COUNTIF(L3:L502,">=10000")/COUNTA(L3:L502)*100,0)),0)&"%"
Related
I've got a matrix, with two coordinates [i;j]
I'm trying to automatize a lookup:
As an example, this would have the coordinates of [1;2]
Here's a table of all the coordinates:
So here, obviously [1;2] would equate to 143,33
To simplify the issue:
I'll try to go step by step over what I'm trying to do to make the question bit less confusing.
Think of what I'm trying to do as a function, lookup(i, j) => value
Now, refer to the second picture (table)
I find all rows containing index [i] (inside column C) and then
only for those rows find row containing index [j] (inside column D ∩ for rows from previous step)
Return [i;j] value
So if u invoked lookup(2, 4)
Find all rows matching i = 2
Row 5: i = 2 ; j = 3
Row 6: i = 2 ; j = 4
Row 7: i = 2 ; j = 5
Lookup column j for j=4 from found rows
Found row 6: i = 2 ; j = 4.
Return value (offset for yij column = 143,33)
Now this isn't an issue algorhitmically speaking, but I have no idea how to go about doing this with excel formulas.
PS: I know this is reltively simple vba issue but I would prefer formulas
PSS: I removed what I tried to make the question more readable.
You can use SUMPRODUCT, which return 0 for not found values:
=SUMPRODUCT(($C$4:$C$18=$I4)*($D$4:$D$18=J$3)*$E$4:$E$18)
or AGGREGATE, which returns an error that can be hidden by the IFERROR function:
=IFERROR(AGGREGATE(15,6,(1/(($C$4:$C$18=$I12)*($D$4:$D$18=J$3)))*$E$4:$E$18,1),"")
You can use SUMIFS here assuming you will not have exact duplicate combinations of [i, j]. If you did have a duplicate combination, the amounts will be summed and placed in the corresponding cell
In cell B2 place this equation: =SUMIFS($Q$2:$Q$16,$P$2:$P$16,B$1,$O$2:$O$16,$A2) and drag across and over as needed
IF you want to convert the 0's to blanks you can nest the above formula inside a text formatter like so:
=TEXT([formula], "0;-0;;#")
I am having an issue with an excel problem and cannot use vba or add any extra columns. The problem goes along with the format of this image. I could not find anything on google that helped me with this problem and im sorry if it has been asked before.
Example Image
On a separate page in a cell i need to write a function that will check if Info 2 = "z" and Info4 = "x" and if that is true then i need to do the following equation with the numbers in Info1 and Info3: Info1*(1 - Info3)
I will also have to keep a sum of these numbers.
For this example I would want the cell with the formula to equal -34 by doing the following:
3*(1-4)+5*(1-6) = -34
I would want the cell to just display the finished sum
Any help would be greatly appreciated,
Thank you!
You are looking for the mighty powers of SUMPRODUCT
=SUMPRODUCT((B:B="z")*(D:D="x")*(A:A)*(1-C:C))
The first two multipliers will make sure we only evaluate those rows having z for B and x for D. While the latter two are your desired function. Excel will evaluate this for each row and sum up the results.
I am using psuedo values below but this should work:
= [value of cell above] + if(and([info2] = "z" , [info4] = "x"), [info1]*(1-[info3]),0)
so basically starting in the middle, you have a two truth tests,
[info2] = "z", [info4]= "x"
using AND() requires they both pass
and([info2] = "z", [info4]= "x")
if they do pass you want to do your formula:
if(and([info2] = "z" , [info4] = "x"), [info1]*(1-[info3]),FALSE)
but since we want to sum all values for each iterative row we make not passing this test 0:
if(and([info2] = "z" , [info4] = "x"), [info1]*(1-[info3]),0)
Ok so this works for one row, but doesn't sum the numbers from the tests on the previous row:
= [value of cell above or 0 for first row] + if(and([info2] = "z" , [info4] = "x"), [info1]*(1-[info3]),0)
an example written with real excel ranges that you may have to tweak depending on where your values are stored:
Sample picture
I have a set of values as following in a row:
(9,888,000) (88,410,205) (76,030,786) (62,712,494) (48,416,610) (33,102,893) (16,729,517) 746,979 19,371,753 39,191,722 43,755,624 66,114,081 89,819,671 114,926,989 141,492,724
Each value represents some amount in a specific year. e.g.(16,729,517) is the cash outflow in year 7.
Now I've an amount of 110,000,000 as the initial payment in another cell.
Now i try to calculate payback year of initial payment. For me payback period should be: 7.96 as in that year amount becomes positive.
But I'm unable to calculate this 7.96 value. can anyone please help?
i've done it via indirect method:
as first step I check value in each column and store true or false against positive and negative values.
2nd Step: =MATCH(TRUE,Complete Array,0). This gives me 8 as Digit, where it finds first positive value.
Then, as third step, i use this formula:
=Year-OFFSET(CFC,0,Year)/OFFSET(Investment,0,Year) .
in this case Year is what i got in step 2. and CFC cell is empty (Cumulative Cash Flow in 0 year). Out put of this 7.96, which is my required value.
But this is a lengthy and indirect way. I want to have a one line formula for all these calculations.
You can combine your formula into a single line. Here's a slight variation on what you are doing, which is a straight line extrapolation between the values below and above zero:
=FORECAST(0,{-1,0},
OFFSET(CashFlows,,MATCH(TRUE,CashFlows>0,0)-2,1,2))
+MATCH(TRUE,CashFlows>0,0)
You may need to change the offset formula if your CashFlows range is in a column instead of a row. The formula is entered as an array formula by holding down ctrl+shift while hitting enter
EDIT This formula ignores the very first cash flow whether positive or negative. If you want to include it, change the > operator to >= and test for an error.
Your formula approach seems natural. I am not sure that you can do much better then what you are doing, although I'm sure that an array-formula guru could find a way to wrap it all into a single, albeit not-quite readable formula.
Using VBA you can write a function which can be called directly from the spreadsheet. In a standard code module put:
Function PayBack(R As Range) As Variant
'R is a range, assumed to be 1-dimensional
'consisting of negative numbers which
'at some point transition to positive
'returns the cross-over point
Dim i As Long, n As Long
Dim x As Double, y As Double
n = R.Cells.Count
x = R.Cells(1).Value
If x >= 0 Then
PayBack = CVErr(xlErrNA)
Exit Function
End If
'x < 0 in the following loop:
For i = 2 To n
y = R.Cells(i).Value
If y >= 0 Then
x = Abs(x)
PayBack = i - y / (x + y)
Exit Function
End If
x = y
Next i
'if the code reaches here -- still negative, so return error
PayBack = CVErr(xlErrNA)
End Function
Then it could be used like:
I have your sample data in row 1 (so A1:O1) and in A3 I just entered the formula
=PayBack(A1:O1)
and it computes as expected. It returns #N/A error if there is no negative to positive transition in the data -- though that can of course be tweaked in various ways.
I need some help on looping with FormulaR1C1 when using Vlookup.
I had been looking for threads related to what I needed but no help was found. I am trying to increase the lookup value cell after each loop but there is always defined error.
I need the "VALUE" to increment by 2 each time it loop pass the code.
The problem is that the VBA does not accept the statement, do I have any ways other than using R1C1?
Example code
g=100
VALUE= 5
Worksheets.("NewData").Select
For i = 1 To 7
Worksheets.("NewData").Cells( g + i, 4).FormulaR1C1= "=Vlookup(R[-VALUE]C[+1], Data!R1C1:R100C100, 2, False)"
VALUE=VALUE+2
Next i
You need to concatenate the VALUE data into the formula:
g=100
VALUE= 5
Worksheets.("NewData").Select
For i = 1 To 7
Worksheets.("NewData").Cells( g + i, 4).FormulaR1C1= "=Vlookup(R[-" & VALUE & "]C[+1], Data!R1C1:R100C100, 2, False)"
VALUE=VALUE+2
Next i
I have a excel array with multiple values. Some are less than 256 characters and some have a length greater than 256.
When I tried to do a VLookup using a sample string, I can get results when it matches the rows with less than 256 characters. For rows greater that 256 characters, it returns a '#N/A'.
Is there a way of using Vlookup or by using some other in-built function in Excel that I can overcome this limit?
If you are using VLOOKUP like this
=VLOOKUP(A2,D2:Z10,3,FALSE)
i.e. looking up A2 in D2:D10 and returning a result from F2:F10 then try this formula instead
=INDEX(F2:F10,MATCH(TRUE,INDEX(D2:D10=A2,0),0))
change ranges as required
Edit:
I mocked up a sample here - values in A2:A10 are the same as G2:G10 but in a different order. The length of each of those values is shown in column B, the VLOOKUP in column C fails on col A values > 255 chars but the INDEX/MATCH formula in col D works in all cases
https://www.dropbox.com/s/fe0sb6bkl3phqdr/vlookup.xls
I had the same problem and I've wrote this custom primitive vlookup. It doesn't care about the length of your cells' values.
Function betterSearch(searchCell, A As Range, B As Range)
For Each cell In A
If cell.Value = searchCell.Value Then
betterSearch = B.Cells(cell.Row, 1)
Exit For
End If
betterSearch = "Not found"
Next
End Function
PS Can't help but wonder why the original VLOOKUP written by professionals is implemented in this particular case more poorly than this 10-lined func?
This is a drag in replacement for Match() and is also optimised vba code unlike betterSearch above.
Public Function Match2(search As String, lookupArray As Range, Optional match_type As Integer = 0) As Long
Application.Volatile
Dim vArray As Variant
vArray = lookupArray.Value
For i = 1 To UBound(vArray, 1)
If match_type = 0 Then
If search = vArray(i, 1) Then
Match2 = i
Exit Function
End If
Else
If match_type = -1 Then
If search <= vArray(i, 1) Then
Match2 = i
Exit Function
End If
Else
If search >= vArray(i, 1) Then
Match2 = i
Exit Function
End If
End If
End If
Next
End Function
Usage:
Index(rangeA, Match2(LookupValue, LookupRange, 0)
Above Ans said:
Can't help but wonder why the original VLOOKUP written by
professionals is implemented in this particular case more poorly
than this 10-lined func?
Optimisation and performance. If you limit the number of characters to 255 this requires only 2 operations on the CPU where as comparison of variable length strings takes many more steps on the CPU, because you have to repeatedly compare across 255 char widths. Programming languages like VBA obscure this a lot because all of the sub-operations are taken care for you.
For example, to compare 2 strings "Hello" and "abc" of fixed length 5 then we simply do the following operation on the CPU:
0100100001100101011011000110110001101111 //Hello
- 0110000101100010011000110000000000000000 //abc
= -0000000000011000111111001111011010010100 //-419231380
Now you can simply ask whether the result is < 0, > 0, = 0 or even approximately 0. This can be done in 2 CPU operations. If cells are variable length (and formulae also), then first you'd have to use the CPU to pad out the end of the value with 0s to get the strings to the same length, before you can do the operations.
XLookup no longer has such limitation. I was able to Lookup > 500 Characters with it.