JenniferMurphy
Well-known Member
- Joined
- Jul 23, 2011
- Messages
- 2,676
- Office Version
- 365
- Platform
- Windows
I've run into a little speed bump in some code that is trying to access a named range of data using the name of that range, rather than the range itself. I know some will argue against doing that, but let's leave that aside for now.
To illustrate the problem, I wrote the two little test UDFs below. They both return the address of the target range. The first one, RangeTest1, gets the range passed as a range parameter. It works perfectly.
The second, RangeTest2, gets the name of the range passed as a string parameter. It also works, but with one little glitch. If the range is absolute ($C$R), it returns that address. But if either part of the range address is relative (C$R, $CR, or CR), it returns the address as if it were called from A1.
Here's the code:
And here's a sample of it in action:
[TABLE="class: grid, width: 750"]
<tbody>[TR]
[TD="align: center"]R/C[/TD]
[TD="align: center"]C[/TD]
[TD="align: center"]D[/TD]
[TD="align: center"]E[/TD]
[TD="align: center"]F[/TD]
[TD="align: center"]G[/TD]
[TD="align: center"]H[/TD]
[TD="align: center"]J[/TD]
[TD="align: center"]K[/TD]
[/TR]
[TR]
[TD="align: center"]5[/TD]
[TD]Features[/TD]
[TD]F1[/TD]
[TD]F2[/TD]
[TD]F3[/TD]
[TD]F4[/TD]
[TD="align: center"]Ranges[/TD]
[TD="align: center"]UDF Results[/TD]
[TD="align: center"]Formulas[/TD]
[/TR]
[TR]
[TD="align: center"]6[/TD]
[TD]Weights[/TD]
[TD]1[/TD]
[TD]3[/TD]
[TD]5[/TD]
[TD]7[/TD]
[TD]rngWeights = $D$6:$G$6[/TD]
[TD]$D$6:$G$6[/TD]
[TD]J6: =rangetest1(rngWeights)[/TD]
[/TR]
[TR]
[TD="align: center"]7[/TD]
[TD]Prod1[/TD]
[TD]2[/TD]
[TD]A[/TD]
[TD]4.5[/TD]
[TD]Y[/TD]
[TD]rngRatings = $D7:$G7[/TD]
[TD]$D$6:$G$6[/TD]
[TD]J7: =rangetest1(rngWeights)[/TD]
[/TR]
[TR]
[TD="align: center"]8[/TD]
[TD]Prod2[/TD]
[TD]4[/TD]
[TD]B[/TD]
[TD]6.2[/TD]
[TD]Y[/TD]
[TD]rngRatings = $D8:$G8[/TD]
[TD]$D$8:$G$8[/TD]
[TD]J8: =rangetest1(rngRatings)[/TD]
[/TR]
[TR]
[TD="align: center"]9[/TD]
[TD]Prod3[/TD]
[TD]6[/TD]
[TD]C[/TD]
[TD]5.0[/TD]
[TD]N[/TD]
[TD]rngRatings = $D9:$G9[/TD]
[TD]$D$9:$G$9[/TD]
[TD]J9: =rangetest1(rngRatings)[/TD]
[/TR]
[TR]
[TD="align: center"]10[/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD]$D$6:$G$6[/TD]
[TD]J10: =rangetest2("rngWeights")[/TD]
[/TR]
[TR]
[TD="align: center"]11[/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD]$D$6:$G$6[/TD]
[TD]J11: =rangetest2("rngWeights")[/TD]
[/TR]
[TR]
[TD="align: center"]12[/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD]$D$1:$G$1[/TD]
[TD]J12: =rangetest2("rngRatings")[/TD]
[/TR]
[TR]
[TD="align: center"]13[/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD]$D$1:$G$1[/TD]
[TD]J13: =rangetest2("rngRatings")[/TD]
[/TR]
</tbody>[/TABLE]
The range names and definitions are shown in Col H. rngWeights is absolute ($D$6:$E$6). rngRatings is half relative ($Dn:$En) so the row numbers adjust to match the row number of the calling cell.
The results of the UDF calls are in Col J and the expressions for those calls are in Col K.
In J6 & J7, RangeTest1 returns the correct address for rngWeights. Similarly, in J10 & J11, RangeTest2 also returns the correct address for rngWeights.
In J8 & J9, RangeTest1 returns the correct address for rngRatings adjusting the row numbers to match the row numbers of the calling cells. In J12 & J13, however, RangeTest2 returns the address for rngRatings as if it had been called from A1.
Is there a way that I can get RangeTest2 to return the correct relative address?
Now I know I can get the address of the calling cell and replace the row number, but I'd like a command that does that itself.
Thanks
To illustrate the problem, I wrote the two little test UDFs below. They both return the address of the target range. The first one, RangeTest1, gets the range passed as a range parameter. It works perfectly.
The second, RangeTest2, gets the name of the range passed as a string parameter. It also works, but with one little glitch. If the range is absolute ($C$R), it returns that address. But if either part of the range address is relative (C$R, $CR, or CR), it returns the address as if it were called from A1.
Here's the code:
Code:
'Return address of range, passed as range argument
Public Function RangeTest1(pRange As Range) As String
RangeTest1 = pRange.Address
End Function
'Return address of range, name passed as string argument
Public Function RangeTest2(pRangeName As String) As String
Dim rng As Range
On Error Resume Next
Set rng = Range(pRangeName)
On Error GoTo 0
If rng Is Nothing Then
RangeTest2 = "n/a"
End If
RangeTest2 = rng.Address
End Function
[TABLE="class: grid, width: 750"]
<tbody>[TR]
[TD="align: center"]R/C[/TD]
[TD="align: center"]C[/TD]
[TD="align: center"]D[/TD]
[TD="align: center"]E[/TD]
[TD="align: center"]F[/TD]
[TD="align: center"]G[/TD]
[TD="align: center"]H[/TD]
[TD="align: center"]J[/TD]
[TD="align: center"]K[/TD]
[/TR]
[TR]
[TD="align: center"]5[/TD]
[TD]Features[/TD]
[TD]F1[/TD]
[TD]F2[/TD]
[TD]F3[/TD]
[TD]F4[/TD]
[TD="align: center"]Ranges[/TD]
[TD="align: center"]UDF Results[/TD]
[TD="align: center"]Formulas[/TD]
[/TR]
[TR]
[TD="align: center"]6[/TD]
[TD]Weights[/TD]
[TD]1[/TD]
[TD]3[/TD]
[TD]5[/TD]
[TD]7[/TD]
[TD]rngWeights = $D$6:$G$6[/TD]
[TD]$D$6:$G$6[/TD]
[TD]J6: =rangetest1(rngWeights)[/TD]
[/TR]
[TR]
[TD="align: center"]7[/TD]
[TD]Prod1[/TD]
[TD]2[/TD]
[TD]A[/TD]
[TD]4.5[/TD]
[TD]Y[/TD]
[TD]rngRatings = $D7:$G7[/TD]
[TD]$D$6:$G$6[/TD]
[TD]J7: =rangetest1(rngWeights)[/TD]
[/TR]
[TR]
[TD="align: center"]8[/TD]
[TD]Prod2[/TD]
[TD]4[/TD]
[TD]B[/TD]
[TD]6.2[/TD]
[TD]Y[/TD]
[TD]rngRatings = $D8:$G8[/TD]
[TD]$D$8:$G$8[/TD]
[TD]J8: =rangetest1(rngRatings)[/TD]
[/TR]
[TR]
[TD="align: center"]9[/TD]
[TD]Prod3[/TD]
[TD]6[/TD]
[TD]C[/TD]
[TD]5.0[/TD]
[TD]N[/TD]
[TD]rngRatings = $D9:$G9[/TD]
[TD]$D$9:$G$9[/TD]
[TD]J9: =rangetest1(rngRatings)[/TD]
[/TR]
[TR]
[TD="align: center"]10[/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD]$D$6:$G$6[/TD]
[TD]J10: =rangetest2("rngWeights")[/TD]
[/TR]
[TR]
[TD="align: center"]11[/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD]$D$6:$G$6[/TD]
[TD]J11: =rangetest2("rngWeights")[/TD]
[/TR]
[TR]
[TD="align: center"]12[/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD]$D$1:$G$1[/TD]
[TD]J12: =rangetest2("rngRatings")[/TD]
[/TR]
[TR]
[TD="align: center"]13[/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD]$D$1:$G$1[/TD]
[TD]J13: =rangetest2("rngRatings")[/TD]
[/TR]
</tbody>[/TABLE]
The range names and definitions are shown in Col H. rngWeights is absolute ($D$6:$E$6). rngRatings is half relative ($Dn:$En) so the row numbers adjust to match the row number of the calling cell.
The results of the UDF calls are in Col J and the expressions for those calls are in Col K.
In J6 & J7, RangeTest1 returns the correct address for rngWeights. Similarly, in J10 & J11, RangeTest2 also returns the correct address for rngWeights.
In J8 & J9, RangeTest1 returns the correct address for rngRatings adjusting the row numbers to match the row numbers of the calling cells. In J12 & J13, however, RangeTest2 returns the address for rngRatings as if it had been called from A1.
Is there a way that I can get RangeTest2 to return the correct relative address?
Now I know I can get the address of the calling cell and replace the row number, but I'd like a command that does that itself.
Thanks