Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


8225 / 13644 ツリー ←次へ | 前へ→

【34472】返り値が複数のユーザーファンクション sheboygan 06/2/3(金) 12:48 質問[未読]
【34475】Re:返り値が複数のユーザーファンクション inoue 06/2/3(金) 13:11 発言[未読]
【34545】Re:返り値が複数のユーザーファンクション sheboygan 06/2/6(月) 11:24 お礼[未読]
【34479】Re:返り値が複数のユーザーファンクション ichinose 06/2/3(金) 13:17 発言[未読]
【34546】Re:返り値が複数のユーザーファンクション sheboygan 06/2/6(月) 11:27 お礼[未読]
【34548】Re:返り値が複数のユーザーファンクション sheboygan 06/2/6(月) 13:43 質問[未読]
【34549】Re:返り値が複数のユーザーファンクション Blue 06/2/6(月) 14:15 発言[未読]
【34550】Re:返り値が複数のユーザーファンクション ごんぼほり 06/2/6(月) 14:28 回答[未読]
【34552】Re:返り値が複数のユーザーファンクション sheboygan 06/2/6(月) 15:16 お礼[未読]
【34482】Re:返り値が複数のユーザーファンクション Kein 06/2/3(金) 13:59 回答[未読]
【34547】Re:返り値が複数のユーザーファンクション sheboygan 06/2/6(月) 11:35 お礼[未読]

【34472】返り値が複数のユーザーファンクション
質問  sheboygan E-MAIL  - 06/2/3(金) 12:48 -

引用なし
パスワード
   ファンクションは、基本的に返り値がひとつですが、複数の値を返り値に持つようなユーザーファンクションを書くことは可能でしょうか?組み込み関数のfrequencyのように、範囲を指定してファンクションを書くと、その範囲の中に複数の数値を返すというようなものです。fortranのサブルーチンでは、こういうことが可能でしたが、VBAのファンクションでは可能でしょうか?ユーザーファンクションでなくても、このような趣旨のことができる簡単な方法はありますか?

【34475】Re:返り値が複数のユーザーファンクション
発言  inoue E-MAILWEB  - 06/2/3(金) 13:11 -

引用なし
パスワード
   >複数の値を返り値に持つようなユーザーファンクション
変数としては1つですが、配列を返すことができます。
' 呼び出す処理
Sub TEST()
  Dim vntRet As Variant, IX As Integer
  vntRet = fncTEST(7) ' ここで呼ぶ
  If IsArray(vntRet) Then
    IX = 0
    Do While IX <= UBound(vntRet)
      Debug.Print vntRet(IX)
      IX = IX + 1
    Loop
  End If
End Sub

' 配列を返す関数(処理は適当)
Function fncTEST(intCnt As Integer) As Variant
  Dim vntTbl() As String, IX As Integer, IX2 As Integer
  Dim vntVal As Variant
  vntVal = Array("A", "B", "C")
  ReDim vntTbl(intCnt)
  IX = 0
  Do While IX <= intCnt
    IX2 = IX Mod 3
    vntTbl(IX) = vntVal(IX2)
    IX = IX + 1
  Loop
  fncTEST = vntTbl
End Function


あと、Functionにしなくても、
引数をByRefで必要数宣言しておいて、
呼び出された方が引数に値をセットさせて返す方法もあります。

【34479】Re:返り値が複数のユーザーファンクション
発言  ichinose  - 06/2/3(金) 13:17 -

引用なし
パスワード
   ▼sheboygan さん:
こんにちは。

>ファンクションは、基本的に返り値がひとつですが、複数の値を返り値に持つようなユーザーファンクションを書くことは可能でしょうか?組み込み関数のfrequencyのように、範囲を指定してファンクションを書くと、その範囲の中に複数の数値を返すというようなものです。fortranのサブルーチンでは、こういうことが可能でしたが、VBAのファンクションでは可能でしょうか?ユーザーファンクションでなくても、このような趣旨のことができる簡単な方法はありますか?
Functionがかえす値を配列にすると可能です。
一例ですが
標準モジュールに
'==========================================
Function funcarray()
  Dim rng As Range
  If TypeName(Application.Caller) = "Range" Then
    Set rng = Application.Caller
    With rng
     ReDim myarray(1 To .Rows.Count, 1 To .Columns.Count)
     For idx = 1 To .Rows.Count
       For jdx = 1 To .Columns.Count
        myarray(idx, jdx) = idx * 2 + jdx
        Next jdx
       Next idx
     End With
    funcarray = myarray()
    Erase myarray()
    End If
End Function


として、

適当なシートのセルA1:C3を選択します。
選択した状態で数式バーに
「=funcarray()」と指定します(両端の「」は除く)。

確定は、Enterキーではなく、
Ctrl+Shift+Enterキーで確定します。

各セルに違う値が設定されます。

確認してください。

【34482】Re:返り値が複数のユーザーファンクション
回答  Kein  - 06/2/3(金) 13:59 -

引用なし
パスワード
   "仮引数"を使う方法もあります。以下の Sub Test_Func() を実行してみて下さい。
「定数 MyStr の文字数、全てを小文字にしたときの文字列、全てを大文字にしたときの
文字列」を一気に返します。

Sub Test_Func()
  Dim i As Integer
  Dim St2 As String, St3 As String
  Const MyStr As String = "VBA And Excel"

  i = Exec_Func(MyStr, St2, St3)
  MsgBox "文字数 : " & Len(MyStr) & vbLf & _
  "小文字変換 : " & St2 & vbLf & "大文字変換 : " & St3
End Sub

Function Exec_Func(A As String, B As String, C As String) As Integer
  Exec_Func = Len(A)
  B = StrConv(A, vbLowerCase)
  C = StrConv(A, vbUpperCase)
End Function

【34545】Re:返り値が複数のユーザーファンクション
お礼  sheboygan E-MAIL  - 06/2/6(月) 11:24 -

引用なし
パスワード
   ▼inoue さん:
回答ありがとうございます。
要は、配列にデータを格納したら、それをFunction名に代入する、
ということでしょうか?
まだ確認していないのですが、こんな解釈でいいのかと単純に考えています。

ありがとうございました。

【34546】Re:返り値が複数のユーザーファンクション
お礼  sheboygan E-MAIL  - 06/2/6(月) 11:27 -

引用なし
パスワード
   ▼ichinose さん:
回答ありがとうございます。
大体わかりましたが、またわからないことがあれば、このツリーに書きますので
よろしくお願いします。

【34547】Re:返り値が複数のユーザーファンクション
お礼  sheboygan E-MAIL  - 06/2/6(月) 11:35 -

引用なし
パスワード
   ▼Kein さん:
回答ありがとうございます。
Functionは、エクセルのワークシートから直接引用する形での使い方を考えています。つまり、セルN個を指定して、その下あるいは隣のN個のセルに、関数の計算結果を返すというようなものです。
また、よろしければ、ご教示ください。

【34548】Re:返り値が複数のユーザーファンクション
質問  sheboygan E-MAIL  - 06/2/6(月) 13:43 -

引用なし
パスワード
   ▼ichinose さん:
先ほど、ご教示いただいたfunctionを参考に、以下のような関数を書いてみました。

Function arraytest(rng As Range)
ReDim out(1 To rng.Rows.Count)
For idx = 1 To rng.Rows.Count
  out(idx) = rng(idx) * idx
Next idx
arraytest = out
End Function

たとえば、A1:A5を引数にして、B1:B5にFunctionの計算結果を出力したいのですが、計算結果が全てout(1)の値になってしまいます。
なぜでしょうか?

【34549】Re:返り値が複数のユーザーファンクション
発言  Blue  - 06/2/6(月) 14:15 -

引用なし
パスワード
   ワークシート関数として複数の値を返すことはできないのでは?
~~~~~~~~~~~~~~~~~~

例えば、

B1 に =FUNC(A1:A5)

としたら、B1にしか結果は入れれません。(他はどこに入れるかわからない)
FUNCが配列を返すようになっている場合、先頭の値だけB1に入れられます。

B1 に =FUNC(A1:A5)
B2 に =FUNC(A1:A5)
B3 に =FUNC(A1:A5)

としているのならば、それは当然の動作です。
入力と出力するセルを引数にして、マクロ内部でそのセルに反映させることはできます。

B1 に =FUNC(A2:A6,B2:B6)

として、

Private Function FUNC(ByVal r1 As Range, ByVal r2 As Range)
   ' (省略)
End Sub

みたいに。

【34550】Re:返り値が複数のユーザーファンクション
回答  ごんぼほり  - 06/2/6(月) 14:28 -

引用なし
パスワード
   こんにちは。

>たとえば、A1:A5を引数にして、B1:B5にFunctionの計算結果を出力したいのですが、計算結果が全てout(1)の値になってしまいます。
>なぜでしょうか?

配列が
>ReDim out(1 To rng.Rows.Count)
と宣言しているからです。1次元配列は、行ベクトルだとみなされます。

ReDim out(1 To rng.Rows.Count,1 to 1)
と宣言して、
out(idx,1) = rng(idx) * idx
にしてください。

【34552】Re:返り値が複数のユーザーファンクション
お礼  sheboygan E-MAIL  - 06/2/6(月) 15:16 -

引用なし
パスワード
   ▼ごんぼほり さん:
ありがとうございました。
おっしゃるとおりにしたところ解決しました。
これで目的を達成しました。
ありがとうございました。

8225 / 13644 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free