storing row numbers only in array using VBA - arrays

I was just wondering if there is a short and simple way to store the row number of cell location into an array. I have only been to store the entire cell location using the '.Address' vba function but I don't want the columns referenced so I can maniuplate the arrays later on in my sub.

If you want to get the row of a range, you can use the row property :
Dim myCell as Range
Dim myRow as Long
myRow = myCell.row
You can, of course, store the row in an array.
By the way, here are some tips about rows and columns : http://www.exceltip.com/excel_tips/Cells,_Ranges,_Rows,_and_Columns_in_VBA/204.html
Regards,
Max

Try:
Sub HTH()
Dim rCell As Range
Dim vMyArray() As Variant
Dim iLoop As Integer
For Each rCell In Range("A1:A10")
ReDim Preserve vMyArray(iLoop)
vMyArray(iLoop) = rCell.Row
iLoop = illop + 1
Next rCell
End Sub

Related

Store element from excel into array VBA

I have some data in terms of a column that I want to store into an array using VBA. After storing it, I will reference the element in the array and make a comparison.
Dim tRange As Range
Set tRange = wb.Sheets("wbname").Range("A1:A5")
Lets say I want to store column A with 5 row into the array in VBA. May I know the way?
Here is one way:
Sub Dave()
Dim tRange As Range, wb As Workbook, cell As Range
Dim i As Long
Set wb = ThisWorkbook
Set tRange = wb.Sheets("wbname").Range("A1:A5")
ReDim arr(1 To tRange.Count)
i = 1
For Each cell In tRange
arr(i) = cell.Value
i = i + 1
Next cell
End Sub
NOTE:
This technique does not depend on the "shape" of the range. It will work if the range is a piece of a column, or a piece of a row, or a rectangle of cells, or even a disjoint set of cells.
You can just declare a Variant data type and make it equal to the range.
Dim DirArray As Variant
DirArray = Range("a1:a5").Value
This was answered in a previous question by #vacip coincidentally for exactly the same range!
Creating an Array from a Range in VBA

How to populate array from a sheet column in Excel

I have an array like this :
myColumns = Array("Serial","Practice","Manager", "QTD")
But I want to fetch its values from a sheet to make it more dynamic. (The values & their number may vary)
So I tried this to affect the range from A2 to last value of the column to my array:
myColumns = Range(Range("A2"), Range("A2").End(xlDown)).Value
It results in :
UBound(myColumns) -> 4 -> OK
BUT when I do this :
s = myColumns(3) -> Subscribe out of range !
How is that possible?
How can I populate it correctly?
Thank you!
Application.Transpose is a good friend of yours, if you are parsing a single column:
Sub TestMe1()
Dim myArr As Variant
myArr = Application.Transpose(Range("A1:A10"))
Dim cnt As Long
For cnt = LBound(myArr) To UBound(myArr)
Debug.Print myArr(cnt)
Next cnt
End Sub
If you are parsing a single row, you should transpose twice:
Sub TestMe2()
Dim myArr As Variant
With Application
myArr = .Transpose(.Transpose(Range("A1:AI1")))
End With
End Sub
If you are simply parsing multiple range or without .Transpose(), you have to refer to both columns and rows:
An article I wrote about it some time ago.

VBA: How do I filter by an array that I created from range of cells

I know I am creating the array correctly and I have used the autofilter code with arrays before but for some reason when I try to filter by a dynamic array only the first value of my array comes back. I create the array from an already filtered list on one sheet and then go to a different sheet to filter by the array values.
Dim StepArray As Variant
Dim LastRow As Long
LastRow = Cells(Rows.Count, 1).End(-4162).Row
StepArray = Range("C4:C" & LastRow).SpecialCells(xlCellTypeVisible).Value
Sheet2.Select
LastRow = Cells(Rows.Count, 1).End(-4162).Row
Range(Cells(1, 1), Cells(LastRow, 5)).AutoFilter Field:=4, Criteria1:=StepArray, Operator:=xlFilterValues
End Sub
edited to add the case the filtered range is a contiguous one
Range values to array doesn't work with non contiguous ranges like a filtered one is much likely to be
you have to loop through range and fill the array, like
Function GetFilteredValues(rng As Range) As Variant
Dim cell As Range
Dim iCell As Long
ReDim arr(1 To rng.Count)
For Each cell In rng
iCell = iCell + 1
arr(iCell) = cell.Value
Next
GetFilteredValues = arr
End Function
to be used in your main code as follows
StepArray = GetFilteredValues(Range("C4:C" & LastRow).SpecialCells(xlCellTypeVisible))
Should filtered range be actually a contiguous one then you have to transpose it and get a one-dimensional array
StepArray = Application.Transpose(Range("C4:C" & LastRow).SpecialCells(xlCellTypeVisible).Value)
StepArray is treated as a value because you didn't set it to be a range.
Set StepArray = Range("C4:C" & LastRow).SpecialCells(xlCellTypeVisible)
Maybe better? Just a suggestion, I never tried to filter with arrays.

Using VBA to assign range of cell values to array of variables

I'm very new to VBA, to bear with me here.
I want to assign a set of variables the value of a set of ranges ie. run a brief code to simplify the following
Dim Sample 1 as string
Sample1 = activeworksheet.range("C17").value
Dim Sample 2 as string
Sample2 = activeworksheet.range("C18").value}
and so on
Following an excelfunctions.net tutorial, I know that I can shorten the declaration to
Dim Sample(1 to 20) as a string
But the tutorial drops it there(because it's a tutorial about names), suggesting I populate it as follows
sample(1)=activesheet.range("C7").value
sample(2)=activesheet.range("C7").value
and so on
I found the discussion below to be on the right track to answer my quest, but I am having trouble applying it to my situation. (Excel VBA Array Ranges for a loop)
As a follow up note, I am ultimately trying to assign values to these variables for use in the following procedures, rather than declaring and assigning them each time.
Thanks!
Try something like this:
Sub test()
Dim sampleArr(1 To 20) As String
Dim i As Integer
Dim rng As Range, cel As Range
i = 1
Set rng = Range("C1:C20")
For Each cel In rng
sampleArr(i) = cel.Value
i = i + 1
Next cel
For i = LBound(sampleArr) To UBound(sampleArr)
Debug.Print sampleArr(i)
Next i
Also, if you know the range you want to put into an array, you can simply set an array to that range:
Sub test()
Dim sampleArr() As Variant
Dim i As Integer
Dim rng As Range, cel As Range
i = 1
Set rng = Range("C1:C20") ' Note, this creates a 2 Dimensional array
sampleArr = rng ' Right here, this sets the values in the range to this array.
For i = LBound(sampleArr) To UBound(sampleArr)
Debug.Print sampleArr(i, 1) ' you need the ",1" since this is 2D.
Next i
End Sub
You should :
Define the range you want to retrieve data
For each cell of the range, retrieve your datas
dim tab() As string, cell as range, i as integer
i = 0
redim tab(0)
for each cell in ActiveWorksheet.Range("C1:C20")
tab(i) = cell
i = i + 1
redim preserve tab(i)
next
edit : I indent the code to display it correctly
Additional way to the above you can only use:
Arr = ActiveWorksheet.Range("C1:C20").Value
Then you can directly use:
Arr(i,1) where i is C1 to C20 range!

VBA Why does Application.Countif return an array or error 424

I would like to count the number of matching items in an array. I tried using
Application.Countif
MyCount = Application.WorksheetFunction.CountIf(Myrange, val)
but this returns an array full of errors rather than a simple count. I have also tried using Application.WorksheetFunction.Countif but this causes a 424 error.
I currently am testing on a worksheet with a short list of names in cells A1:A20, but ultimately I plan to use this code with a very large CSV file and I want to load the information into an array before using CountIf (rather than using the range).
Sub TestCount()
Dim MyCount
Dim Myrange As Variant
Dim val As String
val = "Addison"
Myrange = ActiveSheet.Range("A1").CurrentRegion.Value
MyCount = Application.WorksheetFunction.CountIf(Myrange, val)
MsgBox (MyCount)
End Sub
Can anyone suggest what I did wrong?
You have several problems.
Using CountIf
First, if I understand right, you are intentially trying to use the Application.WorksheetFunction.CountIf statement on an array. That will only cause trouble, since CountIf (as the statment suggests) is a "worksheet function" not a "VBA Array function".
Ditto has created a solution that uses CountIf correctly, by setting a range in the worksheet on which the CountIf statement performs its job. If all you want is a way to count the value within that range, that is the way to go.
Creating an array from a range
Second, if you really need to get the items out of the worksheet and into an array (for example, if you plan to work with those values in ways you don't want to effect the worksheet), you should know that you have only partially solved the question of creating an array of values from a range selection.
You are correct that to establish an array by assigning a range to a variable you need a variant, but you have forgotten the parenthesis, which are an essential part of denoting an array.So, instead of Dim Myrange As Variant you should use Dim Myrange () As Variant
Having established MyRange as an array, you can now assign the array values by saying MyRange = Range("x") where x is the area being captured. You do not need to (or want to) use .Value for this. VBA will automatically do that for you. So, in your case you want to use the CurrentRegion for Range("A1") which is done like this: MyRange = Range("A1").CurrentRegion. You could also use a closely defined range like this: MyRange = Range("A1:A12") or MyRange = Range("C7:F14"). Note: I left off the ActiveSheet because it does not work when assigning ranges to arrays. The assumption is that you are using the active sheet, and the current region is for the cell indicated in the Range("x") statement.
Counting values within the array
Third, once you have succeeded in creating an array, you won't be able to use Countif (as noted above). You'll need to create a method of counting that value within the array. There are several considerations in doing this.
Since an array created from a range will be two dimensional and may have more than one column, you should not assume just one column. You will want to create a variable that holds the number of rows and number of columns, so you can loop through the entire array. Something like this:
Dim Row As Long
Dim Col As Long
You will want to define the limits of your loops using the UBound of the array dimensions. Something like this:
Dim RowNumber As Integer
RowNumber = UBound(MyRange, 1)
Dim ColNumber As Integer
ColNumber = UBound(MyRange, 2)
Code for using an array to find your count
I think the following code will do what you want using an array created in the manner you were attempting:
Sub TestCount()
Dim MyCount As Long
MyCount = 0
Dim MyRange() As Variant
MyRange = Range("A1").CurrentRegion
Dim val As String
val = "Addison"
Dim Row As Long
Dim Col As Long
Dim RowNumber As Long
RowNumber = UBound(MyRange, 1)
Dim ColNumber As Long
ColNumber = UBound(MyRange, 2)
For Col = 1 To ColNumber
For Row = 1 To RowNumber
If MyRange(Row, Col) = val Then MyCount = MyCount + 1
Next Row
Next Col
msgbox MyCount
End Sub
Just because this horse hasn't been beat enough already..here is a 1 liner
Sub Button3_Click()
MsgBox Application.WorksheetFunction.CountIf(Range("A1:a20"), "Addison")
End Sub
Try this:
Sub TestCount()
Dim MyCount
Dim Myrange As Range
Dim val As String
val = "Addison"
Set Myrange = ActiveSheet.Range("A1:a20")
MyCount = Application.WorksheetFunction.CountIf(Myrange, val)
MsgBox (MyCount)
End Sub
1) define "Myrange" as a RANGE, not a variant.
2) use "set" keyword to assign range to Myrange
3) give it the range you want: "a1:a20", not just "a1"
Yes, you didn't declare you range as a range type, so you didn't set the range.
Sub Macro1()
Dim val as String
Dim r As Range
Set r = Range("a1:a20")
val = "Addison"
MsgBox Application.WorksheetFunction.CountIf(r, val)
End Sub
or
Sub CritSrh_Column()
Dim cell As Variant
Dim counter As Integer
For Each cell In Range("A1:A20")
'could use ("A:A") to search the whole column #not recommended#
'for dynamic rows, use end.xl('direction')
If cell.Value = "Addison" Then
counter = counter + 1
End If
Next
MsgBox counter
End Sub

Resources