Consider the Subroutine
below. I almost have what I'm looking for, but it's not quite right.
Knowns to take into account: The Declarations
statements for this Module
have setup each variable (Totaling 63 - I've culled the majority to simplify the sample below) as Public Variables
to be referenced at any time. I have done similar things with modifying Boolean
Variable Values, but this is failing for some reason with Ranges
and I think it has to do with the fact they are Objects
.
The For Loop
correctly pulls the relevant data and places it into the relevant placeholder
within each Variant Array, meaning - the placeholder
for StoreStateRng
for example, holds the correct data frm the Ranges in the sheet, but when trying to manipulate the actual Range Variable
stored inside the the placeholder, it fails to be referenced.
In theory - I would have expected this to physically set the Variable "StoreStateRng"
to the range specified. . . It does indeed set rngVars(i)
to the range specified, and gives it a Variant/Range
Type
when I inspect it on a Watch
, but when inspecting the actual Variable
at the same time, the Range Variable "StoreStateRng"
is empty!
'Excerpt of Declarations Statement
'example of 3 of the 63 variables listed in the arrays below
Public Const StoreStateRng_Col As Integer = 23
Public StoreStateRng As Range
Public StoreStateRng_Val As Variant
'the Variant Arrays defined at the beginning of the sub
Public rngVar As Variant
Public rngVars() As Variant
Public rngVarStr() As Variant
Public rngVarCols() As Variant
Public rngVarColStr() As Variant
Public rngVarVals() As Variant
Public rngVarValStr() As Variant
Sub Get_Ranges()
Set ws = ThisWorkbook.Sheets(wsNameMain)
rngVars() = Array(StoreStateRng, StoreCityRng, StoreDateRng, StoreNumRng)
rngVarStr() = Array("StoreStateRng", "StoreCityRng", "StoreDateRng", "StoreNumRng")
rngVarCols() = Array(StoreStateRng_Col, StoreCityRng_Col, StoreDateRng_Col, StoreNumRng_Col)
rngVarColStr() = Array("StoreStateRng_Col", "StoreCityRng_Col", "StoreDateRng_Col", "StoreNumRng_Col")
'Get Known Range that never has blanks in data:
Set StoreNumRng = ws.Range(Cells(2, StoreNumRng_Col), Cells(2, StoreNumRng_Col))
Dim i As Integer
i = 0
'Get Full Range of Known data set to establish beginning and end rows
rw = StoreNumRng.Row 'Pulled from the removed excerpt above
EndRw = StoreNumRng.End(xlDown).Row 'Pulled from the removed excerpt above
For i = LBound(rngVars) To UBound(rngVars)
If VarType(rngVars(i)) = vbObject Then
Set rngVar = ws.Range(Cells(rw, rngVarCols(i)), Cells(EndRw, rngVarCols(i)))
Set rngVars(i) = rngVar
Debug.Print "The Address for " & rngVarStr(i) & " = " & rngVars(i).Address
End If
Next i
Debug.Print StoreStateRng(1, 1).Value 'Fails because I'm assuming this variable is not set.
End Sub
I did try modifying the .Name
feature of the Variant's Placeholder
and it references the SheetName$COL$ROW
address properly (and even gives me a Named Range
to Goto
in the Sheet), and that Name.Name
value matches the Name of the Variable
- but the Debug.Print StoreStareRng(1,1).Value
fails because the Object itself still is empty.
I feel like I'm really close to figuring it out, but having a hard time wrapping my head around what I'm missing.
The goal is to have named Variables with which to reference throughout the module. For example - the data set I'm working with is 20+ columns wide, offset roughly 20 columns from another existing set of data, and often between 10-30 rows deep. What I'm wanting to avoid is fullRange(3,6).Value
for the 3rd row of the Sheet's Column 23. . . The Sheet's column 23 would be column 6 of the specified range). . . .
Instead, I would like to reference StoreStateRng(3,1).Value
for this same exact range and use a Constant of the actual sheet's column to modify this should the scope of range change down the line vs trying to touch every single routine which may reference StoreStateRng
. . .
I'm also hoping to avoid the cumbersome :
Sub Get_Ranges()
Set ws = ThisWorkbook.Sheets(wsNameMain)
ws.Activate
Set StoreStateRng = ws.Range(Cells(rw, StoreStateRng_Col),Cells(endRw, StoreStateRng_Col))
Set StoreCityRng = ws.Range(Cells(rw, StoreCityRng_Col),Cells(endRw, StoreCityRng_Col))
Set StoreDateRng = ws.Range(Cells(rw, StoreDateRng_Col),Cells(endRw, StoreDateRng_Col))
Set StoreNumRng = ws.Range(Cells(rw, StoreNumRng_Col),Cells(endRw, StoreNumRng_Col))
'Repeat until all 21 needed ranges are populated
End Sub
When you do this
Set rngVars(i) = rngVar
you're replacing the original Range variable with a different one, not assigning the original one to rngVar
Simpler version:
Sub Tester()
Dim rngA As Range, rngB As Range, arrRanges As Variant
arrRanges = Array(rngA, rngB)
Set arrRanges(0) = Range("A1:A5") 'This *replaces* rngA...
Debug.Print rngA.Address 'Error - rngA is still Nothing
End Sub
EDIT - your "cumbersome" example could be streamlined to be quite maintainable...
Sub SetRanges()
Set ws = ThisWorkbook.Worksheets(wsNameMain)
With ws.Range(ws.Cells(rw, "A"), ws.Cells(endRw, "A")).EntireRow
Set StoreStateRng = .Columns(StoreStateRng_Col)
Set StoreCityRng = .Columns(StoreCityRng_Col)
Set StoreDateRng = .Columns(StoreDateRng_Col)
Set StoreNumRng = .Columns(StoreNumRng_Col)
'...
'...
End With
End Sub