For example, suppose I have
{={1,2,3,4,5}}
in a cell. Is there any way to find out how many elements are in that array, and what those elements are?
Now implementing #chris neilsen's idea, I've now got a VBA function as below
Function rinfo(r As Range) As String
With r.CurrentArray
rinfo = .Address & ", " & .Rows.Count & ", " & .Columns.Count & ", " & .Value & ", " & .Value2
End With
End Function
however the data from it doesn't look to hopeful, viz
$A$29, 1, 1, 1, 1
The Rows.Count and Columns.Count make sense if they are counting the rows and cols used in the worksheet. But as an indication of the data in the array formula, no.
Your formula only occupies a single cell, and a cell can only contain a scalar value, so after the cell has been calculated it will contain 1. But you can evaluate the formula from VBA and that can give you an array result. If your formula is in A1 then
Dim vArr As Variant
vArr = Evaluate(Range("a1").Formula)
will result in vArr containing an array of of 4 variants of the 4 numbers. There are several "quirks" to the Evaluate method: see one of my web pages for details.
In a Sub, if cl is a Range and is set to a cell that is part of an array formula, then
cl.CurrentArray
returns the range that contains the array formula.
If your example formula was in cells A1:E1 and the activecell is any of cells A1 .. E1, then running
Sub zx()
MsgBox "ref = " & ActiveCell.CurrentArray.Address
End Sub
would return a message of ref = $A$1:$E$1
You can use .Rows.Count and .Columns.Count to get the size, and .Value to get the values
Related
I want to add a formula to a range of cells using the contents of the cell.
I am relatively new to VBA and I want to make a macro that reduces my work.
The result should be something like this. Using Round formula as an example.
For example, I select a range of cells and the macro adds the formula to the selected range using the contents of that cell. The below image might be clearer in explaining what I want.
Expected Result:
Sub ApplyRoundFormula()
For Each cell In Selection.Cells
If cell.HasFormula Then
StrCurrentFormula = cell.Formula
StrCurrentFormula = Mid(StrCurrentFormula, 2, 999)
cell.Formula = "=ROUND(" & StrCurrentFormula & ",0)"
ElseIf IsNumeric(cell) Then
cell.Formula = "=ROUND(" & cell.Value & ",0)"
End If
Next
End Sub
This script loops through each cell of a selected range (you can change Selection to any range reference), if it has formulas, it crops the equation mark from the beginning and puts the rest into a ROUND formula. If it doesn't have a formula but it has a numeric value, it puts that numeric value into a ROUND formula.
I have a table in Excel as shown in the attached image (Until Column F) and would like to see the final column "Result":
ExcelData:
The Result column should retrieve Column Names where the row values is "IF".
I can use the IF function in Excel, but that would be a long statement that I would have to write to retrieve the final output if there are like 20 columns that I would have to check.
If you are okay with creating a UDF (User Defined Function), then you can essentially create your own worksheet function to do this.
In this function, you will do a quick loop in the input range, and check if any cell in that range is equal to "IF". If so, you will strip the column letter out of the .Address property.
Public Function getIFCols(ByVal rng As Range) As String
Dim retVal As String, cel As Range
For Each cel In rng.Cells
If cel.Value = "IF" Then
retVal = Trim(retVal & " " & colLtr(cel))
End If
Next
getIFCols = Replace(retVal, " ", ", ")
End Function
Private Function colLtr(colRng As Range) As String
colLtr = Split(colRng.Address, "$")(1)
End Function
You will call this function as such:
=getIFCols(B1:F1)
The great thing about this function is that it doesn't require a set amount of columns. So if you need 3 columns checked on one row and 10 on another, it's pretty dynamic.
For Excel Online you can try the texjoin
=TEXTJOIN(",",TRUE,IF(B2:G2="IF",$B$1:$G$1,""))
I have an Excel file populated with a large amount of COUNTIFS functions (above 300). The formulas work fine but I need to be able to find the address for each COUNTIFS result as the data source is very large.
i.e. if COUNTIFs gives me result of 1 for the selected parameters, I need to be able to know which cell/row the function is counting from the data source.
I was thinking this could be done with the ADDRESS function, but I am not sure how this can be used together with COUNTIFS.
I would go with a user-defined function.
Using the below code, you would get this result:
Public Function ListAddresses(SearchTerm As Variant, SearchRange As Range) As String
Dim WS As Worksheet, rCell As Range
Set WS = Sheets(SearchRange.Parent.Name)
SearchTerm = UCase(SearchTerm)
Set SearchRange = Intersect(WS.UsedRange, SearchRange)
For Each rCell In SearchRange.Cells
If UCase(rCell.Value) = SearchTerm Then
ListAddresses = ListAddresses & rCell.Address(False, False) & " | "
End If
Next rCell
If ListAddresses <> "" Then
ListAddresses = Left(ListAddresses, Len(ListAddresses) - 3)
Else
ListAddresses = "<none>"
End If
End Function
Try,
=ADDRESS(AGGREGATE(15, 7, ROW(C$3:INDEX(C:C, MATCH(1E+99, C:C)))/(C$3:INDEX(C:C, MATCH(1E+99, C:C))=1), ROW(1:1)), COLUMN(B:B), 4, 1, "Shett4")
Assuming your criteria rows are aligned, you can find the rows that are going into the count. Referencing the image below, enter this as an array formula (Ctrl+Shift+Enter) in an area with the same number of rows that the COUNTIFS returned (I entered the formula into H2:H4 in the image):
=SMALL(IF(((A2:A11=F1)+(B2:B11=F2)+(C2:C11=F3))=3,ROW(A2:A11)),ROW(INDIRECT("1:"&F4)))
Lets say we have 5000 rows with random values (blanks, numbers, characters). I need to show type of all the cells in these 5000 rows in a single cell using a formula. Is it actually possible? I've tried to CONCATENATE(CELL("type";array)) and ctrl+shift+enter but it didn't work (it returns the type of the first cell in the array).
If you want to know, this is for finding a cell with text rather than values or blanks in a very big file. Maybe you have a better solution.
Thanks in advance.
UPD: thanks for macros but I can't use them in this workbook, I need a formula-solution.
UPD: I've got how to do it with conditional formatting => new rule => use a formula to determine... => use ISTEXT('first cell of the range') formula
But still, is it possible to create the formula?
The best way to go about this is to use MACROs
Here is my sample code:
Sub Button2_Click()
numRows = 10 ' Number fo rows to loop through, in your case 5000
'loop through each cell located in column 1
'Check its type
'Concatenate each one in 1 cell on the 8th column
For i = 1 To numRows
Sheet1.Cells(1, 8).Value = Sheet1.Cells(1, 8).Value & TypeName(Sheet1.Cells(i, 1).Value) & ","
Next i
End Sub
You can adapt this small user defined function to your needs.
Say we are looking at cells in the first row, from A1 through D1 and we want to concatenate their types into a single cell. Enter the following UDF() in a standard module:
Public Function KonKaType(rIN As Range) As String
Dim r As Range
For Each r In rIN
s = "cell(""type""," & r.Address(0, 0) & ")"
KonKaType = KonKaType & Evaluate(s)
Next r
End Function
and then in the worksheet cell E1 enter:
=KonKaType(A1:D1)
I'm looking for a formula to find and replace particular piece of text in a cell.
It sound a bit confusing but you can see what I mean by viewing the following image.
What I'm trying to achieve is when I fill for example cell B1 I would like to replace "SYS-NAME" in cell A25 and other cells where "SYS-NSME" is present.
You need to replace the ** before and after your values. You could change it to "" instead if you want to highlight those inserted values. ** will cause the entire cell to be replaced, instead of its match.
So the code splits column A into 2 sub columns. The first column runs until the first blank row, this contains all your variables and their new value. The second column runs until the end of the last used row. This contains your configuration with the variables that need to be changed.
Sub FindReplace()
Dim NewText, OldText As String
Dim LastRowText, i As Integer
LastRowText = Range("A1").End(xlDown).Offset(1, 0).Row
LastRow = Cells(Rows.Count, 1).End(xlUp).Row
i = 1
Do While i < LastRowText
OldText = Range("A" & i).Value
NewText = Range("B" & i).Value
With ActiveSheet.Range("A" & LastRowText & ":A" & LastRow)
.Replace OldText, NewText, xlPart
End With
i = i + 1
Loop
End Sub
Option without a macro
In your configuration, edit each line with a variable to the following format. This will instantly update the configuration file too.
Cell A25: ="sysname " & B1
Cell A34: ="irf domain " & B2
...
The short answer would be
=SUBSTITUTE(A1,"**SYS-NAME**","MYSYSNAME")
starting in B1.