I've been using class modules for almost a year, and I'm just now comfortable with them. Now I'm trying to incorporate factory methods into data extraction from workbook tables. I found some great guides on the topic here, here, and here, but I'm unsure where to incorporate a collection of the class.
Up until now, I've setup my class modules with self-contained collections in this format:
Class module OrigClass
Option Explicit
'Col position references for input table, only includes cols with relevant data
Private Enum icrColRef
    icrName = 2
    icrCost = 4
End Enum
'UDT mirrors class properties
Private Type TTestClass
    Name                                As String
    Cost                                As Long
End Type
Const WS_NAME                           As String = "Sheet1"
Const NR_TBL                            As String = "Table1"
Private msTestClass                     As Collection
Private TestClass                       As TTestClass
Private Sub Class_Initialize()
    Set msTestClass = New Collection
End Sub
Public Sub Add(Item As OrigClass)
    msTestClass.Add _
        Item:=Item, _
        Key:=Item.Name
End Sub
Public Function Extract() As OrigClass
    Dim tblInputs                       As ListObject
    Dim i                               As Integer
    Dim Item                            As OrigClass
    Set tblInputs = ThisWorkbook.Worksheets(WS_NAME).ListObjects(NR_TBL)
    For i = 1 To tblInputs.DataBodyRange.Rows.Count
        Set Item = New OrigClass
        
        With Item
            .Name = tblInputs.DataBodyRange(i, icrName).Value
            .Cost = tblInputs.DataBodyRange(i, icrCost).Value
        End With
        msTestClass.Add Item
    Next i
End Function
Public Function Item(i As Variant) As OrigClass
    Set Item = msTestClass.Item(i)
End Function
Public Function Count() As Integer
    Count = msTestClass.Count
End Function
Friend Property Let Name(Val As String)
    TestClass.Name = Val
End Property
Public Property Get Name() As String
    Name = TestClass.Name
End Property
Friend Property Let Cost(Val As Long)
    TestClass.Cost = Val
End Property
Public Property Get Cost() As Long
    Cost = TestClass.Cost
End Property
This structure works well when I build functions that pass a ranges/table, loop through the rows, and assign a column value to each property. The address is almost always constant and only the values and record count will vary.
I just started building an interface for a class while also trying to retain the collection component, but I'm stumbling on runtime errors... I could possibly create a separate collection class, but I think my problem is more about mismanaging scope rather than encapsulation:
Class module CTestClass
Option Explicit
'Col position references for input table, only includes cols with relevant data
Private Enum icrColRef
    icrName = 2
    icrCost = 4
End Enum
''UDT mirrors class properties
Private Type TTestClass
    Name                                As String
    Cost                                As Long
End Type
Const WS_NAME                           As String = "Sheet1"
Const NR_TBL                            As String = "Table1"
Private msTestClass                     As Collection
Private TestClass                       As TTestClass
Implements ITestClass
Implements FTestClass
Private Sub Class_Initialize()
    Set msTestClass = New Collection
End Sub
Public Sub Add(Item As CTestClass)
    msTestClass.Add _
        Item:=Item, _
        Key:=Item.Name
End Sub
Public Function Create() As ITestClass
    With New CTestClass
        .Extract
' 2) now in Locals window, Me.msTestClass is <No Variables>
        Set Create = .Self
' 4) Me.msTestClass is again <No Variables>, and
'       Create (as Type ITextClass) is Nothing
'       Create (as Type ITextClass/ITextClass) lists property values as
'           <Object doesn't support this property or method>, aka runtime error 438
    End With
End Function
Private Function FTestClass_Create() As ITestClass
    Set FTestClass_Create = Create
End Function
Public Function Extract() As ITestClass
    Dim tblInputs                       As ListObject
    Dim i                               As Integer
    Dim Item                            As CTestClass
    Set tblInputs = ThisWorkbook.Worksheets(WS_NAME).ListObjects(NR_TBL)
    For i = 1 To tblInputs.DataBodyRange.Rows.Count
        Set Item = New CTestClass
        
        With Item
            .Name = tblInputs.DataBodyRange(i, icrName).Value
            .Cost = tblInputs.DataBodyRange(i, icrCost).Value
        End With
        msTestClass.Add Item
    Next i
' 1) in Locals window, Me.msTestClass is populated with all table records
End Function
Public Function ITestClass_Item(i As Variant) As ITestClass
    Set ITestClass_Item = msTestClass.Item(i)
End Function
Public Function ITestClass_Count() As Integer
    ITestClass_Count = msTestClass.Count
End Function
Friend Property Let Name(Val As String)
    TestClass.Name = Val
End Property
Public Property Get Name() As String
    Name = TestClass.Name
End Property
Friend Property Let Cost(Val As Long)
    TestClass.Cost = Val
End Property
Public Property Get Cost() As Long
    Cost = TestClass.Cost
End Property
Public Property Get Self() As ITestClass
    Set Self = Me
' 3) Me.msTestClass is again populated with all table records (scope shift?), but
'       Self is set to Nothing
End Property
Private Property Get ITestClass_Name() As String
    ITestClass_Name = Name
End Property
Private Property Get ITestClass_Cost() As Long
    ITestClass_Cost = Cost
End Property
Interface module ITestClass
'Attribute VB_PredeclaredId = False     <-- revised in text editor
Option Explicit
Public Function Item(i As Variant) As ITestClass
End Function
Public Function Count() As Integer
End Function
Public Property Get Name() As String
End Property
Public Property Get Cost() As Long
End Property
Factory module FTestClass
'Attribute VB_PredeclaredId = False     <-- revised in text editor
Option Explicit
Public Function Create() As ITestClass
End Function
Standard module
Sub TestFactory()
    Dim i                               As ITestClass
    Dim oTest                           As FTestClass
    
    Set oTest = CTestClass.Create
' 5) oTest is <No Variables>, no properties are present
'       as if the variable was never set
    
    For Each i In oTest     ' <-- Runtime error 438, Object doesn't support this property or method
        Debug.Print
        Debug.Print i.Name
        Debug.Print i.Cost
    Next i
End Sub
What am I doing wrong here?
EDIT:
@freeflow pointed out that I didn't state my intentions for introducing an interface.
My office uses several workbook "models" to compile pricing data into a single output table that is then delivered to a downstream customer for importing into a database.
My goal is to standardize the calculations using these various models. The side goal is to understand how to properly implement a factory method.
Each model has one or more input tables, and each table contains a unique collection of 10-30 fields/columns. The output data calculations vary, along with the dependencies on various input fields. However, the output data is the same format all across the board and always contains the same dozen fields.
The example I've shown is intended to be a single interface ITestClass for writing data to the output table. The class that implements it CTestClass can be considered as just one of the several tables (within the several models) containing the input data. I plan on modeling more class objects, one for each input table.
 
     
    