【问题标题】:Initializing VBA classes - looking for a more elegant solution初始化 VBA 类 - 寻找更优雅的解决方案
【发布时间】:2014-12-31 03:38:19
【问题描述】:

我目前正在做一个项目,我想初始化两个不同的类。我正在使用集合类来存储工作表数据。

首先我想遍历类的属性;可悲的是,这在 VBA 中似乎是不可能的(没有做出一些破解的解决方案)。

下面两个函数几乎是一样的,只有一个属性不同。我能否以某种方式在 VBA 中创建一个更可重用的函数?

Private Sub PasteCMSData()

    Dim PipelineCMSData As Collection
    Dim WonCMSData As Collection
    Dim I As Integer: I = 0

    Set PipelineCMSData = CollectPipeline()
    Set WonSheetName = CollectWon()

End Sub

私有函数 CollectPipeline() 作为集合

Private Function CollectPipeline() As Collection

    Const StartPos As Integer = 2

    Dim I As Integer: I = 0
    Dim PL As cPipeline
    Dim WorkbookData As Worksheet

    Set CollectPipeline = New Collection

    Set WorkbookData = Workbooks(WorkbookName).Worksheets(PLSheetName)

    For I = StartPos To WorkbookData.UsedRange.Rows.Count
        Set PL = New cPipeline
        With PL
            .ProjectType = WorkbookData.Cells(I, PLProjectType)
            .Segment = WorkbookData.Cells(I, PLSegment)
            .Customer = WorkbookData.Cells(I, PLCustomer)
            .Project = WorkbookData.Cells(I, PLProject)
            .Note = WorkbookData.Cells(I, PLNote)
            .CRM = WorkbookData.Cells(I, PLCRM)
            .Probability = WorkbookData.Cells(I, PLProbability)
            .Owner = WorkbookData.Cells(I, PLOwner)
            .SalesPhase = WorkbookData.Cells(I, PLSalesPhase)
            .NREPotential = WorkbookData.Cells(I, PLNREPotential)
            .RoyaltyPotential = WorkbookData.Cells(I, PLRoyaltyPotential)
            .Defcon = WorkbookData.Cells(I, PLDefcon)
            .ProjectStart = WorkbookData.Cells(I, PLProjectStart)
            .ProjectDuration = WorkbookData.Cells(I, PLProjectDuration)
        End With
        CollectPipeline.Add PL
    Next I

End Function

私有函数 CollectWon() 作为集合

Private Function CollectWon() As Collection

    Const StartPos As Integer = 2

    Dim I As Integer: I = 0
    Dim WO As cWon
    Dim WorkbookData As Worksheet

    Set CollectWon = New Collection

    Set WorkbookData = Workbooks(WorkbookName).Worksheets(WonSheetName)

    For I = StartPos To WorkbookData.UsedRange.Rows.Count
        Set WO = New cWon
        With WO
            .ActualCloseDate = WorkbookData.Cells(I, WOActualCloseDate)
            .ProjectType = WorkbookData.Cells(I, WOProjectType)
            .Segment = WorkbookData.Cells(I, WOSegment)
            .Customer = WorkbookData.Cells(I, WOCustomer)
            .Project = WorkbookData.Cells(I, WOProject)
            .Note = WorkbookData.Cells(I, WONote)
            .CRM = WorkbookData.Cells(I, WOCRM)
            .Probability = WorkbookData.Cells(I, WOProbability)
            .Owner = WorkbookData.Cells(I, WOOwner)
            .SalesPhase = WorkbookData.Cells(I, WOSalesPhase)
            .NREPotential = WorkbookData.Cells(I, WONREPotential)
            .RoyaltyPotential = WorkbookData.Cells(I, WORoyaltyPotential)
            .Defcon = WorkbookData.Cells(I, WODefcon)
            .ProjectStart = WorkbookData.Cells(I, WOProjectStart)
            .ProjectDuration = WorkbookData.Cells(I, WOProjectDuration)
        End With
        CollectWon.Add WO
    Next I

End Function

【问题讨论】:

  • 您可以在函数中添加一个参数来告诉它要创建哪种类型的对象,然后将对象变量声明为 Object 并仅在 If TypeOf obj is CWon 子句中分配附加属性。您还可以使用接口类并将变量声明为该类型。

标签: vba excel


【解决方案1】:

你可以;

  • 创建一个CommonAttributes 类来存储两个类共享的数据(.ProjectType.ProjectDuration)。 cWoncPipeline 都持有此类的内部实例。

  • 将初始化逻辑移动到类中:CollectionWon.Add PL.LoadFromRange(I)

  • 在类中枚举索引值;

    enum WOStuff WOActualCloseDate = 1 WONREPotential = 9 ... end enum

使LoadFromRange 解析和存储任何类特定数据(.ActualCloseDate),创建CommonAttributes 的实例并调用方法来加载公共数据:

myCommonAttributes.LoadFromRange(I, [paramArray of enum indexes])

【讨论】:

【解决方案2】:

这永远不会太优雅,但是可以对初始化变量列表进行一项改进。

在保存它们的工作表上,您可以将它们放在两列 {UniqueKey}{Value} 对中,然后将该范围转换为表格 Ctrl-NT

可以为表指定一些列名,例如键和值,以及一个唯一的名称。然后在 VBA 中,您可以通过以编程方式查找 Key 并找到其对应值来访问这些值。这样,表格可以重新排序,并且某些键可能会“丢失”,从而允许 VBA 代码输入预编程的默认值。

可以在 VBA 中以 ListObject 的形式访问该表。


在键值对的内部存储上。如果更适合您的实现,您可能需要考虑将其存储在 Dictionary 中。这样您就可以按键查找对象,而不是像Collection 那样仅按顺序查找。

在这里查看字典示例:

Does VBA have Dictionary Structure?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-25
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    • 1970-01-01
    相关资源
    最近更新 更多