假设我想在Excel VBA中制作自行车设计师程序。我有一个类对象(cBike
),它有一些默认设置。现在我想在将自行车存放到数据库之前制作一个可用于更改这些设置的表单(如图中的那个)。用于存储的方法(子)位于cBike
。
我可以将对象保存为表单代码中的公共变量,如下所示:
Public objBike As cBike
Public Sub StoreBikeToDatabase()
'database storing code goes here
End Sub
虽然这样可行,但我看到很多人反对使用公共(全球)变量。我不太清楚为什么,除了如果你有太多的全局变量,你的代码将是一团糟。
或者我可以忘记该对象,并使用不同表单控件中的值,而不是类模块cBike
的属性。然而,这似乎是一个笨拙的解决方案。
我的问题是:如果有的话,上述哪种解决方案最好?如果没有,那么我该怎么做呢?
更新 我强烈建议您阅读接受的答案,然后再深入了解答案。这两个答案都有一些很棒的想法,而且他们的帖子附加了一些全面的代码示例,可以用于其他类似我的问题。
答案 0 :(得分:4)
表单本身就是一个类,所以我建议在表单中创建一个私有属性来保存你的Bike对象。然后,您可以通过Property Set例程将现有的Bike对象传递给表单/类。
如果需要由表单中的多个例程访问,则在表单级别声明Bike成员/属性没有问题。仅当整个项目需要使用该对象时,才应使用全局/公共变量(在模块中声明)。
'Private Member of this Form/Class
Private mBike As cBike
'Pass the existing object into this Form/Class
Public Property Let Bike(ByVal obj As cBike)
Set mBike = obj
End Property
您可以通过声明cBike的属性来有效地在表单控件和类之间创建动态链接:
Private WithEvents mTextBox1 As MSForms.TextBox
Public Property Set TextBox1(ByVal obj As MSForms.TextBox)
Set mTextBox1 = obj
End Property
这意味着如果文本框的值发生变化,则无需继续将其传递给类。您将需要一个Microsoft Forms 2.0对象库的引用集
答案 1 :(得分:3)
另一种方法是让Bike
可编辑。 Bike
类将包含BikeEditor
,它是用于编辑自行车对象的用户表单。这是自行车类型的示例,但其他自行车属性可以以类似的方式完成。对于BikeType
,使用了一个包裹TypeOfBikeEnum
的类。
自行车
Private m_editor As BikeEditor
Private m_bikeType As BikeType
Private Sub Class_Initialize()
Set m_editor = New BikeEditor
Set m_bikeType = New BikeType
End Sub
Public Property Get TypeOfBike() As BikeType
Set TypeOfBike = m_bikeType
End Property
Public Property Set TypeOfBike(ByVal vNewValue As BikeType)
Set m_bikeType = vNewValue
End Property
Public Sub Edit()
m_editor.Initialize Me
m_editor.Show
End Sub
BikeType
Public Enum TypeOfBikeEnum
[_First]
Unknown = 1
MountainBike = 2
StreetBike = 3
OfficeBike = 4
MoonBike = 5
[_Last]
End Enum
Private m_type As TypeOfBikeEnum
Private Sub Class_Initialize()
m_type = Unknown
End Sub
Public Property Get TypeValue() As TypeOfBikeEnum
TypeValue = m_type
End Property
Public Property Let TypeValue(ByVal vNewValue As TypeOfBikeEnum)
m_type = vNewValue
End Property
Public Function GetBikeTypeNames() As VBA.Collection
Dim enumVal As Long, name As String
Set GetBikeTypeNames = New VBA.Collection
For enumVal = TypeOfBikeEnum.[_First] To TypeOfBikeEnum.[_Last]
name = GetBikeTypeName(enumVal)
If name <> "" Then _
GetBikeTypeNames.Add name, CStr(enumVal)
Next enumVal
End Function
Public Function GetBikeTypeName(typeOfBikeValue As TypeOfBikeEnum) As String
Select Case typeOfBikeValue
Case TypeOfBikeEnum.Unknown
GetBikeTypeName = "Unknown"
Case TypeOfBikeEnum.MountainBike
GetBikeTypeName = "MountainBike"
Case TypeOfBikeEnum.StreetBike
GetBikeTypeName = "StreetBike"
Case TypeOfBikeEnum.OfficeBike
GetBikeTypeName = "OfficeBike"
Case TypeOfBikeEnum.MoonBike
GetBikeTypeName = "MoonBike"
Case Else
GetBikeTypeName = ""
End Select
End Function
BikeEditor
Private m_bikeToEdit As Bike
Public Sub Initialize(bikeToEdit As Bike)
Set m_bikeToEdit = bikeToEdit
Dim bikeTypeName
For Each bikeTypeName In m_bikeToEdit.TypeOfBike.GetBikeTypeNames
Me.bikeTypesComboBox.AddItem bikeTypeName
Next
Me.bikeTypesComboBox.ListIndex = m_bikeToEdit.TypeOfBike.TypeValue - 1
End Sub
Private Sub CancelCommandButton_Click()
Unload Me
End Sub
Private Sub SaveCommandButton_Click()
If Me.bikeTypesComboBox.ListIndex > -1 Then
m_bikeToEdit.TypeOfBike.TypeValue = Me.bikeTypesComboBox.ListIndex + 1
End If
Unload Me
End Sub
模块
Sub test()
Dim bk As Bike
Set bk = New Bike
Dim bt As BikeType
Set bt = New BikeType
bt.TypeValue = OfficeBike
Set bk.TypeOfBike = bt
bk.Edit
End Sub