I am using a range for 5 Employee ID with name of "EmpIDS" and it is working fine, but whenever I am adding a new one I have to set the range again, I think it can be done dynamically, so that the range "EmpIDS" will automatically set the value itself, like-> If I add 5 more rows it will have total 10 values.
Yes you can do it using Counta with Offset and entering this in 'Refers to' when you define the named range:
=OFFSET(Sheet1!$A$1,0,0,COUNTA(Sheet1!$A:$A))
or I prefer to use Index:
=Sheet1!$A$1:INDEX(Sheet1!$A:$A,COUNTA(Sheet1!$A:$A))
See this tutorial
Assumes there are no empty cells in the range - if there are, Counta will give the wrong result, in which case you can substitute
MATCH("zzzzzz",Sheet1!$A:$A)
for Counta with text values, or
MATCH(9E+99,Sheet1!$A:$A)
for numeric values.
Related
I have a global range, let's say for instance A1:A18, that contains value of the same type (only integers or only real numbers) and maybe also empty cells.
Data is dynamically outputted (through an excel function fetching data) in this range : sometimes the whole range contains non empty cells, sometimes not, with the following properties :
both ranges of empty cells (range 2) and non-empty cells (range 1) are "one-piece" ranges
the global range starts with the range 1
Now, in some cell not in the global range, I have the formula =F(A1:18) where F works only for ranges with non empty cells. If my range A1:A18 finishes with empty-cell (and this may well happen), the formula is going to throw an error.
Imagine range 1 is A1:A4. By which (necessarily matrix) formula G(A1:A18,...) depending only on range A1:18, on official excel functions (that is not user-defined excel functions) and not on VBA could I replace the range A1:18 in =F(A1:18) so that =F(G(A1:A18,...)) would in fact calculate =F(A1:A4) ? In others terms : which formula (with aforementioned conditions) gives dynamically A1:A4 from A1:A18 ?
I have also the same question with "#N/A" instead of empty and with "#VALUE!" instead of "empty".
G(A1:A18)=OFFSET(A1,0,0):OFFSET(A1,COUNTA(A1:18)-1,0)does the job
Currently I have a couple of SUM functions setup in my worksheet.
Lets use H2:H34 for my example: If I add a row within that range, the sum function will automatically adjust. The problem is when I add new rows, it is below the range (below H:33). In this case, I would just have to highlight the column and expand/drag the range to where it needs to be. There are a total of 8 columns that are doing a sum function. Is this only possible by using a macro?
=SUBTOTAL(3,H2:H34)
With your formula being the extent of the range minus one row we can use this:
=SUBTOTAL(3,H2:INDEX(H:H,ROW()-1))
Now as rows are added or deleted the reference will remain intact.
If there is a chance that row 2 would be deleted you will get #Ref errors. To avoid that you can use this formula:
=SUBTOTAL(3,INDEX(H:H,2):INDEX(H:H,ROW()-1))
Now there are no specific cell references and adding or deleting will not effect the formula and the range will be dynamic.
you could use a named range like =sum(range1) and something like;
Select first empty cell in column F starting from row 1. (without using offset )
to find the first empty cell to change the reference for the named range.
Triggering it would be difficult... potentially could use on_save?
or option 2.... bit of a dodge, but can work....
you say your sum is in cell H35... maybe move it to h36, and create a dummy hidden row in 35 (0.1 row height). that way when you add a row, it is always above 35. Use sum H1:H35 and it will always auto update? its not a neat solution, but should work
Use the following code, you need to adjust column "H" to whatever column you need.
Dim sumtest As Variant
sumstest = Application.WorksheetFunction.Subtotal(9, Range("H2:H" & ActiveSheet.Cells(ActiveSheet.Rows.Count, "H").End(xlUp).Row))
This is probably an easy one but I just started using VBA recently. So I defined a single column range of about 10 rows and named it CB_CL_Values.
Lets say the range is {1,2,1,3,2,1,1,1,1,3} and right now it's set up to change every values of the range to 1.
Sub Unit_Options_Reset()
Range("CB_CL_Values") = 1
End Sub
Lets say I only want to change values 4 to 10 of that range and leave the first 3 as they are. How would I write this?
Range("CB_CL_Values").cells(4).Resize(7,1).Value=1
Range("CB_CL_Values").cells(4) is the 4th cell in your defined range. By default Cells(r) (with one parameter) takes the r'th cell counting across and then down in your range, so if your range was more than one column wide you should use Siddharth's notation (eg) .Cells(r,1) (r'th row, 1st column).
Note that if you try to address a cewll which technically isn't in your range e.g.:
Range("A1:A10").Cells(20)
Excel will not complain that code will reference A20.
.Resize(7,1) takes that 4th cell and expands the range to 7 rows in height and one column wide (Resize always expands down and to the right from the starting point)
You can use .Cells property of the range to address an individual cell. For multiple cells, you can use a loop.
Range("CB_CL_Values").Cells(r, 1).Value = "Something"
Where r is say 3 for third row.
I'm looking for the most elegant way to count the same number values in a noncontiguous range (I'll refer to it as just 'range'). This is the range:
=$C$2:$C$31,$E$2:$E$31,$G$2:$G$31,$I$2:$I$31,$K$2:$K$31,$M$2:$M$31,$O$2:$O$31,$Q$2:$Q$31,$S$2:$S$7
These are the parameters:
The range contains non-adjacent columns.
The columns differ in height.
The cells in the range are either empty or contain integers.
I'm checking for how many cells equal '1', how many equal '2' etc. in the range. (Not in one go, but in seperate formulas).
I've used a named range to reference the range. I'd really like to use this named range in the formula, in one way or another.
I hope I've given you enough info... Thanks in advance!
I agree with Kartik that a VBA solution is required. However the solution offered is a little inefficient in that it loops over every cell in the ranged passed into the function. It also limits the key parameter to a range reference, and can only count up to 32767 matches. Here's an alternative addresses these shortcomings
Function CountIf_N(rng As Range, key As Variant) As Variant
Dim r As Range
Dim count As Long
count = 0
For Each r In rng.Areas
count = count + WorksheetFunction.CountIfs(r, key)
Next
CountIf_N = count
End Function
Note: assumes Excel 07 or later. If using with an ealier version replace CountIfs with CountIf
One approach is to use excel built in function Countif, but it won't work with non-contigous range. The other way (the easy way) will be to use VBA to create your own custom function, and then use it in excel.
I've presented that technique here.
Goto visual basic editor in excel by pressing Alt+F11, in the project window insert a new module and paste the below code:
Function countif_n(rng As Range, key As Range) As Integer
Dim count As Integer
count = 0
For Each cell In rng
If cell.Value = key.Value Then
count = count + 1
End If
Next cell
countif_n = count
End Function
Here rng is your non-contigous range, and key represent the "range"(cell) which contains the value you want to count. For eg., to check for 1 enter 1 in any cell lets suppose "F2", and your non-contigous range is "testrange"
Then use the above function by entering the following in any blank cell:
=countif_n(testrange, F2)
Although COUNTIF can't handle non-contiguous ranges some functions can, for example RANK and COUNT so for a range called Range this formula will give the number of instances of a number in Z2 within Range
=IFERROR(COUNT(Range)-SUM(RANK(Z2,Range,{1,0}))+2,0)
assumes Excel 2007 or later but can be amended to work in earlier versions
This doesn't quite work if there's stuff below S7 that can't be counted, but you may be able to modify. It also doesn't incorporate the named range.
=SUM(IF(MOD(COLUMN(A2:S31),2)=0,IF(A2:S31=2,1,0)))
This example counts the number of 2's.
This needs to be array-entered with ctrl-shift-enter. It's based on the fact that you're counting in every other column, at least in your example. Also, although you mention the columns are different heights, it looks like all except S are the same height. So maybe there's a way to work around that.
The data in column A looks like this.
RowHeaderThatIsText
RowHeaderThatIsNumber
empty
empty
empty
empty
empty
14.00
-3.00
-4.00
The project goal is to to calculate summary statistics for the series of numbers and update the summary each month.
My goal is to allow a new number to be added to the series and have the summary update automatically.
Here's what I've done so far.
Define a range named LastCell with the formula
=INDEX($A:$A, MAX(($A:$A <> "") * (ROW($A:$A))))
This returns the last non-empty cell in the column. The data to summarize is always the last block of numbers.
Define a named range called HeaderOffset with the formula
=3
Used in the step 3.
Define a range named FirstCell with the formula
=OFFSET(LastCell, HeaderOffset - COUNTA($A:$A), 0)
This returns the first cell of the last block of numbers if, as is the case with the data I'll be summarizing, the cells between the first and last blocks are empty.
Define a range named DataBlock with the formula
=FirstCell:LastCell
So far so good. This allows one to enter =SUM(DataBlock) into any cell and get the expected result of 7.00. And, if I add another value, say 3.00, to the list the SUM result will update to 10.
The part I don't like is HeaderOffset. If another row is added to the header, HeaderOffset needs to be updated from =3 to =4. What if I forget to update HeaderOffset? This lead me to the problem I can't currently solve...
Is there an Excel formula that, given the ending cell, returns the starting cell of a block of data? Basically I'm looking for a FirstCell formula that removes the need for HeaderOffset.
As a bonus I was trying to do this whole thing without using volatile Excel functions. I failed by using OFFSET. Solving this is great. Solving it without volatile functions is ideal.
Is FirstCell always the first number? If so try this to define FirstCell
=INDEX($A:$A,MATCH(TRUE,ISNUMBER($A:$A),0))
That's an "array formula" if entered on the worksheet but doesn't need any special treatment if used in the "refers to:" box to define a named range.
Note: if your final aim is the sum of the numbers then could you just use =SUM(A:A) [I assume that's oversimplifying the issue?]
Revised given comment below:
Try this for LastCell
=INDEX($A:$A,MATCH(9.99E+307,$A:$A))
and this one for FirstCell
=INDEX($A:$A,MATCH(2,1/($A$1:LastCell=""))+1)
assumes LastCell is numeric (although that can be changed if required)