excelvba

How to use a variable to globally define a cell's location?


I am writing series of small macros to manipulate data on a series of identical sheets.

For example, on every sheet E3 is the sheet's subject.

I am looking for a way to globally define E3 as a variable called SheetSubject for any macro I write.

I am envisioning something like this.

SheetSubject = Range("E3")

I'd then be able to use SheetSubject in my macros instead of referring to Range("E3") every time.

This type of macro wide definition means I only have change one bit of code...say E3 to E67...in one place instead of lots of macros should the data in E3 move to E67,

Global variables only define names for macro wide use...not a location.

I've thought about each macro calling a higher macro to define globally defined variables, but this seems clumsy.


Solution

  • As a Function for example (in a regular module):

    Function SheetSubject(ws As Worksheet) As Range
        Set SheetSubject = ws.Range("E3")
    End Function
    

    Usage example:

    Dim ws As Worksheet
    For Each ws in ThisWorkbook.Worksheets
        If ws.Name like "Data*" Then Debug.Print ws.Name, SheetSubject(ws)
    Next ws
    

    However, if you have a bunch of sheets which all share the same common layout and purpose, it's usually tidier to write a Class module to encapsulate the common properties and behaviors. For example you could write a class clsDataSheet:

    Const RNG_SUBJ As String = "E3"
    Const RNG_TITLE As String = "E4"
    
    
    Private wsDS As Worksheet
    
    Sub Init(ws As Worksheet)
        Set wsDS = ws   'assign the worksheet which this object will wrap
    End Sub
    
    Property Get Subject() As String      'read the Subject
        Subject = wsDS.Range(RNG_SUBJ).Value
    End Property
    
    Property Get Title() As String
        Title = wsDS.Range(RNG_TITLE).Value
    End Property
    Property Let Title(v As String)   'add a Let if you need to write to the property
        'you could add some checks on `v` here...
        wsDS.Range(RNG_TITLE).Value = v
    End Property
    
    '-------------------------------------
    'other properties and/or methods here
    '-------------------------------------
    

    Then you can do something like this:

    Dim oDS as clsDataSheet
    
    Set oDS = New clsDataSheet
    oDS.Init ThisWorkbook.Worksheets("Sheet1")
    
    Debug.Print oDS.Subject
    Debug.Print oDS.Title 
    
    oDS.Title = "New Title here"