我在VBA中创建了一个类,我想要一些与之关联的预设值。我是新手,我想知道在类对象中构造我的VBA代码的最好(/一个好)方法是什么,这样我可以在输入时轻松访问这些默认值。答案最好:
Sub
并不理想值得注意的是,我对这些硬编码值的主要用途是将默认值设置为我的类的变量(通过在initialize
事件中循环),但我可能还想在其他部分访问它们代码
我尝试了什么:
声明Enum
以保存我的硬编码值
'Declarations
Private Enum startingVals
Top = 10
Column_Count = 4
Left = 15
...
End Enum
Private topVal As Long 'variables which I assign default values to
Private colCnt As Long
Private leftVal As Long
Private Sub Class_Initialize()
topVal = startingVals.Top
colCnt = startingVals.Column_Count
'etc.
End Sub
这有两个限制;
Long
个
Const
s加载来解决这个问题,但是你必须记住每个常量的名称,加上它看起来很混乱.Top
和.Column_Count
的智能感知,但仍然需要完整输入startingVals
理想情况下,我可以这样做
Private Sub Class_Initialize()
With startingVals 'or Dim v As startingVals, With v
topVal = .Top
colCnt = .Column_Count
'etc.
End With
End Sub
但我不能
另一种方法是使用函数来保存值,这样就可以将不同的类型声明为long。
'Declarations
Private Enum startingVals
Top = 1
Column_Count = 2
Left = 3
...
End Enum
Private topVal As Long 'variables which I assign default values to
Private colCnt As Long
Private leftVal As Long
Private Sub Class_Initialize()
topVal = getval(Top)
colCnt = getval(Column_Count)
'etc.
End Sub
然后要访问硬编码数据,你有一个带枚举输入的函数(允许智能感知)
Private Function getval(dataType As startVals) As String
Const savedData As String = "1,2,1.17171717,hey,me,you" 'save the return values for the index specified by dataType
getval = Split(savedData, ",")(dataType) 'use datatype as a direct index of the array
End Function
或其他保存值的方法
Private Function getval(dataType As startVals) As String
Const colV As Long = 10 'index 1
Const topV As String = "This is the top" 'index 2
'...
If dataType = ColumnCount Then getval = colV 'use dataType to check what to return
If dataType = Top Then getval = colV 'could use a select case too
'etc
End Function
在类对象中保存硬编码值的最佳方法是什么,其中最佳定义为
Long
)function
或enum
名称)即可访问
With
块或函数等效就好了,因为只需要指定枚举/数据集合名称的一个实例答案 0 :(得分:2)
您可以使用常量在一个位置定义默认值。
然后,您可以使用Ctrl + Space + Default ...
轻松访问它们Const Default_Top = 10
Const Default_Text = "abcd"
Private m_topVal As Long
Private m_text As String
Private Sub Class_Initialize()
m_topVal = Default_Top
m_text = Default_Text
End Sub
Public Property Get TopVal() As Long
TopVal = m_topVal
End Property
答案 1 :(得分:2)
...以防止我的班级变得太杂乱
我将该类与其初始化过程分开,添加另一个类可以调用它Initializer
。初始化程序将知道如何初始化我的对象,将包含默认值,并将使用此默认值填充我的对象。但是在初始化程序中,你必须编写赋值,没有魔法智能感知,只需简单地写m_
并从列表中选择。 HTH
Class Foo
Option Explicit
'variables which I assign default values to
Private m_topVal As Long
Private m_colCnt As Long
'Private m_leftVal As Long
Private Sub Class_Initialize()
Dim initializer As FooInitializer
Set initializer = New FooInitializer
initializer.Initialize Me
End Sub
Public Property Get TopVal() As Long
TopVal = m_topVal
End Property
Public Property Let TopVal(ByVal vNewValue As Long)
m_topVal = vNewValue
End Property
Public Property Get ColCnt() As Long
ColCnt = m_colCnt
End Property
Public Property Let ColCnt(ByVal vNewValue As Long)
m_colCnt = vNewValue
End Property
' Add Get/Let(Set) for other member variables as well
Class FooInitializer
Option Explicit
' Default startingVals values
Private m_topValDefault As Integer
Private m_columnCountDefault As Integer
'etc.
Public Sub Initialize(ByRef fooInstance As Foo)
fooInstance.TopVal = m_topValDefault
fooInstance.ColCnt = m_columnCountDefault
'etc.
End Sub
Private Sub Class_Initialize()
m_topValDefault = 10
m_columnCountDefault = 4
'etc.
End Sub
标准模块
Option Explicit
Sub test()
Dim f As Foo
Set f = New Foo
' f is now initizlized via initializer with default values
Debug.Print f.TopVal
Debug.Print f.ColCnt
End Sub
答案 2 :(得分:0)
我不能声称对此解决方案拥有所有权,但当我在Code Review上遇到它时,我的天才足以将其合并到我的很多代码中。
在其他一些面向对象语言中使用时,使用this
构造访问类内部实例变量非常熟悉。使用此处的示例将该概念扩展到VBA。
我创建了一个名为CustomClass
的类模块,并在其中创建了一个私有自定义类型,仅供该类使用。
Option Explicit
Private Type CustomType
Top As Long
Name As String
Temperature As Double
anotherCustomObject As CustomClass
End Type
Private this As CustomType
以这种方式工作,您可以创建任意类型组合(包括对象)的任意数量的内部变量。现在,访问和初始化每个值都与使用this
结构化变量一样简单。 Class_Initialize
子显示如何:
Private Sub Class_Initialize()
this.Top = 150
this.Name = "Wayne"
this.Temperature = 98.6
Set this.anotherCustomObject = New CustomClass
End Sub
根据您心中的内容设置并初始化您的所有值。
此外,如果您愿意,可以使用属性访问器建立每个属性访问器。其中一些可以是只读的:
'--- Read Only Properties
Public Property Get Name() As String
Name = this.Name
End Property
Public Property Get Temperature() As Double
Temperature = this.Temperature
End Property
Public Property Get ContainedObject() As CustomClass
Set ContainedObject = this.anotherCustomObject
End Property
你可以创建一些读/写:
'--- Read/Write Properties
Public Property Let Top(ByVal newValue As Long)
this.Top = newValue
End Property
Public Property Get Top() As Long
Top = this.Top
End Property
另外,您仍然可以使用Me
关键字在课堂上轻松使用这些属性:
'--- Internal Private Methods
Private Sub TestThisClass()
Debug.Print "current temperature is " & Me.Temperature
Debug.Print "the Top value is " & Me.Top
End Sub
当然,当你在不同的模块中声明CustomClass
的对象时,这一切都有效。
希望这有助于帮助规范您的代码。
(为方便起见,全班同学:)
Option Explicit
Private Type CustomType
Top As Long
Name As String
Temperature As Double
anotherCustomObject As CustomClass
End Type
Private this As CustomType
Private Sub Class_Initialize()
this.Top = 150
this.Name = "Wayne"
this.Temperature = 98.6
Set this.anotherCustomObject = New CustomClass
End Sub
'--- Read Only Properties
Public Property Get Name() As String
Name = this.Name
End Property
Public Property Get Temperature() As Double
Temperature = this.Temperature
End Property
Public Property Get ContainedObject() As CustomClass
Set ContainedObject = this.anotherCustomObject
End Property
'--- Read/Write Properties
Public Property Let Top(ByVal newValue As Long)
this.Top = newValue
End Property
Public Property Get Top() As Long
Top = this.Top
End Property
'--- Internal Private Methods
Private Sub TestThisClass()
Debug.Print "current temperature is " & Me.Temperature
Debug.Print "the Top value is " & Me.Top
End Sub