Referencing Named Ranges in Range Function (Excel - VBA) - 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

Related

VBA Range change selection, value doesn't change

I have a range variable (called Constr) that is based on data that looks like this
Type Bound1 Bound2 Var1 Var2
X 1 2 3 4
Y 1 2 3 4
--
Z 1 2 3 4
I now use this procedure to change the selection to only the entries before the '--'
Sub Adjust_Selection(which As String, what_in As String, columns As Integer)
Dim row_nr_start As Integer
Dim row_nr_end As Integer
Dim row_nr_delta As Integer
Sheets("Main").Select
row_nr_start = Range(which).Find(what:=what_in, LookIn:=xlValues, LookAt:=xlWhole).Row
row_nr_end = Range(which).Find(what:="--", LookIn:=xlValues, LookAt:=xlWhole).Row
row_nr_delta = row_nr_end - row_nr_start
Range(which).Resize(row_nr_delta, columns).Select
This works and I can see that the selection changes, if I now call it using
Call Adjust_Selection("Constr", "Type", 5)
myitem("Constraints") = Range("Constr").Value
myitem is of type
Dim myitem As New Scripting.Dictionary
however when I access the value it still has everything in it. How can I update the value to only the first few lines up until the '--'?
You are calling Adjust_Selection with the named range Constr and afterwards refer to the named range Constraints. So, of course the result is different because you are referring to two different named ranges.
Furthermore, the named range Constr is not altered. It is merely used as a starting point and then a sub-set is Selected. But by selecting something you are not changing a named range (especially not a differently named range).
So, I am guessing that this is what you are searching for:
Call Adjust_Selection("Constr", "Type", 5)
ThisWorkbook.Names.Add Name:="Constraints", RefersTo:=Selection
myitem("Constraints") = Range("Constraints").Value
Note, that the selection of Adjust_Selection is now "saved" in the new named range Constraints and then myitem is being assigned this named range which is limited to the (correct) selection. Hence, the resulting variable (being a dictionary) contains all elements without the --.
Hi ThatQuantDude, I don't quite understand your question even after trying it out on my own. Based on the examples you gave, I assumed you want to store the selected range data into "Constraints" key? Apart from this, your sub function for selecting the range is working fine.
Call Adjust_Selection("Constr", "Type", 5)
myitem("Constraints") = Range("Constraints").Value
Appreciate if you could elaborate it further so I can better understand what you are trying to do? Thanks.
Range.Resize is a function. It will not change the range; it returns a new one. You just happen to select it, which isn't necessary. Turn your sub into a function returning the result of Range.Resize, and use this function directly on the right hand side of your assignment.
Note that you're not using the same name for your range in both lines of code, which I assume is a typo.

Count characters between two empty space to dashes() in vba

How do I get the length of character between beginning with space and ending with * Here is the image. Column B shows the total len before dasher(-) and my code
Sub xn()
Dim x As Integer
x = 1
If Worksheet("Sheet1").Range("A"& x).len(Right," ") Or _
Worksheet("Sheet1").Range("A"&x)len(Left,"-") Then
len(totallen)
End If
x = x + 1
End Sub
The code posted has multiple issues:
Worksheet is not a valid object - you need to use Worksheets.
.len is not a property of a Range object.
Even in .len was a property of a Range, you would need a
de-reference operator (aka '.') in here: Range("A"&x)len(Left,"-")
If you intend to use the function Len(), it only takes one argument.
You apparently are trying to loop, but you need to use either a For
or For Each loop - it won't loop automatically when you increment x
at the bottom of the sub.
Right is a function, but you're calling it without arguments and they are not optional.
Similarly, Left is a function, but you're also calling it without
the required arguments.
totallen is not declared anywhere, so Len(totallen) will assume
that totallen is a Variant (default for undeclared variables), then
cast it to a String, and then always return 0 because it has never
been given a value.
Anything else I may have missed.
The solution is to use the InStr function. It returns the location in a string of a given sub-string.
Sub xn()
Dim x As Long
Dim sheet As Worksheet
Set sheet = ActiveWorkbook.Worksheets("Sheet1")
For x = 1 To sheet.Range("A" & sheet.Rows.Count).End(xlUp).Row
sheet.Cells(x, 2) = InStr(1, sheet.Cells(x, 1), "-") - 1
Next x
End Sub
I'd also recommend taking a look at the MSDN article on Looping Through a Range of Cells (2003 vintage, but still valid), and Error Finding Last Used cell In VBA.

Referencing Cells within Named Range in 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

VBA Referring to named range

I'm just starting to used named references within my VBA, but have hit a minor problem.
I have a named reference called "SiteCount" that counts the number of sites in a column
=COUNTA(Data!$B:$B)
It is saved as Workbook in scope and works when I use it in a cell as
=SiteCount
I thought I could use this in my code rather than replicate the calculation, however I can not save the value even just as
Sitecount = Range("SiteCount")
I have tried using the worksheet name as well, but I get the same 1004 "Method range of object global failed"
I'm guessing it's something very simple. but I can't figure it out.
Advice is gratefully received :)
Evaluate() should do since it's a formula name not a named range
Dim siteCount as Long
siteCount = Evaluate("SiteCount")
It's not a named range, it's a named formula, so you have to refer to it differently. You can use:
lSiteCount = [SiteCount]
note that the variable name must not be the same as the formula name!
or
SiteCount = Sheets("Data").Evaluate("SiteCount")
or
SiteCount = Application.Evaluate("SiteCount")
If you want to get the values of specific named formulas then:
Sub WhatsInAName()
For Each n In ActiveWorkbook.Names
If n.Name = "SiteCount" Then
MsgBox n.Value & vbCrLf & Evaluate(n.Value)
End If
Next n
End Sub

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.