Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 类对象VBA中单个属性的多个实例_Excel_Vba_Class - Fatal编程技术网

Excel 类对象VBA中单个属性的多个实例

Excel 类对象VBA中单个属性的多个实例,excel,vba,class,Excel,Vba,Class,假设我创建了一个名为Farm的类。它有3个特性: FarmName作为字符串 NumberOfStables尽可能长 HasHorse作为布尔值 我开始上课 Dim SmithFarm as Farm Set SmithFarm = New Farm SmithFarm.FarmName = "Smith Farm" SmithFarm.NumberOfStables = 3 是否有方法创建HasHorse属性的多个副本?假设我想知道农场的每个马厩里是否都有一匹马 Dim i As Lon

假设我创建了一个名为
Farm
的类。它有3个特性:

  • FarmName作为字符串
  • NumberOfStables尽可能长
  • HasHorse作为布尔值
我开始上课

Dim SmithFarm as Farm
Set SmithFarm = New Farm
SmithFarm.FarmName = "Smith Farm"
SmithFarm.NumberOfStables = 3
是否有方法创建HasHorse属性的多个副本?假设我想知道农场的每个马厩里是否都有一匹马

Dim i As Long
For i = 1 To SmithFarm.NumberOfStables
    SmithFarm.HasHorse(i) = True
Next
所以现在史密斯农场将拥有
马厩1
马厩2
马厩3
——所有这些马我都可以出租,并记录农场马厩里有多少匹马-

Dim currentHorses As Long
For i = 1 To SmithFarm.NumberOfStables
    If SmithFarm.HasHorse(i) Then currentHorses = currentHorses + 1
Next
或者我想看看第二个马厩里有没有马-

Dim targetStable As Long
targetStable = 2
If Not SmithFarm.HasHorse(targetStable) Then MsgBox "There's no horse here!"

如何做到这一点?我知道上面的代码不起作用,但是有办法解决这个问题吗?我需要一个农场级别的马厩吗?或者我需要一个存放在其他地方并以农场命名的马厩集合吗?

您可以将
HasHorse
设置为布尔值数组。但您将面临一个问题,即,您需要使数组的大小与
NumberOfStables
属性一致。因此,不要管理
NumberOfStables
属性,只管理返回数组大小的
getter
。 这就是对你的类的创造者和创造者的需求

' Code for the Farm Class
Option Explicit

Public FarmName As String
Private mStables() As Boolean

Public Property Get NumberOfStables() As Long
  NumberOfStables = UBound(mStables)
End Property

Public Property Let NumberOfStables(ByVal n As Long)
      ReDim Preserve mStables(1 To n)
End Property

Public Property Get HasHorse(ByVal i As Long) As Boolean
    HasHorse = mStables(i)
End Property

Public Property Let HasHorse(ByVal i As Long, ByVal b As Boolean)
    mStables(i) = b
End Property

Public Property Get currentHorses() As Long
    Dim i As Long
    For i = 1 To NumberOfStables
        If HasHorse(i) Then currentHorses = currentHorses + 1
    Next
End Property
下面是一些测试,在普通代码模块中:

Sub FarmTesting()
    Dim smithFarm As New Farm

    smithFarm.NumberOfStables = 3
    Debug.Print smithFarm.NumberOfStables
    smithFarm.HasHorse(2) = True

    Debug.Print smithFarm.HasHorse(1), smithFarm.HasHorse(2), smithFarm.HasHorse(3)

    smithFarm.NumberOfStables = 2
    Debug.Print smithFarm.HasHorse(1), smithFarm.HasHorse(2)

    Debug.Print smithFarm.currentHorses
End Sub

您可以将
HasHorse
设置为布尔值数组。但您将面临一个问题,即,您需要使数组的大小与
NumberOfStables
属性一致。因此,不要管理
NumberOfStables
属性,只管理返回数组大小的
getter
。 这就是对你的类的创造者和创造者的需求

' Code for the Farm Class
Option Explicit

Public FarmName As String
Private mStables() As Boolean

Public Property Get NumberOfStables() As Long
  NumberOfStables = UBound(mStables)
End Property

Public Property Let NumberOfStables(ByVal n As Long)
      ReDim Preserve mStables(1 To n)
End Property

Public Property Get HasHorse(ByVal i As Long) As Boolean
    HasHorse = mStables(i)
End Property

Public Property Let HasHorse(ByVal i As Long, ByVal b As Boolean)
    mStables(i) = b
End Property

Public Property Get currentHorses() As Long
    Dim i As Long
    For i = 1 To NumberOfStables
        If HasHorse(i) Then currentHorses = currentHorses + 1
    Next
End Property
下面是一些测试,在普通代码模块中:

Sub FarmTesting()
    Dim smithFarm As New Farm

    smithFarm.NumberOfStables = 3
    Debug.Print smithFarm.NumberOfStables
    smithFarm.HasHorse(2) = True

    Debug.Print smithFarm.HasHorse(1), smithFarm.HasHorse(2), smithFarm.HasHorse(3)

    smithFarm.NumberOfStables = 2
    Debug.Print smithFarm.HasHorse(1), smithFarm.HasHorse(2)

    Debug.Print smithFarm.currentHorses
End Sub

A.S.H.的答案很有效,是
属性Let
属性Get
的一个很好的例子

OOP“纯粹主义者”可能会说您需要两个类:
Farm
Stables
。这实际上取决于你的结构会变得多么复杂。下面是一个非常基本的两类结构,您可以从中开始:

Farm
类(称为clsFarm):

Stable
类(称为clsStable):

您可以在模块中填充类:

Dim oFarm As clsFarm
Dim oStable As clsStable

Set oFarm = New clsFarm
With oFarm
    .FarmName = "Smith Farm"
    Set .Stables = New Collection
End With

Set oStable = New clsStable
With oStable
    .StableRef = "1"
    .HasHorse = True
End With
oFarm.Stables.Add oStable, oStable.StableRef

Set oStable = New clsStable
With oStable
    .StableRef = "2"
    .HasHorse = False
End With
oFarm.Stables.Add oStable, oStable.StableRef

Set oStable = New clsStable
With oStable
    .StableRef = "3"
    .HasHorse = True
End With
oFarm.Stables.Add oStable, oStable.StableRef
然后根据需要操作数据,例如:

MsgBox oFarm.HorseCount

If Not oFarm.Stable("2").HasHorse Then MsgBox "Bolted!"

A.S.H.的答案很有效,是
属性Let
属性Get
的一个很好的例子

OOP“纯粹主义者”可能会说您需要两个类:
Farm
Stables
。这实际上取决于你的结构会变得多么复杂。下面是一个非常基本的两类结构,您可以从中开始:

Farm
类(称为clsFarm):

Stable
类(称为clsStable):

您可以在模块中填充类:

Dim oFarm As clsFarm
Dim oStable As clsStable

Set oFarm = New clsFarm
With oFarm
    .FarmName = "Smith Farm"
    Set .Stables = New Collection
End With

Set oStable = New clsStable
With oStable
    .StableRef = "1"
    .HasHorse = True
End With
oFarm.Stables.Add oStable, oStable.StableRef

Set oStable = New clsStable
With oStable
    .StableRef = "2"
    .HasHorse = False
End With
oFarm.Stables.Add oStable, oStable.StableRef

Set oStable = New clsStable
With oStable
    .StableRef = "3"
    .HasHorse = True
End With
oFarm.Stables.Add oStable, oStable.StableRef
然后根据需要操作数据,例如:

MsgBox oFarm.HorseCount

If Not oFarm.Stable("2").HasHorse Then MsgBox "Bolted!"

Array
方法将迫使您处理“零状态”,而
Dictionary
方法可以通过将stable的成员和方法包装到类中来更有效地处理stable

如下


农场
类别代码

Option Explicit

Public FarmName As String
Private Stables As Scripting.Dictionary

Public Property Get NumberOfStables() As Long
    NumberOfStables = Stables.Count
End Property

Public Sub AddStables(ByVal stablesNr As Long)
    Dim i As Long
    For i = 1 To stablesNr
        Stables.Add Stables.Count + 1, 0
    Next
End Sub

Public Sub AddStable()
    Me.AddStables 1
End Sub

Public Sub RemoveStable()
    If Stables.Count > 0 Then Stables.Remove Stables.Count
End Sub

Public Sub GetHorsesFromStable(ByVal stableNr As Long, ByVal horsesToRemove As Long)
    If Stables.Exists(stableNr) Then If horsesToRemove > 0 Then Stables(stableNr) = IIf(Stables(stableNr) - horsesToRemove >= 0, Stables(stableNr) - horsesToRemove, 0)
End Sub

Public Sub GetHorseFromStable(ByVal stableNr As Long)
    If Stables.Exists(stableNr) Then Me.GetHorsesFromStable stableNr, 1
End Sub

Public Sub AddHorsesToStable(ByVal stableNr As Long, ByVal horsesToAdd As Long)
    If Stables.Exists(stableNr) Then If horsesToAdd > 0 Then Stables(stableNr) = Stables(stableNr) + horsesToAdd
End Sub

Public Sub AddHorseToStable(ByVal stableNr As Long)
    If Stables.Exists(stableNr) Then Me.AddHorsesToStable stableNr, 1
End Sub

Public Property Get HasHorse(ByVal stableNr As Long) As Boolean
    If Stables.Exists(stableNr) Then HasHorse = Stables(stableNr) > 0
End Property

Public Property Get stableHorses(ByVal stableNr As Long) As Long
    If Stables.Exists(stableNr) Then stableHorses = Stables(stableNr)
End Property

Public Property Get currentHorses() As Long
    Dim horses As Variant
    For Each horses In Stables.Items
        currentHorses = currentHorses + horses
    Next
End Property


Private Sub Class_Initialize()
    Set Stables = New Scripting.Dictionary
End Sub

你的
农场
班级

Option Explicit

Sub FarmTest()
    Dim smithFarm As New Farm

    With smithFarm
        .AddStables 3 '<--| add stables
        Debug.Print .NumberOfStables '<--| returns three
        Debug.Print .currentHorses '<--| returns zero
        Debug.Print .HasHorse(1) '<--| returns False
        Debug.Print .HasHorse(2) '<--| returns False
        Debug.Print .HasHorse(3) '<--| returns False

        Debug.Print ""

        .AddHorsesToStable 1, 2 '<--| add stable 1 two horses
        Debug.Print .currentHorses '<--| returns two
        Debug.Print .HasHorse(1) '<--| returns True
        Debug.Print .stableHorses(1) '<--| returns two
        Debug.Print .HasHorse(2) '<--| returns False
        Debug.Print .stableHorses(2) '<--| returns zero

        Debug.Print ""

        .AddHorsesToStable 2, 1 '<--| add stable 2 one horse
        Debug.Print .currentHorses '<--| returns three
        Debug.Print .HasHorse(2) '<--| returns True
        Debug.Print .stableHorses(2) '<--| returns one
        Debug.Print .HasHorse(3) '<--| returns False
        Debug.Print .stableHorses(3) '<--| returns zero

        Debug.Print ""

        .AddHorsesToStable 3, 2 '<--| add stable 3 two horses
        Debug.Print .currentHorses '<--| returns five
        Debug.Print .HasHorse(3) '<--| returns True
        Debug.Print .stableHorses(3) '<--| returns three

    End With

End Sub
选项显式
次级测试()
新农场
史密斯农场

.AddStables 3'
数组
方法将强制您处理“零状态”,而
字典
方法可以通过在类中包装其成员和方法来更有效地处理stables

如下


农场
类别代码

Option Explicit

Public FarmName As String
Private Stables As Scripting.Dictionary

Public Property Get NumberOfStables() As Long
    NumberOfStables = Stables.Count
End Property

Public Sub AddStables(ByVal stablesNr As Long)
    Dim i As Long
    For i = 1 To stablesNr
        Stables.Add Stables.Count + 1, 0
    Next
End Sub

Public Sub AddStable()
    Me.AddStables 1
End Sub

Public Sub RemoveStable()
    If Stables.Count > 0 Then Stables.Remove Stables.Count
End Sub

Public Sub GetHorsesFromStable(ByVal stableNr As Long, ByVal horsesToRemove As Long)
    If Stables.Exists(stableNr) Then If horsesToRemove > 0 Then Stables(stableNr) = IIf(Stables(stableNr) - horsesToRemove >= 0, Stables(stableNr) - horsesToRemove, 0)
End Sub

Public Sub GetHorseFromStable(ByVal stableNr As Long)
    If Stables.Exists(stableNr) Then Me.GetHorsesFromStable stableNr, 1
End Sub

Public Sub AddHorsesToStable(ByVal stableNr As Long, ByVal horsesToAdd As Long)
    If Stables.Exists(stableNr) Then If horsesToAdd > 0 Then Stables(stableNr) = Stables(stableNr) + horsesToAdd
End Sub

Public Sub AddHorseToStable(ByVal stableNr As Long)
    If Stables.Exists(stableNr) Then Me.AddHorsesToStable stableNr, 1
End Sub

Public Property Get HasHorse(ByVal stableNr As Long) As Boolean
    If Stables.Exists(stableNr) Then HasHorse = Stables(stableNr) > 0
End Property

Public Property Get stableHorses(ByVal stableNr As Long) As Long
    If Stables.Exists(stableNr) Then stableHorses = Stables(stableNr)
End Property

Public Property Get currentHorses() As Long
    Dim horses As Variant
    For Each horses In Stables.Items
        currentHorses = currentHorses + horses
    Next
End Property


Private Sub Class_Initialize()
    Set Stables = New Scripting.Dictionary
End Sub

你的
农场
班级

Option Explicit

Sub FarmTest()
    Dim smithFarm As New Farm

    With smithFarm
        .AddStables 3 '<--| add stables
        Debug.Print .NumberOfStables '<--| returns three
        Debug.Print .currentHorses '<--| returns zero
        Debug.Print .HasHorse(1) '<--| returns False
        Debug.Print .HasHorse(2) '<--| returns False
        Debug.Print .HasHorse(3) '<--| returns False

        Debug.Print ""

        .AddHorsesToStable 1, 2 '<--| add stable 1 two horses
        Debug.Print .currentHorses '<--| returns two
        Debug.Print .HasHorse(1) '<--| returns True
        Debug.Print .stableHorses(1) '<--| returns two
        Debug.Print .HasHorse(2) '<--| returns False
        Debug.Print .stableHorses(2) '<--| returns zero

        Debug.Print ""

        .AddHorsesToStable 2, 1 '<--| add stable 2 one horse
        Debug.Print .currentHorses '<--| returns three
        Debug.Print .HasHorse(2) '<--| returns True
        Debug.Print .stableHorses(2) '<--| returns one
        Debug.Print .HasHorse(3) '<--| returns False
        Debug.Print .stableHorses(3) '<--| returns zero

        Debug.Print ""

        .AddHorsesToStable 3, 2 '<--| add stable 3 two horses
        Debug.Print .currentHorses '<--| returns five
        Debug.Print .HasHorse(3) '<--| returns True
        Debug.Print .stableHorses(3) '<--| returns three

    End With

End Sub
选项显式
次级测试()
新农场
史密斯农场

.AddStables 3'这可以通过使用两个类来实现:cFarm和cHorse,通过使cHorse成为cFarm的属性来实现

Stable存储在字典中,这也是cFarm类的一个属性由于此词典,您必须添加Microsoft脚本运行时参考库

使用类来执行以下操作的示例:
  • 创建一个农场
  • 增加10个马厩
  • 用马填充马厩(所有马厩最初都有一匹马)
  • 将马从马厩中带出(您可以编写另一个函数将马放回马厩)
  • 打印(到即时窗口)马厩列表以及是否有马
在这个例子中,马被命名

该潜艇将进入标准模块

Sub CreateFarm()

    Dim clsFarm As New cFarm

    With clsFarm
        .FarmName = "Smith Farm"
        .AddStables 10

        .TakeHorseOutOfStable 2
        .TakeHorseOutOfStable 5
        .TakeHorseOutOfStable 6
        .TakeHorseOutOfStable 9

        .PrintStableHorseState
    End With

End Sub
CreateFarm子对象的输出

cFarm类 chose类(定义在此类下方)是此(cFarm)类的一个属性。stables存储在字典中,字典也是此类的一个属性。这些属性由类初始值设定项设置

Option Explicit

Private pFarmName As String
Private pdictStables As Scripting.Dictionary ' requires Microsoft Scripting Runtime library
Private pHorse As cHorse
Private pNumStables As Integer



Public Property Get FarmName() As String
    FarmName = pFarmName
End Property

Public Property Let FarmName(ByVal sFarmName As String)
    pFarmName = sFarmName
End Property

Public Property Get dictStables() As Scripting.Dictionary
    Set dictStables = pdictStables
End Property

Public Property Set dictStables(ByVal dStable As Scripting.Dictionary)
    Set pdictStables = dStable
End Property

Public Property Get Horse() As cHorse
    Set Horse = pHorse
End Property

Public Property Set Horse(ByVal clsHorse As cHorse)
    Set pHorse = clsHorse
End Property

Public Property Get NumStables() As Integer
    NumStables = pNumStables
End Property

Public Property Let NumStables(ByVal iNumStables As Integer)
    pNumStables = iNumStables
End Property

Sub AddStables(intNumStables As Integer)

    ' all stables are initialized to have a horse

    Dim i As Integer

    With Me
        .NumStables = intNumStables
        For i = 1 To .NumStables

            Set .Horse = New cHorse

            With .Horse
                .HorseName = .HorseNames(i)
                .HasHorse = True
            End With
            .dictStables.Add i, .Horse
        Next i
    End With

End Sub

Sub TakeHorseOutOfStable(intStableNum As Integer)

    With Me
        Set .Horse = .dictStables(intStableNum)
        .Horse.HasHorse = False
        Set .dictStables(intStableNum) = .Horse
    End With

End Sub

Sub PrintStableHorseState()

    Dim vStable As Variant

    With Me.dictStables
        For Each vStable In .Keys
            Debug.Print "Stable number: " & vStable & _
                    "   Horse Name: " & .Item(vStable).HorseName & _
                    "           HasHorse: " & .Item(vStable).HasHorse
        Next vStable
    End With

End Sub

Private Sub Class_Initialize()

    Dim clsHorse As cHorse
    Dim dict As Scripting.Dictionary

    Set clsHorse = New cHorse
    Set Me.Horse = clsHorse

    Set dict = New Scripting.Dictionary
    Set Me.dictStables = dict

End Sub
和弦类
这可以通过使用两个类来实现:cFarm和cHorse,将cHorse设置为cFarm的属性

Stable存储在字典中,这也是cFarm类的一个属性由于此词典,您必须添加Microsoft脚本运行时参考库

使用类来执行以下操作的示例:
  • 创建一个农场
  • 增加10个马厩
  • 用马填充马厩(所有马厩最初都有一匹马)
  • 将马从马厩中带出(您可以编写另一个函数将马放回马厩)
  • 打印(到即时窗口)马厩列表以及是否有马
在这个例子中,马被命名

该潜艇将进入标准模块

Sub CreateFarm()

    Dim clsFarm As New cFarm

    With clsFarm
        .FarmName = "Smith Farm"
        .AddStables 10

        .TakeHorseOutOfStable 2
        .TakeHorseOutOfStable 5
        .TakeHorseOutOfStable 6
        .TakeHorseOutOfStable 9

        .PrintStableHorseState
    End With

End Sub
CreateFarm子对象的输出

cFarm类 chose类(定义在此类下方)是此(cFarm)类的一个属性。马厩储存在字典中,w