只能将公共对象模块中定义的用户定义类型强制给变量或强制自变量,或传递给后期绑定函数

Ric*_*ell 2 excel vba compiler-errors excel-vba

我正在尝试创建一种结构,可以用来分隔记录的各个元素以使用它们的组件。每个记录包含一个记录编号,组,分区,类别和5个整数代码,这些代码将根据其组,分区和类别用于各种操作。每当我尝试将RecordType传递到ArrayList中时,都会收到此问题标题中所述的错误。我曾尝试查看其他有此错误的问题,但似乎没有答案。我曾尝试为RecordType创建一个单独的类,但是它说不能使用公共类类型来完成。这是我尝试分离和使用的数据:

65f8|gh|l1|9k|985|8437|7894|9495|3730|
4287|gh|w1|uk|7341|5638|7715|8906|698|
3s89|jk|w1|h7|225|487|2013|4328|4066|
62l5|lo|r5|9k|5103|9879|3448|2921|7581|
486p|lo|r5|uk|6882|9879|2672|1015|3160|
a597|lo|r6|m9|385|6915|3615|9195|9817|
1m36|hu|k8|h7|656|8064|3852|9110|9858|
Run Code Online (Sandbox Code Playgroud)

这是我编写的代码。注释是我用来在excel中测试代码某些部分的循环。

Type RecordType
    number As String
    group As String
    div As String
    cat As String
    code1 As Integer
    code2 As Integer
    code3 As Integer
    code4 As Integer
    code5 As Integer
End Type

Sub ProgramOne()


Dim fileName As String, textData As String, fileLine As String, rowList() As String, numOfRecords As Integer, someString As String
Dim rowNum As Integer, colNum As Integer, counter As Integer, counter2 As Integer, groupCount As Integer, divCount As Integer, catCount As Integer
Dim groupBool As Boolean, catBool As Boolean, divBool As Boolean, groupList As Object, divList As Object, catList As Object

Set groupList = CreateObject("System.Collections.ArrayList")
Set divList = CreateObject("System.Collections.ArrayList")
Set catList = CreateObject("System.Collections.ArrayList")

fileName = "/Users/Ricky/Desktop/project1Data.txt"
Open fileName For Input As #1
rowNum = 1

Dim records As Object
Set records = CreateObject("System.Collections.ArrayList")
Dim placeholder As RecordType

Do Until EOF(1)
    numOfRecords = numOfRecords + 1
    Line Input #1, fileLine
    rowList = Split(fileLine, "|")

    placeholder.number = rowList(0)
    placeholder.group = rowList(1)
    placeholder.div = rowList(2)
    placeholder.cat = rowList(3)
    placeholder.code1 = rowList(4)
    placeholder.code2 = rowList(5)
    placeholder.code3 = rowList(6)
    placeholder.code4 = rowList(7)
    placeholder.code5 = rowList(8)

    records.Add (placeholder)
Loop

'Dim counter2 As Integer
'counter2 = 2
'    For x = 0 To UBound(records) - LBound(records)
'        Cells(counter2, 1) = records(x).group
'        Cells(counter2, 2) = records(x).div
'        counter2 = counter2 + 1
'    Next

Close #1

'For x = 0 To UBound(records) - LBound(records)

    divBool = False
    catBool = False

groupCount = 0
divCount = 0
catCount = 0
'Dim GroupName As Variant

'For Each GroupName In groupList
'    groupBool = False
'    For num = 0 To UBound(records) - LBound(records)
'        If CStr(records(num).group) = CStr(GroupName) Then
'            groupBool = True
'        End If
'        If Not groupBool Then
'            groupCount = groupCount + 1
'            groupList(groupCount) = records(num).group
'        End If
'    Next num
'Next GroupName
counter = 0
counter2 = 0
For Each GroupName In records
    For Each GroupName2 In groupList
        If records(counter).group = groupList(counter2) Then
            groupBool = True
        End If
        counter2 = counter2 + 1
    Next GroupName2
    If groupBool = False Then

Next GroupName

Cells(1, 1) = "Number of records: " & numOfRecords
Cells(1, 2) = "Number of Groups: " & groupCount
Cells(2, 1) = "records index: " & UBound(records) - LBound(records)
counter = 0
'For Each GroupName In groupList
'    Cells(3, counter) = GroupName
'    counter = counter + 1
'Next GroupName
End Sub
Run Code Online (Sandbox Code Playgroud)

Mat*_*don 5

添加一个新的类模块,调用它Record,将其移入Type其中,使其成为Private,然后声明该类型的私有字段,并为每个成员公开a Property Get和a Property Let

Option Explicit

Private Type TRecord
    Number As String
    Group As String
    Division As String
    Category As String
    Codes(1 To 5) As Long
End Type

Private this As TRecord

Public Property Get Number() As String
    Number = this.Number
End Property

Public Property Let Number(ByVal value As String)
    this.Number = value
End Property

Public Property Get Group() As String
    Group = this.Group
End Property

Public Property Let Group(ByVal value As String)
    this.Group = value
End Property

Public Property Get Division() As String
    Division = this.Division
End Property

Public Property Let Division(ByVal value As String)
    this.Division = value
End Property

Public Property Get Category() As String
    Category = this.Category
End Property

Public Property Let Category(ByVal value As String)
    this.Category = value
End Property

Public Property Get Code(ByVal index As Long) As Long
    Code = this.Codes(index)
End Property

Public Property Let Code(ByVal index As Long, ByVal value As Long)
    this.Codes(index) = value
End Property
Run Code Online (Sandbox Code Playgroud)

现在改用该类的实例,它应该可以正常工作。

要获得更多凉爽因素,请删除并导出类模块,在记事本中将其打开,然后将其VB_PredeclaredId属性设置为True。保存并重新导入模块:现在,您的类具有默认实例,有了它,您可以具有工厂方法

Public Function Create(ByVal pNumber As String, ByVal pGroup As String, ByVal pDivision As String, ByVal pCategory As String, ParamArray pCodes As Variant) As Record
    With New Record
        .Number = pNumber
        .Group = pGroup
        .Division = pDivision
        .Category = pCategory

        'todo assert number of parameters to prevent out-of-bounds error
        Dim i As Long
        For i = LBound(pCodes) To UBound(pCodes)
            .Code(i) = pCodes(i)
        Next

        Set Create = .Self
    End with
End Function

Public Property Get Self() As Record
    Set Self = Me
End Property
Run Code Online (Sandbox Code Playgroud)

现在,阅读器循环可以如下所示:

Do Until EOF(1)
    numOfRecords = numOfRecords + 1
    Line Input #1, fileLine
    rowList = Split(fileLine, "|")
    records.Add Record.Create(rowList(0), rowList(1), rowList(2), rowList(3), rowList(4), rowList(5), rowList(6), rowList(7), rowList(8))
Loop
Run Code Online (Sandbox Code Playgroud)

请注意,可以滥用类的默认实例 来保持全局状态(例如,某些人使用的默认实例的方式)。那并不意味着他们应该。对于属于“静态”的方法使用默认实例类型,而不是一个实例,你会做的很好。UserForm

结合接口,您甚至可以模拟不变性,但是我认为您不需要为此而去。