Is there a way to store specific cells into new variables from a range in VBA? What I mean is...
Suppose I have set the data below to a range call "numbers".
Now in VBA, for each row I want to extract each individual cell value and assign each value to a different variable. And then repeat again for the next row.
I essentially want to the use the values in a given row to do something and then have it repeat again for the next row.
Does this make sense???
This is what I've been playing around with... but I don't get how to assign each cell from a given row to a new variable
Public Sub try()
Dim rng As Range
Dim row As Range
Dim cell As Range
Dim n As Double
Set rng = Range("numbers")
For Each row In rng.Rows
For Each cell In row.Cells
n = cell.value
Next cell
Next row
End Sub
Try this:
Dim numberArray As Variant
' this line will assign numbers inside the range to an array
numberArray = Range("numbers").Value2
' now you are able to access all numbers in you range through this array, like this:
MsgBox numberArray(1, 1) 'it will show 1
The way you are doing it right now doesn't make sense, since you are assigning all values to one variable n, so on every iteration of a loop previous value gets overwritten, resulting in n having last value in a range, which is 3.
Is there any particular reason you want to store any cell value in a new variable?
With a given range it would be very easy to just store your values in a Variant Array. In your example it would be something like:
Public Sub try()
Dim rng As Range
Dim dataArray as Variant
Set rng = Range("numbers")
dataArray = rng
debug.print dataArray(1, 2) 'This would print 7 in your example range
end sub
You could then easily loop through your Variant Array like this:
Dim i as Long, j as Long
For i = 1 To UBound(dataArray, 1) 'This will loop through each row
For j = 1 To UBound(dataArray, 2) 'This will loop through each column (cell in your row)
Debug.Print dataArray(i, j)
Next
Next
UBound() returns the length of the Array at the given dimension as the second parameter. I am just printing the values again since I do not know what exactly your intention is.
Related
I have data organized into rows and in column B I have data titles. I want to select the data after the titles and then give them range names based on that title. I was able to code a solution that could name column ranges dynamically this way, but when altering it to name the rows of data I run into a 1004 error, specifically at the rng.CreateNames point.
Sub RowNames()
Dim ws As Worksheet, firstCol As Long, lastCol As Long, rowNum As Long, r As Integer, n As Integer, rng As Range, rngName As Range
Set ws = ThisWorkbook.Sheets("MonthlySales")
Set rng = ws.Range("B2:N41")
For n = 1 To rng.Rows.Count
For r = rng.Columns.Count To 1 Step -1
rowNum = rng.Rows(n).Row
firstCol = rng.Columns(1).Column
lastCol = rng.Columns(r).Column
If Cells(firstCol, rowNum).Value <> "" Then
Set rngName = Range(Cells(firstCol, rowNum), Cells(lastCol, rowNum))
rngName.CreateNames Left:=True
Exit For
End If
Next r
Next n
End Sub
Naming Row Ranges
Range.CreateNames Method
Frankly, never heard of it. Basically, in this case, you take a range and write different names in its first column and when you loop through the rows, for each row you write something like Range("A1:D1").CreateNames Left:=True to create a named range whose name is the value in A1 and it will refer to the range B1:D1.
To mix it up, this example (I think OP also) assumes that there might be blank cells in the first column, and the number of cells in each row range may vary. Each row range will be checked backwards for a value which will define its size.
The Code
Option Explicit
Sub RowNames()
' Define worksheet.
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("MonthlySales")
' Define Source Range.
Dim rng As Range
Set rng = ws.Range("B2:N41")
' Define Columns Count.
Dim ColumnsCount As Long
ColumnsCount = rng.Columns.Count
Dim RowRange As Range ' Current Row Range
Dim r As Long ' Source Range Rows Counter
Dim c As Long ' Source Range / Current Row Range Columns Counter
' Loop through rows of Source Range.
For r = 1 To rng.Rows.Count
' Create a reference to the current Row Range.
Set RowRange = rng.Rows(r)
' Check if first cell of current Row Range contains a value,
' making it a possible candidate for a defined name.
If RowRange.Cells(1).Value <> "" Then
' Loop through cells (columns) of current Row Range backwards.
For c = ColumnsCount To 2 Step -1
' Check if current cell in current Row Range contains a value.
If RowRange.Cells(c) <> "" Then
' Create a named range from value in first cell. The range
' is defined from the second cell to to current cell
' in current Row Range.
RowRange.Cells(1).Resize(, c).CreateNames Left:=True
' Exit loop, we got what we came for (the named range).
Exit For
End If
Next c
End If
Next r
End Sub
I'm trying to loop trough each row in the range J16:P19, and with every iteration, it must be checked if the value in the cell = 3, and if the text in the corresponding coloumn (range J15:J19) is present in the range ( W1:W7).
eg. If the cell (K17) in the row (J17:P17) = 3 & the corresponding coloumn name (K15) of that cell is present in the range ( W1:W7); the value of in Q17 must be substracked by 1.
This should be done for every row in the range. My code looks like this:
private Sub CommandButton2_Click()
dim rng As Range
dim i As Range
dim row As Range
Set rng = Range("j16:p19")
For Each row In rng.Rows
For Each i In row.Cells
If i.Value = 3 & Cells(i,15) %in% Range("w1:w7") Then
Cells(row,22).Value = Cells(row,17).Value -1
Else
Cells(row,22).Value = Cells(row,17).Value
End if
Next i
Next row
End sub
It works when I select the range to be one column only, and without the second part of the if statement. Do you have any suggestions on have to solve my problem? thank you in advance
Try this.
Not sure why you were referring to column 22? Also "%in%" is not valid VBA syntax. I've used Match instead (which avoids the outer loop), but you could use Find or Countif.
Private Sub CommandButton2_Click()
Dim rng As Range
Dim i As Range
Dim row1 As Range, v As Variant 'better in my view not to call a variable "row"
Set rng = Range("j16:p19")
For Each row1 In rng.Rows
v = Application.Match(3, row1, 0)
If IsNumeric(v) Then 'row contains a 3
If IsNumeric(Application.Match(Cells(row1.row,"J"), Range("W1:W7"), 0)) Then 'corresponding J column value in W1:W7
Cells(row1.row, "Q").Value = Cells(row1.row, "Q").Value - 1 'deduct 1 from Q
End If
End If
Next row1
End Sub
I have coded a specific type of data bar I need in excel. I'm trying to apply this data bar to every other cell in a range of cells. It keeps applying it to all of my cell in my specific range instead of every other one. This is driving me crazy! Please help!
Sub ShadeEveryOtherRow()
Dim Counter As Integer
Dim rng As Range
Set rng = ActiveSheet.Range("N4:N120")
Dim cell As Range
'For every row in the current selection...
For Counter = 1 To Selection.Rows.Count
'If the row is an odd number (within the selection)...
For Each cell In rng.Cells
If Counter Mod 2 = 1 Then
Call Add_Data_Bar(cell, cell.Value)
End If
Next cell
Next Counter
End Sub
You need to use step 2 for your counter. You also need Counter to be defined as an object for Rows. Hope this example helps:
Sub ShadeEveryOtherRow()
Dim Counter As Integer
Dim rng As Range
Set rng = ActiveSheet.Range("N4:N120")
Dim cell As Range
'For every row in the current selection...
For Counter = 1 To rng.Rows.Count Step 2
rng.Rows(Counter).FormatConditions.AddDatabar
Next Counter
End Sub
I have an Excel sheet abc.xlsm" and I have values in "A1" to "A15" in this sheet. I want to copy till 10th row, and then store all the values in an array using VBA.
As mentioned in the comments, please be more specific in your questions: most questions should have at least some bit of code of what you have tried. At any rate this should work, with a couple extra notions:
Sub copy()
'Declaring an array - if you know the data type you can type is as well
Dim varray As Variant
'Declaring other variables - don't need to be separeted, just for clarity
Dim i As Long, iLenghtArray As Integer, rgData As Range, rgTarget As Range
'This is to dimension your array - you have tell VBA the lenght of it, or use REDIM
ilengtharray = 10
'Setting the range reference
Set rgData = Sheet1.Range("$A$1:$J$1")
'Then set the array = to the range you set above
varray = rgData
'Then you can interate over your array like so:
For i = 1 To UBound(varray, 2)
Debug.Print varray(1, i)
Next
'You can also directly past your array into a suitable range
'Setting destination range:
Set rgTarget = Sheet1.Range("$A$2:$J$2")
rgTarget = varray
End Sub
Ideally, I would have a range selected and then I would run the macro and I want the macro to essentially run a loop to go through each row so I can extract information from each row until it reaches the end of the range.
For example, A6:B9 are selected, first I want to focus on A6:B6. As in I want to be able to find the min value of the two cells for instance, using my MinSelected function(stated below) which requires a selected range which would ideally be A6:B6. And I want to do this for each row until the end of the original range.
Function MinSelected(R As Range)
MinSelected = Application.WorksheetFunction.min(R)
End Function
Is there any way to do this??? Please tell me to clarify anything that's unclear. Thanks in advance.
You can loop through rows - but looping through a variant array is more efficient (for many rows)
variant aray
Dim X
Dim lngCnt As Long
X = Range("A6:B9").Value2
For lngCnt = 1 To UBound(X)
Debug.Print Application.Min(Application.Index(X, lngCnt))
Next
range approach
Dim rng1 As Range
Dim rng2 As Range
Set rng1 = Range("A6:B9")
For Each rng2 In rng1.Rows
Debug.Print Application.Min(rng2)
Next
Use a For loop, Rows.Count property, Columns.Count
Dim i as long
For i = 1 to Selection.Rows.Count
For j = 1 To Selection.Columns.Count
Cells(i, j).Value ' Use this to access the value of cell in row i and column j