繁体   English   中英

自定义函数在VBA中工作,并在Excel单元格中调用时返回#VALUE“错误的数据类型”

[英]Custom Function Works in VBA and returns #VALUE “wrong data type” when called in a Excel Cell

我有一个UDF,可以计算给定一周内有多少个客户和服务人员,或一个客户有多少服务人员。 数据有两个不同的范围,一个是由服务人员排序的,另一个是由客户端排序的,以防止必须先排序。

该代码创建了一个数组来记录我要搜索的一周中各行的行引用,然后计算完工作人员或客户的最后一个实例。 该代码在VBA中有效,并在Excel中返回一个#VALUE,并在Excel中返回“错误检查”,指示错误的数据类型。使用中断,看来代码在进行范围创建时失败了,这可能与创建是否从范围中获取行引用的数组。

我想知道我是否正在尝试修改“ excel的状态”。对这个问题的想法以及如何解决?

Public Function clientOrServiceWorkerCount(startWeek As Integer, endWeek As 
Integer, searchID As Long, outputType As Integer, sheetName As Variant) As 
Integer

    clientOrServiceWorkerCount = 0

    Dim WSMod111 As Worksheet
    Set WSMod111 = sheetName


    Dim rowOffset As Integer
    rowOffset = 3
    Dim endIndex As Integer
    endIndex = WSMod111.Cells(WSMod111.Rows.count, 13).End(xlUp).row - 
    rowOffset

    Dim tempRange As Range
    Set tempRange = WSMod111.Range("U4:Z" & endIndex)

    Dim tempArray() As Integer
    Dim weekNow As Integer
    Dim weekNext As Integer
    Dim ClientIDNow As Long
    Dim ClientIDNext As Long
    Dim serviceWorkerIDNow As Integer
    Dim serviceWorkerIDNext As Integer
    Dim arrayID As Integer
    Dim serviceWorkerCount As Integer
    Dim cLCount As Integer
    Dim colOffset As Integer
    Dim arrayCount As Integer

    arrayCount = 0

    ' Offset which columns to refer to based on the outputType value. 1 = 
    search for client then service workers
    ' 2 = search for service workers and then clients
    If outputType = 1 Then
        colOffset = 0
    End If

    If outputType = 2 Then
        colOffset = 3
    End If

    'Build the array for the week range of interest, defined by startWeek 
and endWeek
    For i = 0 To endIndex - 1
        weekNow = tempRange(i + 1, 1 + colOffset)
        arrayID = tempRange(i + 1, 2 + colOffset)

        If weekNow >= startWeek And weekNow <= endWeek And arrayID = 
        searchID Then
            ReDim Preserve tempArray(arrayCount)
            tempArray(arrayCount) = i + 1
            arrayCount = arrayCount + 1

            'Print the results to the worksheet to check answers
            tempRange.Cells(arrayCount, 8) = tempArray(arrayCount - 1)
        End If
    Next i

   For n = 0 To arrayCount - 1

        weekNow = tempRange(tempArray(n), 1 + colOffset)
        serviceWorkerIDNow = tempRange(tempArray(n), 2 + colOffset)
        ClientIDNow = tempRange(tempArray(n), 3 + colOffset)

        'Debugging printing

        'tempRange.Cells(1 + n, 9) = weekNow
        'tempRange.Cells(1 + n, 11) = serviceWorkerIDNow
        'tempRange.Cells(1 + n, 13) = ClientIDNow

        If n < arrayCount - 1 Then

            weekNext = tempRange(tempArray(n + 1), 1 + colOffset)
            serviceWorkerIDNext = tempRange(tempArray(n + 1), 2 + colOffset)
            ClientIDNext = tempRange(tempArray(n + 1), 3 + colOffset)

            'Debugging printing
            tempRange.Cells(1 + n, 10) = weekNext
            tempRange.Cells(1 + n, 12) = serviceWorkerIDNext
            tempRange.Cells(1 + n, 14) = ClientIDNext

        End If

        If outputType = 1 Then
            If ClientIDNow <> ClientIDNext Or n = arrayCount - 1 Then
                cLCount = cLCount + 1
            End If
        End If

        If outputType = 2 Then
            If serviceWorkerIDNow <> serviceWorkerIDNext Or n = arrayCount - 
            1 Then
                serviceWorkerCount = serviceWorkerCount + 1
            End If
        End If
    Next

    'Return the count of either the clients (outputType=1) or the serviceWorkerinators (outputType=2)
    If outputType = 1 Then
        clientOrServiceWorkerCount = cLCount
    End If

    If outputType = 2 Then
       clientOrServiceWorkerCount = serviceWorkerCount
    End If

End Function

您想在工作表上使用用户定义的函数,但是您的UDF包含更改单元格值的内容。 无法通过直接将功能应用到工作表来完成此操作,因此会发生错误。

    'Debugging printing
    tempRange.Cells(1 + n, 10) = weekNext
    tempRange.Cells(1 + n, 12) = serviceWorkerIDNext
    tempRange.Cells(1 + n, 14) = ClientIDNext

在过程中使用函数的功能如下所示。

Sub test()
    Dim c As Integer
    c = clientOrServiceWorkerCount(2, 3, 1, 1, "Sheet2")
    Range("r1") = c

End Sub

如果注释掉有问题的代码,则结果在工作表上效果很好。

Public Function clientOrServiceWorkerCount( _
        startWeek As Integer, _
        endWeek As Integer, _
        searchID As Long, _
        outputType As Integer, _
        sheetName As Variant) As Integer

    clientOrServiceWorkerCount = 0

    Dim WSMod111 As Worksheet
    Set WSMod111 = Sheets(sheetName)'<~~ Your code should change like this.


    Dim rowOffset As Integer
    rowOffset = 3
    Dim endIndex As Integer
    endIndex = WSMod111.Cells(WSMod111.Rows.Count, 13).End(xlUp).Row - rowOffset

    Dim tempRange As Range
    Set tempRange = WSMod111.Range("U4:Z" & endIndex)

    Dim tempArray() As Integer
    Dim weekNow As Integer
    Dim weekNext As Integer
    Dim ClientIDNow As Long
    Dim ClientIDNext As Long
    Dim serviceWorkerIDNow As Integer
    Dim serviceWorkerIDNext As Integer
    Dim arrayID As Integer
    Dim serviceWorkerCount As Integer
    Dim cLCount As Integer
    Dim colOffset As Integer
    Dim arrayCount As Integer

    arrayCount = 0

    ' Offset which columns to refer to based on the outputType value. 1 = search for client then service workers
    ' 2 = search for service workers and then clients
    If outputType = 1 Then
        colOffset = 0
    End If

    If outputType = 2 Then
        colOffset = 3
    End If

    'Build the array for the week range of interest, defined by startWeek and endWeek
    For i = 0 To endIndex - 1
        weekNow = tempRange(i + 1, 1 + colOffset)
        arrayID = tempRange(i + 1, 2 + colOffset)

        If weekNow >= startWeek And weekNow <= endWeek And arrayID = searchID Then
            ReDim Preserve tempArray(arrayCount)
            tempArray(arrayCount) = i + 1
            arrayCount = arrayCount + 1

            'Print the results to the worksheet to check answers
            'tempRange.Cells(arrayCount, 8) = tempArray(arrayCount - 1)
        End If
    Next i

   For n = 0 To arrayCount - 1

        weekNow = tempRange(tempArray(n), 1 + colOffset)
        serviceWorkerIDNow = tempRange(tempArray(n), 2 + colOffset)
        ClientIDNow = tempRange(tempArray(n), 3 + colOffset)

        'Debugging printing

        'tempRange.Cells(1 + n, 9) = weekNow
        'tempRange.Cells(1 + n, 11) = serviceWorkerIDNow
        'tempRange.Cells(1 + n, 13) = ClientIDNow

        If n < arrayCount - 1 Then

            'weekNext = tempRange(tempArray(n + 1), 1 + colOffset)
            'serviceWorkerIDNext = tempRange(tempArray(n + 1), 2 + colOffset)
            'ClientIDNext = tempRange(tempArray(n + 1), 3 + colOffset)

            'Debugging printing
            'tempRange.Cells(1 + n, 10) = weekNext
            'tempRange.Cells(1 + n, 12) = serviceWorkerIDNext
            'tempRange.Cells(1 + n, 14) = ClientIDNext

        End If

        If outputType = 1 Then
            If ClientIDNow <> ClientIDNext Or n = arrayCount - 1 Then
                cLCount = cLCount + 1
            End If
        End If

        If outputType = 2 Then
            If serviceWorkerIDNow <> serviceWorkerIDNext Or n = arrayCount - 1 Then
                serviceWorkerCount = serviceWorkerCount + 1
            End If
        End If
    Next

    'Return the count of either the clients (outputType=1) or the serviceWorkerinators (outputType=2)
    If outputType = 1 Then
        clientOrServiceWorkerCount = cLCount
    End If

    If outputType = 2 Then
       clientOrServiceWorkerCount = serviceWorkerCount
    End If

End Function

Dy.Lee,我根据您的建议注释了调试打印:

    For n = 0 To arrayCount - 1

        weekNow = tempRange(tempArray(n), 1 + colOffset)
        serviceWorkerIDNow = tempRange(tempArray(n), 2 + colOffset)
        ClientIDNow = tempRange(tempArray(n), 3 + colOffset)

        'Debugging printing
        'tempRange.Cells(1 + n, 9) = weekNow
        'tempRange.Cells(1 + n, 11) = serviceWorkerIDNow
        'tempRange.Cells(1 + n, 13) = ClientIDNow

        If n < arrayCount - 1 Then

            weekNext = tempRange(tempArray(n + 1), 1 + colOffset)
            serviceWorkerIDNext = tempRange(tempArray(n + 1), 2 + colOffset)
            ClientIDNext = tempRange(tempArray(n + 1), 3 + colOffset)

            'Debugging printing
            'tempRange.Cells(1 + n, 10) = weekNext
            'tempRange.Cells(1 + n, 12) = serviceWorkerIDNext
            'tempRange.Cells(1 + n, 14) = ClientIDNext

而且效果很好。 我还更新了您所做的Sheet(“”)引用,并且不再收到编译错误。 我不知道我的调试代码是否违反了“单元格中引用的函数只能更改该引用的单元格”的规则-因为我不知道该规则存在。 非常感谢您的帮助,数周来我一直在脑子里ash着脑子,努力找出问题所在。 问候,安东尼

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM