【问题标题】:Only public user defined types defined in public object modules can be used as parameters in VBA只有在公共对象模块中定义的公共用户定义类型才能用作 VBA 中的参数
【发布时间】:2015-11-24 04:18:53
【问题描述】:

我有一个公共 UDT,并想将它用作普通模块中公共子的参数。然后我得到一个编译错误:

只有在公共对象模块中定义的公共用户定义类型才能用作类模块的公共过程的参数或返回类型,或者用作公共用户定义类型的字段。

不知道真不明白,UDT和sub都是public的。

这是我定义的 UDT。

Public Type perf
    retailer As String
    sale As Integer
    cateDiscrip As String
    prodCode As String
    forecast As Integer
    score As Double
End Type

基本上,我想将一个表(包含零售商、类别描述、产品代码等)存储到一个数组中,然后按零售商对它们进行排序,对于同一零售商,按类别排序。 我从另一张表中复制它们,然后将它们粘贴到当前工作簿的“数据”表中。 然后,我定义了一个公共 UDT 并将它们存储在一个数组中。

Public Sub getlist()

    Dim highvol() As perf
    Dim lowvol() As perf
    Dim oneArr() As perf
    Dim i As Integer
    Dim s As Integer

    Set ws = Application.Worksheets("data")

    'find the number of retailers, redimension the array, and fill them with
    'the data in the lists

    With ws.Range("A2")
        nRetailer = ws.Range(.Offset(1, 0), .End(xlDown)).Rows.Count
        ReDim highvol(nRetailer)
    End With

    For isale = 2 To nRetailer
          If ws.Range("M1").Cells(isale) >= 10 Then
              n = n + 1
          Else
              m = m + 1
          End If
     Next

    ReDim highvol(n)
    ReDim lowvol(m)
    ReDim oneArr(nRetailer)

    nsale = 0
    msale = 0

''isale is the current row, nsale is the size of highvol sales. 
    For isale = 2 To nRetailer
        If ws.Range("M1").Cells(isale) >= 10 Then
            nsale = nsale + 1
            highvol(nsale).sale = ws.Cells(isale, 13)
            highvol(nsale).forecast = Str(ws.Range("N1").Cells(isale))
            highvol(nsale).retailer = ws.Range("A1").Cells(isale)
            highvol(nsale).cateDiscrip = ws.Range("B1").Cells(isale)
            highvol(nsale).prodCode = ws.Range("C1").Cells(isale)
            highvol(nsale).score = Str((1 - AbsPerErr(ws.Range("M1").Cells(isale), ws.Range("N1").Cells(isale))) * 100)
        Else
            msale = msale + 1
            lowvol(msale).sale = Str(ws.Range("M1").Cells(isale))
            lowvol(msale).forecast = Str(ws.Range("N1").Cells(isale))
            lowvol(msale).retailer = ws.Range("A1").Cells(isale)
            lowvol(msale).cateDiscrip = ws.Range("B1").Cells(isale)
            lowvol(msale).prodCode = ws.Range("C1").Cells(isale)
            lowvol(msale).score = Str((1 - AbsPerErr(ws.Range("M1").Cells(isale), ws.Range("N1").Cells(isale))) * 100)
        End If
    Next

之后,我有两个函数用于过滤和比较,将数据传递到一个数组中。

    For i = 1 To nsale
        oneArr(i) = highvol(i)
    Next

    For s = 1 To msale
        oneArr(nsale + s) = lowvol(s)
    Next

    Dim result1() As perf
    Dim result2() As perf

    filter oneArr, "AED", 1, result1
    filter result1, "RhinoBulk1", 2, result2

End Sub

这是我得到错误 filter oneArr 的地方。谁能解释发生了什么问题以及如何解决?

【问题讨论】:

  • 为此使用类而不是 UDT。 (您只需将您的 UDT 成员添加为该类的公共成员即可实现最简单的实现)
  • @Rory 谢谢你,但我是新手,以前从未使用过课程。我是否要添加一个新的类模块,然后将代码粘贴到该类中?
  • @user3804820 有关使用类的一些基本信息,请参阅cpearson.com/Excel/Classes.aspx
  • @RonRosenfeld 谢谢,这很有帮助

标签: vba excel user-defined-types


【解决方案1】:

添加一个新的类模块,并将其重命名为 perf 而不是 Class1。粘贴这段代码:

Public retailer As String
Public sale As Integer
Public cateDiscrip As String
Public prodCode As String
Public forecast As Integer
Public score As Double

然后您需要更改循环代码以为数组的每个元素创建类的新实例:

For isale = 2 To nRetailer
    If ws.Range("M1").Cells(isale) >= 10 Then
        nsale = nsale + 1
        Set highvol(nsale) = New perf
        highvol(nsale).sale = ws.Cells(isale, 13)
        highvol(nsale).forecast = Str(ws.Range("N1").Cells(isale))
        highvol(nsale).retailer = ws.Range("A1").Cells(isale)
        highvol(nsale).cateDiscrip = ws.Range("B1").Cells(isale)
        highvol(nsale).prodCode = ws.Range("C1").Cells(isale)
        highvol(nsale).score = Str((1 - AbsPerErr(ws.Range("M1").Cells(isale), ws.Range("N1").Cells(isale))) * 100)
    Else
        msale = msale + 1
        Set lowvol(msale) = new perf
        lowvol(msale).sale = Str(ws.Range("M1").Cells(isale))
        lowvol(msale).forecast = Str(ws.Range("N1").Cells(isale))
        lowvol(msale).retailer = ws.Range("A1").Cells(isale)
        lowvol(msale).cateDiscrip = ws.Range("B1").Cells(isale)
        lowvol(msale).prodCode = ws.Range("C1").Cells(isale)
        lowvol(msale).score = Str((1 - AbsPerErr(ws.Range("M1").Cells(isale), ws.Range("N1").Cells(isale))) * 100)
    End If
Next

【讨论】:

  • 非常感谢,我尝试将它们与其余代码一起粘贴到一个新类中,但是当我运行它时,它没有运行,我不知道是什么问题
  • “不运行”是什么意思?我忘了提到,每当您将类从一个数组分配给另一个数组时,您都需要使用 Set,例如 Set oneArr(i) = highvol(i)
  • 当我运行时,它会弹出一个“宏”窗口,让我选择宏名称(类不包括在内)
  • 你想运行什么?获取列表?
  • 你不能运行一个类模块。类模块只有我发布的第一段代码。其余的替换了您在 GetList 例程中的循环。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-28
  • 1970-01-01
相关资源
最近更新 更多