在表单中保存类模块

假设我想在Excel VBA中制作自行车devise程序。 我有一个类对象( cBike ),它有一些默认设置。 现在,我想在将自行车存储到数据库之前创build一个可用于更改这些设置的窗体(如图像中的窗体)。 用于存储的方法(子)位于cBike

用于设计自行车的用户表单的示例。

我可以将对象保存为表单代码中的公共variables,如下所示:

 Public objBike As cBike Public Sub StoreBikeToDatabase() 'database storing code goes here End Sub 

虽然这会起作用,但我看到很多人反对使用公共(全球)variables。 我不太清楚为什么,除了如果你有太多的全局variables,你的代码将是一团糟。

或者我可以忘记对象,并使用不同的表单控件的值,而不是类模块cBike的属性。 但是,这似乎是一个笨拙的解决scheme。

我的问题是:上述哪个解决scheme最好,如果有的话? 如果没有,那我该怎么办呢?

更新:我强烈build议您阅读已接受的答案,然后再深入阅读。 这两个答案都有一些很好的想法,Dee的后面还增加了一些综合代码的例子,可以用于其他类似于我的问题。

表单实质上就是一个类,所以我build议在表单中创build一个私有属性来保存你的Bike对象。 然后,您可以通过一个属性设置例程将现有的Bike对象传递给窗体/类。

如果表单中的几个例程需要访问,则在表单级别声明Bike成员/属性没有问题。 全局/公共variables(在模块中声明)只能在对象需要被整个项目使用的情况下使用。

 '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的属性来有效地创build表单控件和类之间的dynamic链接,如下所示:

 Private WithEvents mTextBox1 As MSForms.TextBox Public Property Set TextBox1(ByVal obj As MSForms.TextBox) Set mTextBox1 = obj End Property 

这意味着,如果它改变,你不需要继续传递文本框的值。 您将需要一个参考设置为Microsoft Forms 2.0对象库

另一种方法是让Bike可以编辑。 Bike类将包含BikeEditor ,它是用于编辑自行车对象的用户forms。 这里是自行车types的例子,但其他的自行车属性可以用类似的方式完成。 对于BikeType使用包装BikeType的类。

自行车

 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