2

非数値データの平均を作成するために UDF (ユーザー定義関数) を作成しようとしています (数値形式に変換してから、最後に再び戻します)。個々のセルをリストすると、UDF を機能させることができます。#VALUE を取得します。セル範囲を参照しようとするとエラーになります。処理する範囲と個々のセルの両方が混在している場合があります。

何か案は?

これまでのコードは以下です。

Function avlvl(ParamArray av() As Variant)
Dim a As Integer
'creates an average ks3 level from data in format "5a"
a = 0
n = 0
total = 0
Do While a < UBound(av()) + 1
   'ignore blank or zero cells
    If av(a) = 0 Or av(a) = "" Then
        a = a + 1
    Else
       'convert data into numeric value - split into level and sub level
        level = Val(Left(av(a), 1))
        sl = Right(av(a), 1)
        If sl = "c" Then
            sublevel = 0
        ElseIf sl = "C" Then
            sublevel = 0
        ElseIf sl = "b" Or sl = "B" Then
            sublevel = 1 / 3
        ElseIf sl = "a" Or sl = "A" Then
            sublevel = 2 / 3
        Else
            sublevel = 0
        End If
       'score is numeric value of the data
        score = level + sublevel
       'total is teh toatl of the cells so far
        total = total + score
        a = a + 1
        n = n + 1
    End If
Loop
ave = total / n
'reconvert into format level and sublevel (a,b,c)
averagelevel = Application.WorksheetFunction.RoundDown(ave, 0)
asl = ave - averagelevel
If asl < 0.17 Then
    averagesublevel = "c"
ElseIf asl < 0.5 Then
    averagesublevel = "b"
ElseIf asl < 0.84 Then
    averagesublevel = "a"
ElseIf asl < 1 Then
    averagelevel = averagelevel + 1
    averagesublevel = "c"
Else
    averagesublevel = "c"
End If

avlvl = averagelevel & averagesublevel

End Function
4

2 に答える 2

2

何が起こっているかというと、範囲が Range 型の単一のオブジェクトとして入力され、コードがそれを配列として入力されているかのように処理しようとしているということです。

最善の方法は、関数の本体内に新しい配列を作成し、範囲内の要素を新しい配列に割り当てることです。ParamArray の要素の型をテストする必要があります。要素が String 型の場合は、新しい配列に直接配置します。要素が Range 型の場合、その要素をループして、そのセル値を新しい配列に割り当てます。

次に、新しい配列で処理を行います。

次のコードは、範囲と個々のセルまたは値を渡すための機構を提供します。私はあなたのコードを含めていませんが、それがどこに行くのかを示しました.

Function avlvl(ParamArray av() As Variant) As Variant

    Dim a As Integer
    Dim i As Long
    Dim avArr()
    Dim element As Variant

    a = 0
    i = 0
    Do While a < UBound(av) + 1
        If TypeName(av(a)) = "String" Then
            avArr(i) = av(a)
            i = i + 1
        ElseIf TypeName(av(a)) = "Range" Then
            For Each element In av(a)
                ReDim Preserve avArr(0 To i)
                avArr(i) = element
                i = i + 1
            Next
        Else
            avlvl = CVErr(xlErrValue)
            Exit Function
        End If
        a = a + 1
    Loop
    i = 0
    Do While i < UBound(avArr) + 1
        '...
        'now process the elements of avArr()
        '...
        i = i + 1
    Loop
End Function
于 2013-06-28T21:28:24.213 に答える
0

ばらばらのセル範囲があり、それらを UDF に渡したい場合、1 つの方法は、定義名を作成し、それを単一の引数として UDF に渡すことです。

于 2013-06-28T12:32:09.143 に答える