Building a table for my book (2 Viewers)

jwcolby54

Active member
Local time
Today, 11:03
Joined
May 19, 2025
Messages
320
I have been thinking about how to build tables for my book, and how that might fit into the purpose of the book, learning about how to use classes. I want to build some pretty specific little tables. I'll get into the why in a minute. For now, know that I didn't write the following code, I guided ChatGPt, and it was an iterative process. You don't even want to see the entire chat!

I started with wanting to define the name of the table, the name of the fields, and their data types. For this I defined a class. Eventually as I got comfortable with ChatGPT's ability to do this stuff (and in can do this stuff). I added in things like "make a field an autonumber, add an index, add a default value" etc.

So the field class I defined looks like:

Code:
Option Compare Database
Option Explicit

Private mStrName As String
Private mIntType As Integer
Private mBlnIsAutoNumber As Boolean
Private mBlnIsIndexed As Boolean
Private mBlnIsPK As Boolean
Private mIntSize As Integer
Private mVarDefaultValue As Variant
Private mBlnIsRequired As Boolean

Public Property Get pName() As String
    pName = mStrName
End Property
Public Property Let pName(ByVal lStrValue As String)
    mStrName = lStrValue
End Property

Public Property Get pType() As Integer
    pType = mIntType
End Property
Public Property Let pType(ByVal lIntValue As Integer)
    mIntType = lIntValue
End Property

Public Property Get pIsAutoNumber() As Boolean
    pIsAutoNumber = mBlnIsAutoNumber
End Property
Public Property Let pIsAutoNumber(ByVal lBlnValue As Boolean)
    mBlnIsAutoNumber = lBlnValue
End Property

Public Property Get pIsIndexed() As Boolean
    pIsIndexed = mBlnIsIndexed
End Property
Public Property Let pIsIndexed(ByVal lBlnValue As Boolean)
    mBlnIsIndexed = lBlnValue
End Property

Public Property Get pIsPK() As Boolean
    pIsPK = mBlnIsPK
End Property
Public Property Let pIsPK(ByVal lBlnValue As Boolean)
    mBlnIsPK = lBlnValue
End Property

Public Property Get pSize() As Integer
    pSize = mIntSize
End Property
Public Property Let pSize(ByVal lIntValue As Integer)
    mIntSize = lIntValue
End Property

Public Property Get pDefaultValue() As Variant
    pDefaultValue = mVarDefaultValue
End Property
Public Property Let pDefaultValue(ByVal lVarValue As Variant)
    mVarDefaultValue = lVarValue
End Property

Public Property Get pIsRequired() As Boolean
    pIsRequired = mBlnIsRequired
End Property
Public Property Let pIsRequired(ByVal lBlnValue As Boolean)
    mBlnIsRequired = lBlnValue
End Property

As you can see it is simply a bunch of variables which define the fields and various properties of a field, plus property get / lets for all of it. And no I am not going to get into the whole "why not public" thing. Called oddly enough clsFieldDef.

After that I needed a class to build a table. Called oddly enough clsTableBuilder. The idea is to build a class which can accept a table name, and which has a class factory to allow me to create instances of clsFieldDef. These clsFieldDef instances get stored in a collection. Once I have defined the clsFieldDef instances for every field, I then call a function which builds the table and all of the fields, iterating the collection.

Code:
' === ENUM FIELDTYPES ===
Public Enum FieldTypes
    ftBigInt = dbBigInt
    ftBinary = dbBinary
    ftBoolean = dbBoolean
    ftByte = dbByte
    ftCurrency = dbCurrency
    ftDate = dbDate
    ftDecimal = dbDecimal
    ftDouble = dbDouble
    ftGUID = dbGUID
    ftInteger = dbInteger
    ftLong = dbLong
    ftMemo = dbMemo
    ftSingle = dbSingle
    ftText = dbText
    ftVarBinary = dbVarBinary
End Enum

' === MEMBER VARIABLES ===
Private mStrTableName As String
Private mColFields As Collection
Private mDbDatabase As DAO.Database
Private mTdfTableDef As DAO.TableDef

' === INITIALIZATION ===
Private Sub Class_Initialize()
    Set mDbDatabase = CurrentDb
    Set mColFields = New Collection
End Sub

Private Sub Class_Terminate()
    Set mTdfTableDef = Nothing
    Set mDbDatabase = Nothing
    Set mColFields = Nothing
End Sub

Public Sub Init(ByVal lStrTableName As String)
    mStrTableName = lStrTableName
End Sub

Public Sub AddFieldDef(ByVal lFldDef As clsFieldDef)
    On Error Resume Next
    mColFields.Add lFldDef, lFldDef.pName
    If Err.Number <> 0 Then
        MsgBox "Duplicate field name: " & lFldDef.pName, vbExclamation
        Err.Clear
    End If
    On Error GoTo 0
End Sub

' === FACTORY METHOD ===
Public Function CreateFieldDef( _
    ByVal lStrName As String, _
    ByVal lEnumType As FieldTypes, _
    Optional ByVal lBlnIsIndexed As Boolean = False, _
    Optional ByVal lBlnIsAutoNumber As Boolean = False, _
    Optional ByVal lBlnIsPK As Boolean = False _
) As clsFieldDef

    Dim lFld As clsFieldDef
    Set lFld = New clsFieldDef

    lFld.pName = lStrName
    lFld.pType = lEnumType
    lFld.pIsIndexed = lBlnIsIndexed
    lFld.pIsAutoNumber = lBlnIsAutoNumber
    lFld.pIsPK = lBlnIsPK

    Set CreateFieldDef = lFld
End Function

' === CREATE THE TABLE ===
Public Sub CreateTable()
    Dim lFldDef As clsFieldDef
    Dim lFld As DAO.Field
    Dim lIdx As DAO.Index
    Dim lFldPK As clsFieldDef
    Dim lIntPKCount As Integer

    ' Delete table if exists
    On Error Resume Next
    mDbDatabase.TableDefs.Delete mStrTableName
    Err.Clear
    On Error GoTo 0

    Set mTdfTableDef = mDbDatabase.CreateTableDef(mStrTableName)

    ' === Add fields ===
    For Each lFldDef In mColFields
        ' Size for text/binary/varbinary
        If lFldDef.pSize > 0 And _
           (lFldDef.pType = dbText Or lFldDef.pType = dbBinary Or lFldDef.pType = dbVarBinary) Then
            Set lFld = mTdfTableDef.CreateField(lFldDef.pName, lFldDef.pType, lFldDef.pSize)
        Else
            Set lFld = mTdfTableDef.CreateField(lFldDef.pName, lFldDef.pType)
        End If

        If lFldDef.pIsAutoNumber Then
            lFld.Attributes = dbAutoIncrField
        End If

        If Not IsNull(lFldDef.pDefaultValue) Then
            lFld.DefaultValue = lFldDef.pDefaultValue
        End If

        lFld.Required = lFldDef.pIsRequired

        mTdfTableDef.Fields.Append lFld
    Next lFldDef

    ' === Add Composite Primary Key ===
    Set lIdx = mTdfTableDef.CreateIndex("PrimaryKey")
    For Each lFldPK In mColFields
        If lFldPK.pIsPK Then
            lIdx.Fields.Append lIdx.CreateField(lFldPK.pName)
            lIntPKCount = lIntPKCount + 1
        End If
    Next lFldPK

    If lIntPKCount > 0 Then
        lIdx.Primary = True
        mTdfTableDef.Indexes.Append lIdx
    End If

    ' === Add Secondary Indexes ===
    For Each lFldDef In mColFields
        If lFldDef.pIsIndexed And Not lFldDef.pIsPK Then
            Set lIdx = mTdfTableDef.CreateIndex("idx_" & lFldDef.pName)
            lIdx.Fields.Append lIdx.CreateField(lFldDef.pName)
            mTdfTableDef.Indexes.Append lIdx
        End If
    Next lFldDef

    mDbDatabase.TableDefs.Append mTdfTableDef
    mDbDatabase.TableDefs.Refresh

    MsgBox "Table '" & mStrTableName & "' created successfully.", vbInformation
End Sub

And yes, this code actually works. Test code:
 
Last edited:
Code:
Public Function Test_Build_tblPeople()
    On Error GoTo Test_Build_tblPeople_Error
    Dim lclsTableBuilder As clsTableBuilder
    Set lclsTableBuilder = New clsTableBuilder

    Dim lClsFieldDef As clsFieldDef

    lclsTableBuilder.Init "tblPeople"

    ' === PE_ID: AutoNumber PK ===
    Set lClsFieldDef = lclsTableBuilder.CreateFieldDef("PE_ID", ftLong, False, True, True)
    lclsTableBuilder.AddFieldDef lClsFieldDef

    ' === PE_FName: Short Text, Required ===
    Set lClsFieldDef = lclsTableBuilder.CreateFieldDef("PE_FName", ftText)
    lClsFieldDef.pSize = 50
    lClsFieldDef.pIsRequired = True
    lclsTableBuilder.AddFieldDef lClsFieldDef

    ' === PE_LName: Short Text, Required ===
    Set lClsFieldDef = lclsTableBuilder.CreateFieldDef("PE_LName", ftText)
    lClsFieldDef.pSize = 50
    lClsFieldDef.pIsRequired = True
    lclsTableBuilder.AddFieldDef lClsFieldDef

    ' === PE_DOB: Date/Time ===
    Set lClsFieldDef = lclsTableBuilder.CreateFieldDef("PE_DOB", ftDate)
    lclsTableBuilder.AddFieldDef lClsFieldDef

    ' === PE_IDEC: Long Integer, Indexed ===
    Set lClsFieldDef = lclsTableBuilder.CreateFieldDef("PE_IDEC", ftLong, True)
    lclsTableBuilder.AddFieldDef lClsFieldDef

    ' === PE_IDHC: Long Integer, Indexed ===
    Set lClsFieldDef = lclsTableBuilder.CreateFieldDef("PE_IDHC", ftLong, True)
    lclsTableBuilder.AddFieldDef lClsFieldDef

    ' === PE_Active: Yes/No, Default = True ===
    Set lClsFieldDef = lclsTableBuilder.CreateFieldDef("PE_Active", ftBoolean)
    lClsFieldDef.pDefaultValue = True
    lclsTableBuilder.AddFieldDef lClsFieldDef

    ' === PE_Trash: Yes/No, Default = False ===
    Set lClsFieldDef = lclsTableBuilder.CreateFieldDef("PE_Trash", ftBoolean)
    lClsFieldDef.pDefaultValue = False
    lclsTableBuilder.AddFieldDef lClsFieldDef

    ' === Build the table ===
    lclsTableBuilder.CreateTable
   
Exit_Test_Build_tblPeople:
    On Error GoTo 0
    Test_Build_tblPeople = True
    Exit Function

Test_Build_tblPeople_Error:
Dim strErrMsg As String
    Select Case Err
    Case 0      'insert Errors you wish to ignore here
        Resume Next
    Case Else   'All other errors will trap
        strErrMsg = "Error " & Err.Number & " (" & Err.Description & ") in procedure FirstDatabase.basTest.Test_Build_tblPeople, line " & Erl & "."
        Beep
#If boolELE = 1 Then
        WriteErrorLog strErrMsg
#End If
        assDebugPrint strErrMsg
        Resume Exit_Test_Build_tblPeople
    End Select
    Resume Exit_Test_Build_tblPeople
    Resume 0    'FOR TROUBLESHOOTING
End Function

The two classes and this code will go in the book to build a tblPeople. I can now build tables by adding new Test_Build_xyz functions. Obviously it takes a bit of work on my part to define the fields, but hey... it serves the purpose of demonstrating a bunch of OOP functionality, as well as getting a finished product for the book, tables built for forms to demonstrate functionality of my form and control wrappers.

It took me about two hours guiding ChatGPT to get these finished products. Two classes and a function to build the table.

Call me crazy. Now I go back to work to add code to add data values.
 
Last edited:
I actually prompted ChatGPT with the following to get the test_Build_XXX code:

Build a test function which builds tblPeople. It contains the following fields:
PE_ID autonumber
PE_FName Short
TextPE_LName Short
textPE_DOB Date/Time
PE_IDEC Long Integer, indexed
PE_IDHC Long Integer, Indexed
PE_Active Yes/no, default value = true
PE_Trash Yes/No, Default value = false

From that it built

Public Function Test_Build_tblPeople()
 
And a couple of additions for programmer assistance:

Code:
' === LOG TABLE STRUCTURE TO IMMEDIATE WINDOW ===
Private Sub LogStructure()
    Dim lClsFieldDef As clsFieldDef
    Debug.Print "Creating table: " & mStrTableName
    Debug.Print String(60, "-")

    For Each lClsFieldDef In mColFields
        Debug.Print "Field: " & lClsFieldDef.pName
        Debug.Print "  Type: " & FieldTypeName(lClsFieldDef.pType)
        If lClsFieldDef.pSize > 0 Then Debug.Print "  Size: " & lClsFieldDef.pSize
        If lClsFieldDef.pIsRequired Then Debug.Print "  Required: Yes"
        If Not IsNull(lClsFieldDef.pDefaultValue) Then Debug.Print "  Default: " & lClsFieldDef.pDefaultValue
        If lClsFieldDef.pIsAutoNumber Then Debug.Print "  AutoNumber: Yes"
        If lClsFieldDef.pIsPK Then Debug.Print "  Primary Key: Yes"
        If lClsFieldDef.pIsIndexed Then Debug.Print "  Indexed: Yes"
        Debug.Print ""
    Next lClsFieldDef
End Sub

' === HELPER TO CONVERT DAO TYPE TO STRING ===
Private Function FieldTypeName(ByVal lIntType As Integer) As String
    Select Case lIntType
        Case dbText: FieldTypeName = "Text"
        Case dbMemo: FieldTypeName = "Memo"
        Case dbLong: FieldTypeName = "Long"
        Case dbDate: FieldTypeName = "Date"
        Case dbBoolean: FieldTypeName = "Yes/No"
        Case dbCurrency: FieldTypeName = "Currency"
        Case dbInteger: FieldTypeName = "Integer"
        Case dbGUID: FieldTypeName = "GUID"
        Case dbDouble: FieldTypeName = "Double"
        Case dbSingle: FieldTypeName = "Single"
        Case dbByte: FieldTypeName = "Byte"
        Case dbDecimal: FieldTypeName = "Decimal"
        Case dbBinary: FieldTypeName = "Binary"
        Case dbVarBinary: FieldTypeName = "VarBinary"
        Case dbBigInt: FieldTypeName = "BigInt"
        Case Else: FieldTypeName = "Unknown"
    End Select
End Function
 
Hi John
I haven't studied the lengthy code in posts 1-4 but you may be interested n reviewing the code by Adolph Dupre that does very similar things.
See his presentation for the Access Europe User Group at

The session video is at:
 
Adding the ability to seed data into the table. This goes into clsTableBuilder:

Code:
Public Sub SeedRows(ByVal lVntSeedData As Variant)
    Dim lRst As DAO.Recordset
    Dim lLngRow As Long
    Dim lLngCol As Long
    Dim lClsFieldDef As clsFieldDef
    Dim lStrFieldName As String

    If IsEmpty(lVntSeedData) Then Exit Sub

    Set lRst = mDbDatabase.OpenRecordset(mStrTableName, dbOpenDynaset)

    For lLngRow = LBound(lVntSeedData, 1) To UBound(lVntSeedData, 1)
        lRst.AddNew
        For lLngCol = 0 To mColFields.Count - 1
            Set lClsFieldDef = mColFields(lLngCol + 1)
            If Not lClsFieldDef.pIsAutoNumber Then
                lStrFieldName = lClsFieldDef.pName
                lRst(lStrFieldName).Value = lVntSeedData(lLngRow, lLngCol)
            End If
        Next lLngCol
        lRst.Update
    Next lLngRow

    lRst.Close
    Set lRst = Nothing
End Sub

And finally, added into the test code:

Code:
    ' === Create Table ===
    lClsTableBuilder.CreateTable lBlnAutoDelete

    ' === Seed data only if table was rebuilt ===
    If lBlnAutoDelete Then
        Dim lVntSeedData As Variant
        lVntSeedData = Array( _
            Array("John", "Smith", #1/15/1980#, 1, 1, True, False), _
            Array("Mary", "Jones", #7/4/1990#, 2, 1, True, False), _
            Array("Alan", "Brown", #3/22/1975#, 1, 2, False, False) _
        )
        lClsTableBuilder.SeedRows lVntSeedData
    End If
 
Hi John
I haven't studied the lengthy code in posts 1-4 but you may be interested n reviewing the code by Adolph Dupre that does very similar things.
In fact it does the opposite, but quite cool thing. I am building a table from scratch, he is building a class to build a table from an existing table. I did that ages ago, not sure I could even find my code for that but still, it is quite a useful thing. I could of course go build the tables for the book, add data and then use that kind of code to build those same tables in the reader's database they are building.

The problem is that I am trying to teach classes, and the reader doesn't have the tables to run that code against. My code will build the book's tables on-the-fly, demoing the "class way" of doing precisely that.
 
And of course when I get around to testing the SeedRows it doesn't function. A couple of iterations later:

Code:
Public Sub SeedRows(ByVal lVntSeedData As Variant)
    Dim lRst As DAO.Recordset
    Dim lLngRow As Long
    Dim lLngFieldIndex As Long
    Dim lLngDataCol As Long
    Dim lClsFieldDef As clsFieldDef
    Dim lStrFieldName As String

    If IsEmpty(lVntSeedData) Then Exit Sub

    Set lRst = mDbDatabase.OpenRecordset(mStrTableName, dbOpenDynaset)

    For lLngRow = LBound(lVntSeedData) To UBound(lVntSeedData)
        lRst.AddNew
        lLngDataCol = 0

        For lLngFieldIndex = 1 To mColFields.Count
            Set lClsFieldDef = mColFields(lLngFieldIndex)
            If Not lClsFieldDef.pIsAutoNumber Then
                lStrFieldName = lClsFieldDef.pName
                If lLngDataCol <= UBound(lVntSeedData(lLngRow)) Then
                    lRst(lStrFieldName).Value = lVntSeedData(lLngRow)(lLngDataCol)
                    lLngDataCol = lLngDataCol + 1
                Else
                    Debug.Print "WARNING: Column " & lLngDataCol & " missing in row " & lLngRow
                End If
            End If
        Next lLngFieldIndex

        lRst.Update
    Next lLngRow

    lRst.Close
    Set lRst = Nothing
End Sub

It "works" now. Just preliminary testing of course but I have the table built with seed data;

1750722121369.png
 
And finally documentation for the class, now found in the class header:

Code:
' ========================================================================================
' clsTableBuilder
' ----------------------------------------------------------------------------------------
' PURPOSE:
'   Dynamically builds Access DAO tables at runtime using a declarative approach.
'   Encapsulates field definition, table creation, indexing, seeding, and logging.
'
' OVERVIEW:
'   - Works in tandem with clsFieldDef to define field names, types, and properties.
'   - Stores all field definitions in an internal collection.
'   - Generates new tables using DAO, optionally deletes and recreates existing ones.
'   - Can log the full intended structure to the Immediate window (via assDebugPrint).
'   - Supports composite primary keys, secondary indexes, AutoNumber, and defaults.
'   - Allows clean and structured seeding of data into newly created tables.
'
' ROLE OF clsFieldDef:
'   clsFieldDef represents a single field definition: its name, data type, size, default value,
'   and flags for AutoNumber, Required, Indexed, and Primary Key.
'   clsTableBuilder uses one clsFieldDef object per field. These are:
'     - Created via the CreateFieldDef factory method
'     - Added via AddFieldDef
'     - Stored in mColFields (a Collection)
'   Each field in the final DAO table is generated based on its corresponding clsFieldDef.
'
' KEY PUBLIC METHODS:
'   Init(tableName As String)
'       Sets the target table name to be built.
'
'   CreateFieldDef(name As String, type As FieldTypes, [isIndexed], [isAutoNumber], [isPK])
'       Factory method to create a new clsFieldDef object.
'
'   AddFieldDef(fieldDef As clsFieldDef)
'       Adds a clsFieldDef to the internal field collection.
'
'   CreateTable([autoDelete As Boolean], [log As Boolean])
'       Builds the table. If autoDelete=True, deletes the existing table if found.
'       If log=True, outputs the full structure to the Immediate window.
'
'   SeedRows(seedData As Variant)
'       Inserts data into the newly created table. Skips AutoNumber fields.
'       Accepts a 1D array of 1D arrays (jagged array of rows).
'
'   FormatSeedData(rawData As Variant) As Variant
'       Converts a simple jagged row array to match the order of the non-AutoNumber fields.
'       Useful before passing to SeedRows().
'
' DEPENDENCIES:
'   - clsFieldDef class module (with pName, pType, pIsIndexed, etc.)
'   - assDebugPrint(msg As String) function for conditional logging
'
' EXAMPLE USAGE:
'   Dim b As New clsTableBuilder
'   b.Init "tblExample"
'   b.AddFieldDef b.CreateFieldDef("ID", ftLong, False, True, True)
'   b.AddFieldDef b.CreateFieldDef("Name", ftText)
'   b.CreateTable True, True
'   b.SeedRows b.FormatSeedData(Array(Array("Alice"), Array("Bob")))
'
' AUTHOR: John W. Colby
' LICENSE: MIT or Public Domain as defined in the accompanying documentation.
' ========================================================================================
 
A couple of extra table builders for hair and eye colors:

Code:
' ========================================================================================
' Test_Build_tlkpEyeColor
' ----------------------------------------------------------------------------------------
' PURPOSE:
'   Builds a lookup table named "tlkpEyeColor" for eye color codes.
'
' BEHAVIOR:
'   - Defines the following fields:
'       EC_ID     (AutoNumber Primary Key)
'       EC_Color  (Short Text)
'
'   - Deletes existing table if lBlnAutoDelete = True
'   - Logs structure if lBlnLog = True
'   - Seeds static lookup values for standard eye colors
'
' ========================================================================================
Public Sub Build_tlkpEyeColor(Optional ByVal lBlnAutoDelete As Boolean = False, _
                                   Optional ByVal lBlnLog As Boolean = False)

    Dim lClsTableBuilder As clsTableBuilder
    Set lClsTableBuilder = New clsTableBuilder
    lClsTableBuilder.Init "tlkpEyeColor"

    Dim lClsFieldDef As clsFieldDef

    ' EC_ID: AutoNumber Primary Key
    Set lClsFieldDef = lClsTableBuilder.CreateFieldDef("EC_ID", ftLong, False, True, True)
    lClsTableBuilder.AddFieldDef lClsFieldDef

    ' EC_Color: Short Text
    Set lClsFieldDef = lClsTableBuilder.CreateFieldDef("EC_Color", ftText)
    lClsFieldDef.pSize = 25
    lClsTableBuilder.AddFieldDef lClsFieldDef

    lClsTableBuilder.CreateTable lBlnAutoDelete, lBlnLog

    If lBlnAutoDelete Then
        Dim lArrRawData As Variant
        lArrRawData = Array( _
            Array("Brown"), _
            Array("Blue"), _
            Array("Green"), _
            Array("Violet"), _
            Array("Yellow"), _
            Array("Red"), _
            Array("Black") _
        )

        Dim lArrSeedFormatted As Variant
        lArrSeedFormatted = lClsTableBuilder.FormatSeedData(lArrRawData)

        lClsTableBuilder.SeedRows lArrSeedFormatted
    End If
End Sub

and :

Code:
' ========================================================================================
' Test_Build_tlkpHairColor
' ----------------------------------------------------------------------------------------
' PURPOSE:
'   Builds a lookup table named "tlkpHairColor" for hair color codes.
'
' BEHAVIOR:
'   - Defines the following fields:
'       HC_ID     (AutoNumber Primary Key)
'       HC_Color  (Short Text)
'
'   - Deletes existing table if lBlnAutoDelete = True
'   - Logs structure if lBlnLog = True
'   - Seeds static lookup values for standard hair colors
'
' ========================================================================================
Public Sub Build_tlkpHairColor(Optional ByVal lBlnAutoDelete As Boolean = False, _
                                    Optional ByVal lBlnLog As Boolean = False)

    Dim lClsTableBuilder As clsTableBuilder
    Set lClsTableBuilder = New clsTableBuilder
    lClsTableBuilder.Init "tlkpHairColor"

    Dim lClsFieldDef As clsFieldDef

    ' HC_ID: AutoNumber Primary Key
    Set lClsFieldDef = lClsTableBuilder.CreateFieldDef("HC_ID", ftLong, False, True, True)
    lClsTableBuilder.AddFieldDef lClsFieldDef

    ' HC_Color: Short Text
    Set lClsFieldDef = lClsTableBuilder.CreateFieldDef("HC_Color", ftText)
    lClsFieldDef.pSize = 25
    lClsTableBuilder.AddFieldDef lClsFieldDef

    lClsTableBuilder.CreateTable lBlnAutoDelete, lBlnLog

    If lBlnAutoDelete Then
        Dim lArrRawData As Variant
        lArrRawData = Array( _
            Array("Brown"), _
            Array("Black"), _
            Array("Blond"), _
            Array("Grey"), _
            Array("Red") _
        )

        Dim lArrSeedFormatted As Variant
        lArrSeedFormatted = lClsTableBuilder.FormatSeedData(lArrRawData)

        lClsTableBuilder.SeedRows lArrSeedFormatted
    End If
End Sub
 
wow, you really took time to build that class of yours, when people
would prefer to do it using the manual way.
 

Users who are viewing this thread

Back
Top Bottom