1

特定の状況でエラーをスローする関数があり、その関数を使用したい場合がありますが、特定のユースケースでは、スローを引き起こす状況は実際にはエラー状況ではありません。たとえば、キーと値のセットからエントリを削除する関数があるとします。この関数は、コレクションにそのようなキーが存在しない場合はエラーをスローし、存在する場合は削除された値を返します。多くの場合、それは素晴らしいことですが、特定のケースでは、エントリが存在する場合は削除したい場合があり、存在しない場合は気にしません。

したがって、複数の「On Error」行でコードを散らかします。

' General error handling
On Error GoTo ErrorHandler

' Do some stuff
(...)

' Don't throw an error just because the key doesn't have an entry
On Error Resume Next

' Delete it if it's there
DeletedValue = Delete(Key)

' Go back to regular error handling
On Error GoTo ErrorHandler

' Do some more stuff
(...)

または、小さなラッパー関数を記述します。

Public Function DeleteButDoNotThrowError(ByVal Key As String) As String
    On Error GoTo ErrorHandler

    DeleteButDoNotThrowError = Delete(Key)

    Exit Function

ErrorHandler:
    DeleteButDoNotThrowError = vbNullString
End Function

私は最初の方法が嫌いです - それは私には非常に冗長に汚染されているようです - だから私は通常2番目の方法を使用します. しかし、私が本当に望んでいるのは、そのような方法で関数を使用するたびに、そのようなラッパーを何度も書く必要がないことです。だから私は次のようなものが欲しいです:

Public Function AbsorbErrorString(ByVal CallReturn As String, _
        ByVal ErrorReturn As String) As String
    On Error GoTo ErrorHandler

    AbsorbErrorString = CallReturn

    Exit Function

ErrHandler:
    AbsorbErrorString = ErrorReturn
End Function

次に、(私のファンタジーの世界で)次のように使用できます。

DeletedValue = AbsorbErrorString(Delete(Key), vbNullString)

しかし、もちろん、AbsorbErrorString が Delete を呼び出しているわけではないため、これは機能しません。むしろ、メイン関数が Delete を呼び出しており、それが成功した場合にのみ、メイン関数が AbsorbErrorString を呼び出します。そのため、Delete によってスローされたエラーによって AbsorbErrorString が完全にバイパスされるため、AbsorbErrorString のエラー ハンドラーによってキャッチされません。

比較的クリーンであまり冗長ではない方法で、私が望むようなことを行う方法はありますか?

4

1 に答える 1

0

残念ながら、実行するコードを文字列として渡す以外には不可能です (Daniel Cook が述べたように)。

私が提案できるのは、定型コードを減らすために、2番目の例をより簡単に微調整することだけです。たいしたことではありませんが、VB6 でできることとほぼ同じです。

Public Function SafeDelete(ByRef Key As String) As String
    On Error GoTo ErrorHandler
    SafeDelete = Delete(Key)
ErrorHandler:
End Function

エラーが発生した場合Delete、SafeDelete にはまだ古い値があり、デフォルトは空の文字列です。その後、(空になった) エラー ハンドラを通過しても問題ありません。また、ラップされた関数が ByRef を必要とする場合に備えて、パフォーマンスのために ByVal ではなく ByRef を使用することをお勧めします。(私の同僚の何人かによると、不要な文字列のコピーも保存されます。)

于 2013-01-12T07:10:44.927 に答える