Referencing Cells within Named Range in VBA - vba

I'd like to know if its possible to use Cells(r, c) within a named range in VBA.
Ex.: I have named range "Test" to be A1:B5 and I am working on a Macro that loops through this range, however I'd like to avoid explicit declarations of ranges as much as possible, so sheet manipulation can be as easier as possible.
In case what I said wasnt possible, I basically need to be able to loop/write through cells in the named ranges, if there is another approach for this I'd be more than glad to get a suggestion.
Thanks!

Sure, you can simply use e. g.
Worksheets("name").Range("Test").Cells(r, c)
and
Dim c As Range
For Each c In Worksheets("Name").Range("Test").Cells
Debug.Print c.Address
Next

I figured it out with a bit more of research
In case anyoone drops by wondering this:
Sub test()
dim r1 as Range
set r1 = Range("NamedRange")
f = r1.row
l = Range("NamedRange").Row + Range("NamedRange").Rows.Count - 1
Do while (Cells(f,1) <> "" and f <= l
'Run code
Loop
end sub

Related

Referencing Named Ranges in Range Function (Excel - VBA)

I'm trying to write a macro that takes a string variable as an input, with the string variable referencing a named range.
Currently what I have is:
Sub SubItems()
Dim M As String
M = "=R[-1]C"
'where M refers to row above, currently it is Manufacturers
Dim g As Range
Set g = Range(" & M & ")
ActiveCell.Value = g(2)
'For Example
End Sub
The problem is with the Set g = Range(" & M & ") syntax
I want the input argument for the Range function to be what M is, and not the literal letter M. Similar to how in C you would do printf('%s', M) for example.
Edit:
Currently how I have the excel sheet setup, is that you select a main item from a drop down menu. Then I want to select the cell below the main item and automatically fill in the rows with sub items. The sub items are stored in a named range that is named after the main item.
Hence I want my macro to automatically read the row above it (Main Item) hence why I have M = "=R[-1]C". Then I want to input that into the range function and that's the problem I'm currently facing.
I hope this clarifies my problem more clearly.
The problem is that your variable M describes a relative reference, and I do not believe you can apply a relative reference to a Range object in the manner you describe. Perhaps you want to attack your problem from a different angle? For instance:
You could use your method but rather set an absolute reference, e.g.
M = "A5"
Debug.Print Range(M).Value
Or alternatively you could specify a relative reference using code such as:
debug.print activecell.Offset(-1,0).Value
String literals are encased in double quotes, so you're essentially referencing a named Range called & M & .
If you're using a string variable, remember that its value is surrounded by quotes as well. So it should just be Range(M), or Range("=R[-1]C"), the two are the same.
Note: =R[-1]C is a very strange name, are you sure you meant this? Make sure you understand the difference between a named range and what's in the range (it looks like a formula)! Perhaps some description on what =R[-1]C is and I can help you more?
What I have understood so far - you have a named range, called M and you want to assign it to a VBA range. If this is the case, this is the code to achieve it:
Sub TestMe()
Dim g As Range
Set g = ActiveSheet.[M]
Debug.Print g.Address
End Sub

Extract Row Locations to Use as Reference

I populated an excel sheet with the locations of blank cells in my sheet using suggestions from this post. So I have a Column A filled with locations in the following format
$X$1 or $X2:$X$4.
What I am trying to do is use those row numbers from the column explain above to populate a separate column. I want to use the row numbers as a reference in what to populate for the column. So a Column B looking something like
=$B$1 or =$B$2:$B$4 (took 1 and 2-4 and used it as row number for reference call)
Both columns are referencing a different sheet so please excuse any column naming.
I'm not sure if this is going to require VBA or if I can get away with just using a formula, I expect VBA due to desired specifics. I've looked at post like this and this. But neither of these fully encompass what I'm looking for. Especially since I want it to express all the contents in a $B$2:$B$4 case.
My intuition on how to solve this problem tells me, parse the string from Column A for the 1st number then check if it's the end of the string. If it is, feed it to the reference that populates Column B, if not then find the 2nd number and go through a loop that populates the cell (would prefer to keep all the content in one cell in this case) with each value for each reverence.
i.e.
=$B2
=$B3
=$B4
My question is how do I go about this? How do I parse the string? How do I generate the loop that will go through the necessary steps? Such as using the number as a reference to pull information from a different column and feed it neatly into yet another column.
If (for example) you have an address of $X2:$X$4 then
Dim rng As Range
Set rng = yourSheetReference.Range("$X2:$X$4")
If you want to map that to the same rows but column B then
Set rng = rng.Entirerow.Columns(2)
will do that. note: it's not so clear from your question whether you're mapping X>>B or B>>X.
Once you have the range you want you can loop over it:
For Each c in rng.Cells
'do something with cell "c"
next c
Something like this should work for you:
Sub Tester()
Dim shtSrc As Worksheet, c As Range, rng As Range, c2, v, sep
Set shtSrc = ThisWorkbook.Worksheets("Sheet1") '<< source data sheet
Set c = ActiveSheet.Range("A2") '<<range addresses start here
'process addresses until ColA is empty
Do While c.Value <> ""
'translate range to (eg) Column X
Set rng = shtSrc.Range(c.Value).EntireRow.Columns(24)
sep = ""
v = ""
'build the value from the range
For Each c2 In rng.Cells
v = v & sep & c2.Value
sep = vbLf
Next c2
c.Offset(0, 1) = v '<< populate in colB
Loop
End Sub
Try this code:
Sub Test()
Dim fRng As Range ' the cell that has the formula
Set fRng = Worksheets("sheet1").Range("A1")
Dim tWS As Worksheet 'the worksheet that has the values you want to get
Set tWS = Worksheets("sheet2")
Dim r As Range
For Each r In Range(fRng.Formula).Rows
'Debug.Print r.Row ' this is the rows numbers
Debug.Print tWS.Cells(r.Row, "N").Value 'N is the column name
Next
End Sub

return a cell in the same row as activecell and first column of a selection in VBA

thanks in advance for your help. I'm new to VBA and I need to select the row header of an activecell -basically building this code, which doesn't seem to work in VBA:
Dim C as range ("I4")
Dim R as C.CurrentRegion
cells(C.row,R.Columns(1)).Select
I can't use C.End(xlToLeft) because I have another table on the left and, although there is one blank column dividing the 2 tables, this code jumps to the table on the left. Also, the first column of my table is not A, and I can't hardcode the column number.
Many thanks if you can help!
Silvia
from that little that can be understood in your post, I'd guess you're after
Intersect(ActiveCell.EntireRow, ActiveCell.CurrentRegion.Columns(1)).Select
or
ActiveSheet.Cells(ActiveCell.row, ActiveCell.CurrentRegion.Columns(1).Column).Select
With no use of "helper" range variables (like yours C or R)
Should you need to use them, then the two alternatives become:
Set C = ActiveCell
Set R = C.CurrentRegion
Intersect(C.EntireRow, R.Columns(1)).Select
or
Set C = ActiveCell
Set R = C.CurrentRegion
ActiveSheet.Cells(C.row, R.Columns(1).Column).Select
but in any case you'd better not select anything and just:
set it to some range variable:
Dim myCell as Range
set myCell = Intersect(ActiveCell.EntireRow, ActiveCell.CurrentRegion.Columns(1))
and then use it:
myCell.Font.ColorIndex = 3

Formula using Cells in the spreadsheet

I am looking for a way to set a variable equal to the number of non-empty cells in Column A using Excel VBA.
So pseudo code
Dim j As Integer
j = CountA(A:A)
This however does not work. Neither does j = "=CountA(A:A)"
Something like this will do the trick.
The VBA functions don't work exactly the same as in the spreadsheets themselves. You need to first select the range of the active worksheet and then call the counta function.
Dim j = Application.WorksheetFunction.counta(activeworksheet.range("A:A"))
Paste this into a module in Excel VBA.
Function CountNonEmptyCells(ColId As Integer) As Integer
Dim r As Range
Dim Count As Integer
Set r = Sheet1.Columns(ColId)
For Each cell In r.Cells
If cell.Value <> "" Then
Count = Count + 1
End If
Next
CountNonEmptyCells = Count
End Function
My end result:
You can also use Evaluate Function like this:
Dim j As Long
j = [CountA(A:A)] 'brackets are shortcut for Evaluate
or explicitly like this:
j = Evaluate("CountA(A:A)")
Essentially, you can either Evaluate the formula as it would appear on the worksheet or you can adapt the syntax to use as an adopted VBA command. Here are a couple variations of each. Note that I am explicitly including a reference to the parent worksheet. This is particularly important for the first two evaluate methods and desirable for all four variations in order that you are not counting column A from the wrong worksheet.
Dim j As Long
j = [COUNTA(Sheet1!A:A)]
Debug.Print j
j = Evaluate("COUNTA(Sheet1!A:A)")
Debug.Print j
j = Application.CountA(Sheets("Sheet1").Columns(1))
Debug.Print j
j = Application.CountA(Range("Sheet1!A:A"))
Debug.Print j
The first simply uses [ and ] as wrappers around the COUNTA formula as it would appear on the worksheet. This forces evaluation of the formula to a result. The second is another evaluation of the formula but using the .Evaluate command allows you the option to construct the formula as a string using concatenation, replacement and other text parsing methods. You can include an equals sign (e.g. =) as a prefix if that makes more sense to you, (e.g. j = [=COUNTA(Sheet1!A:A)]) but it is not necessary.
In the last two, VBA adopts the native worksheet COUNTA function by prefacing it with either Application.Worksheetfunction. or (as above) just Application.. The cell range also moves from worksheet cell notation to VBA style cell notation.

looping through a range of cells

I need to run the function AddColumnofData on each cell from c27 and every contiguous non empty cell to the right, but I get a "Run-time error 424 object required", any help woul dbe greatly appreciated.
Set col = Range("$C$27", Range("$C$27").End(xlToRight))
For Each c In col
AddColumnofData (c)
Next c
On the assumption you have defined AddColumnofData as
Sub AddColumnofData(c As Range)
...
End Sub
your call to it needs to be
AddColumnofData c
(that is, remove the brackets)
Jesse's advice to DIM your variables, while not not manditory is good advice. Applies to col as well. To make it manditory add Option Explicit to the top of your module.
You can declare or set your range objects before passing them to your function. To prove that you are passing the correct values to your function, try this.
Dim r As Range '-- if you don't declare it as a range type you get a variant type as default
Dim c As Range '-- this is used to store the single cell in the For Each loop
Set r = Range("A1:D1") '-- substitute your range as per your example
For Each c In r '-- you could also use r.cells
MsgBox c.Value '-- pass to your function instead of a call to the Message Box
Next
This produces a series of 4 Message Boxes containing the values in cells A1 to D1 of the active worksheet, if your Range "r" is seriously large then pass it to Debug.Print instead.
If you declare c:
Dim c as Range
Then what you have should work.