#3です。
補足:
>SUM関数と全く同じものをVBAでつくるとどのような式(?)になるのでしょうか?
私は、読み落としていたけれども、「まったく同じもの」というのは、遥か先の話ですね。
少なくとも、「初心者」という銘を打っている限りは、難しいです。以下ですと、私が、何年か前に書いたもので、中級レベルの技術で書かれたものです。
例えば、このような計算が可能です。
A1~A9 まで、1,2,3,4,5,6,7,8,9 と入れておいて、
=MYSUM(A1:A9+1)
とし、配列の確定(F2を押して、『ShiftとCtrlを押しながらEnterキー』を押す)で、「54」という答えが出せます。中身は、2,3,4,5,6,7,8,9,10 と計算したものと同じです。
VBAのプログラミングの本質的なところは、初級も上級も変わらないのですが、エラー対策を施せるようになると技術的に上になっていきます。エラー対策など必要がないと思っている限りは、なかなか上に上がっていきません。
SUM関数と同じようなエラーが出で来るはずです。ただ、完全に、エラーを排出できるわけではありません。例えば、[循環参照ダイアログ]の呼び出しが出来ません。#VALUE! エラーになるだけです。
このコードは、最初に、関数を入れて、入れた状態で、Ctrl + A のショートカットで、SUMと同じように出てくるかどうか、というところから始まっています。それから、[チップ・テキスト(クリーム色のヘルプメッセージ)]は出てきません。
それと、少しVBAやExcelを詳しい人ですと、揮発性(Volatile)とか不揮発性とか言う人がいます。簡単に、Volatile メソッドを入れればよいと思っている人もいるようですが、それは、少し考え違いをしています。それは、実際、引数の変化によって、値が変わればよいのですから、必ずしも、Volatile メソッドは必要がないのです。
'------------------------------------------------------
Public Function MySum(数値1 As Variant, ParamArray 数値2() As Variant) As Variant
Dim dblTotal As Double
Dim ar As Variant
Dim c As Variant
Dim Arg As Variant
Dim Args() As Variant
Dim fml As String
Const vbMyError As Integer = 513
On Error Resume Next
fml = Application.Caller.FormulaR1C1
On Error GoTo ErrHandler
If InStr(fml, "RC") > 0 Then
Err.Raise vbMyError 'すべての循環参照は検出できない
ElseIf InStr(fml, "R") = 0 And InStr(fml, "C") = 0 Then
Err.Raise vbMyError + 1
End If
If TypeName(数値1) = "Range" Then
Set Arg = 数値1
For Each c In Arg
If VarType(c) = vbDouble Then
dblTotal = dblTotal + c.Value
End If
Next c
ElseIf TypeName(数値1) = "Double" Then
Arg = 数値1
dblTotal = dblTotal + Arg
ElseIf UBound(数値1, 1) > -1 Or UBound(数値1, 2) > -1 Then
Arg = 数値1
'配列時の計算
For Each c In Arg
dblTotal = dblTotal + c
Next c
MySum = dblTotal
End If
If Not IsMissing(数値2) Then
Args() = 数値2
ElseIf UBound(数値2) = -1 Then
'配列が確保されていない時の離脱条件
MySum = dblTotal
Exit Function
End If
For Each ar In Args()
If TypeName(ar) = "Range" Then
For Each c In ar
If VarType(c) = vbDouble Then
dblTotal = dblTotal + c.Value
End If
Next c
ElseIf TypeName(ar) = "Double" Then
dblTotal = dblTotal + ar
End If
Next ar
MySum = dblTotal
Exit Function
ErrHandler:
'エラー処理
If Err.Number = vbMyError Then
MySum = CVErr(xlErrValue)
ElseIf Err.Number = vbMyError + 1 Then
MySum = CVErr(xlErrName)
ElseIf IsError(数値1) Then
MySum = CVErr(数値1) '←この部分は検証されていない
End If
End Function
お礼
解りやすい解説ありがとうございます この一連のやりとりは この先何度も見直すとおもいます。 貴重な時間を割いていただいて本当にありがとうございました。