Module level variables

It is common to create a big wall of declaration in a module such as this:

Private strCompanyName As String
Private dteOrderDate As Date
Private lngOrderID As Long
Private objEmail As Object
Private objOutlook As Object

While the code will compile and work fine, the discoverability and naming of the module level variables does become difficult and unwieldy. To help cut down on this ambiguity, it is recommended to create a private user-defined type instead.

Private Type TData
  CompanyName As String
  OrderDate As Date
  OrderID As Long
  Email As Object
  Outlook As Object
End Type
Private This As TData

Note the This variable which holds the UDT. That enables us to then refer to variables in the module in very similar manner to how we can use Me — for example:

Set This.Outlook = GetOutlook
Set This.Email = This.Outlook.CreateItem(olMailItem)

Or,

Public Property Get OrderID() As Long
  OrderID = This.OrderID
End Property

Public Property Let OrderID(NewValue As Long)
  This.OrderID = NewValue
End Property

By consistently using This UDT to hold all module-level variables, the naming and references is now much clearer and easier to understand. You do not have to wonder whether strCompanyname is a module-level variable or a private variable scoped to a specific procedure and because it’s in a UDT, shadowing cannot happen since you can simply disambiguate the reference.