1

私はvbaにかなり慣れていないので、vbArraysでこの問題を解決できないようです。生活を楽にするために、vba で関数 cumsum を作成しました。ただし、関数と範囲の両方のバリアントを渡すことができるように、コードを柔軟にしたいと考えています。私のコードでは、範囲を渡す場合に vec=vec.value という行を追加すると、完全に正常に動作しますが、関数を呼び出して範囲外の型を渡すと機能したい場合は機能しません. 私が気づいたのは、コードに vec=vec.value という行がなく、範囲を渡すと、次元が 0 になり、独自の関数を作成してチェックしたことです。誰かが私にこの問題を解決する方法を説明してもらえますか? ありがとう。

Public Function cumsum(vec As Variant) As Variant
    Dim temp() As Variant
    MsgBox (getDimension(vec))
    'works if i use vec=vec.value if vec is a range but has 0 if i do not vec = vec.values
    ReDim temp(LBound(vec, 1) To UBound(vec, 1), 1 To 1) As Variant
    Dim intCounter As Integer
    For intCounter = LBound(vec) To UBound(vec)
        If intCounter = LBound(vec) Then
            temp(intCounter, 1) = vec(intCounter, 1)
        Else
            temp(intCounter, 1) = temp(intCounter - 1, 1) + vec(intCounter, 1)
        End If
    Next
    cumsum = temp()
End Function
Function getDimension(var As Variant) As Integer
On Error GoTo Err:
    Dim i As Integer
    Dim tmp As Integer
    i = 0
    Do While True:
        i = i + 1
        tmp = UBound(var, i)
    Loop
Err:
    getDimension = i - 1
End Function
4

3 に答える 3

2

VarTypeTypeNamevecを使用してのデータ型を確認してから、必要な操作を実行してみませんか。vec

Public Function cumsum2(vec As Variant) As Variant
    MsgBox TypeName(vec)
    MsgBox VarType(vec)

    cumsum2 = 0
End Function
于 2012-07-20T16:05:30.883 に答える
1

@Jake と @chris からの回答は正しい方向へのヒントですが、十分に進んでいるとは思いません。

このルーチンを UDF として (つまり、ワークシートの数式から) 呼び出すだけであることが確実な場合は、次のように追加するだけで済みます。

If IsObject(vec) Then
    Debug.Assert TypeOf vec Is Range

    vec = vec.Value2
End If

関数の先頭に。UDF として呼び出され、渡される唯一のオブジェクト タイプは ですRange。また、UDF と呼ばれ、渡された配列には 1 から始まるインデックスが付けられるという事実に依存できます。

私はあなたのルーチンに他の問題を見つけることができますが、それらはあなたの最初の質問の要点から外れます. 簡単に言うと、これは列ベクトルでのみ機能し、単一セル範囲などでは失敗します。

関数がsgetDimensionに対してゼロを返す理由は、範囲が詰まっていることに注意してください。エラー ハンドラーは、実際には予期していなかったエラー (型の不一致) を喜んでキャッチし、0 を返します。(「次元」を見つける方法は、エラーが添字の範囲外エラーになると想定しています。)RangeUBound

getDimensionExcel を使用する場合、一般的なアプローチが良いとは思わない理由を説明する回答をしばらく前に書きました。

https://stackoverflow.com/a/6904433/58845

最後に、問題VarTypeは、既定のプロパティを持つオブジェクトを渡すと、実際にはプロパティの型を返すことです。VarType(<range>)は、オブジェクトのコードではなく、範囲内のもののタイプを示します。これはRange、デフォルトのプロパティRange.Value.

于 2012-07-21T18:58:20.757 に答える
0

getDimension含めるように変更します

If TypeName(var) = "Range" Then
    var = var.Value
End If
于 2012-07-20T22:11:41.020 に答える