excel 如何通过集合、“late”字典或其他方式关联多个对象示例?

aiazj4mn  于 2023-02-17  发布在  其他
关注(0)|答案(1)|浏览(123)

我用一个类创建了一个接口。
我有一个子获取多个工作表,相关的命名范围和行金额,我用这个循环通过数据,我需要分组在一起。
一旦数据被逐行读取,它就示例化对象(类通过从模块接收范围的公共init方法将数据从单元格中取出),我将它们添加到模块中的一个没有键的简单集合中。
在某些情况下,我需要将对象示例彼此关联起来,因为我需要在稍后阶段以稍微不同的方式处理它们(后面的输出项中会有更多列)。
我在数据中添加了一个唯一标识符,该标识符仅由相关示例共享,但我不知道如何从此处开始创建这样的关联。
这是读:

'Create solution is placed between Class creation and sub to define the target sheets & ranges
Option Explicit
Sub ReadData(Solutions As Collection)

Set Solutions = New Collection

Dim Solution As Variant
Dim ws As Worksheet
Dim rng As Range
Dim rowamount As Long

'define length of range
rowamount = Worksheets("source").Range("Named_ranges").Rows.Count

Dim myrow As Integer
Dim suspectWorksheet As String
Dim TargetWorksheet As Worksheet
Dim TargetWorkRange As String
Dim TargetRangeCount As Integer
Dim x As Integer

For myrow = 1 To rowamount

    'Identify the visible sheets from the source matrix & init worksheet
    suspectWorksheet = Worksheets("source").Range("Named_ranges").Cells(myrow, 1)
    Set TargetWorksheet = Worksheets(suspectWorksheet)
    If TargetWorksheet.Visible = True Then
    
        ' Init the range variable and get the max amount of lines to scan
        TargetWorkRange = Worksheets("source").Range("Named_ranges").Cells(myrow, 2)
        TargetRangeCount = Worksheets("source").Range("Named_ranges").Cells(myrow, 3)

        ' Start the lineloop to inject the data into the class
        For x = 1 To TargetRangeCount
            Debug.Print "Loop " & x
            'Is there an active line in the target range?
            If Worksheets(suspectWorksheet).Range(TargetWorkRange).Cells(x + 1, 1) > 0 Then
                Set rng = Worksheets(suspectWorksheet).Range(TargetWorkRange).Resize(1, 60).Offset(x, 0)
                Set Solution = solutionClassFactory(rng)
                Solutions.Add Solution
                 
                'Solution.PrintOut
            End If
        Next x
    End If
Next myrow

Set TargetWorksheet = Nothing
End Sub

' Checks the type of solution and returns into a class
Function solutionClassFactory(rng As Range) As Variant

Dim solutionType As String

solutionType = rng.Cells(1, 51)

Dim Solution As Variant
Select Case solutionType
    Case "something":
        Set Solution = New something
End Select

Solution.Init rng

' solution is returned to be added to the main collection
Set solutionClassFactory = Solution

End Function

这是写作部分:

Sub Create()
Dim Solution As Variant
Dim Solutions As Collection
Dim TargetWorksheet As String
Dim i As Integer
'Define to which sheet it needs to be written
TargetWorksheet = "sheet"

ReadData Solutions
i = 5

For Each Solution In Solutions

    Worksheets(TargetWorksheet).Cells(i, 1) = Solution.amount
    'more

    i = i +1

Next Solution

End Sub

出于性能原因,我不想恢复到循环中的循环。
分类代码

' class derived from Solution interface
Option Explicit

 ' Implements Solution interfacs
Implements Solution

Private amount_ As Integer
Private amountRef_ As String

Private Sub Class_Initialize()

End Sub

Public Sub Init(rng As Range)
    amount_ = rng.Cells(1, 1)
    amountRef_ = "'" & rng.Parent.Name & "'!" & rng.Columns.Item(1).address
End Sub

Public Sub PrintOut()
Debug.Print amount_, TypeName(Me), linekey_ & vbNewLine;
Debug.Print amountRef_, TypeName(Me), linekeyRef_ & vbNewLine;
End Sub

Private Sub Class_Terminate()
    ' Debug.Print "WAN class instance deleted"
End Sub

Public Property Get amount() As Integer
    amount = amount_
End Property

Public Property Let amount(ByVal Value As Integer)
    amount = amount_
End Property

Public Property Get linekeyRef() As String
    linekeyRef = linekeyRef_
End Property

Public Property Let linekeyRef(ByVal Value As String)
    linekeyRef = linekeyRef_
End Property

' Implement required interface properties
Private Property Get Solution_address() As String
    Solution_address = address
End Property
mdfafbf1

mdfafbf11#

使用一个字典对象,以你的唯一ID作为键,以对象集合作为值。例如,一些顶级代码来创建对象和调用方法。

Option Explicit

Sub Process()

   Dim rep As reporter
   Set rep = New reporter
   Set rep.SourceRng = Sheets("source").Range("Named_ranges")
   rep.readata
   MsgBox rep.linecount & " lines read"
   
   Set rep.DestRng = Sheets("Sheet5").Range("A1")
   rep.writedata
  
   Set rep.DestRng = Sheets("Sheet6").Range("A1")
   rep.writedata_bytyp
   MsgBox "Done"
   
End Sub

Solution

Public amount As Long
Public ref As String
Public typ As String

用于保存字典和集合的Reporter

Private Solutions As New Collection
Private Things As Object
Public SourceRng As Range
Public DestRng As Range
Public linecount As Long
Const COL_TYPE = "AY" '51

Sub readata()

   Dim i As Long, obj As Solution, v
   Dim ws As Worksheet, sRng As String, rng As Range
   Dim r As Long, rowcount As Long
   Set Things = CreateObject("Scripting.Dictionary")
   
   For i = 1 To SourceRng.Rows.Count
        Set ws = Sheets(SourceRng.Cells(i, 1).Value2)
        sRng = SourceRng.Cells(i, 2)
        rowcount = SourceRng.Cells(i, 3)
        
        If ws.Visible = True Then
            Set rng = ws.Range(sRng)
            For r = 2 To rowcount + 1
            
                v = rng.Cells(r, 1).Value2
                If v > 0 Then
                      
                    Set obj = New Solution
                    obj.amount = v
                    obj.typ = Trim(rng.Cells(r, COL_TYPE))
                    obj.ref = ws.Name & "!" & rng.Cells(r, 1).Address
                    Solutions.Add obj
                    
                    If Not Things.exists(obj.typ) Then
                        Things.Add obj.typ, New Collection
                    End If
                    Things(obj.typ).Add obj
                    linecount = linecount + 1
                End If
            Next
        End If
    Next
End Sub

Sub writedata()
    Dim i As Long, obj
    With DestRng
        For Each obj In Solutions
           i = i + 1
           .Cells(i, 1) = obj.amount
           .Cells(i, 2) = obj.typ
           .Cells(i, 3) = obj.ref
        Next
    End With
End Sub

Sub writedata_bytyp()
    Dim i As Long, key, obj
    With DestRng
        For Each key In Things.keys
            i = i + 1
            .Cells(i, 1) = key
            For Each obj In Things(key)
                i = i + 1
                .Cells(i, 2) = obj.amount
                .Cells(i, 3) = obj.typ
                .Cells(i, 4) = obj.ref
            Next
        Next
    End With
End Sub

相关问题