• ベストアンサー

配列を返すVBAユーザー定義関数の書き方

VBAで、商と余りを返す整数割算のユーザー定義関数を書こうとしています。セルA1に割られる数、B1に割る数が書いてあり、C1とD1に「=xdiv("A1:B1")」をCtrl+Shift+Enterで入力します。C1に商、D1に余りを返すようにしたいと思ってます。 以下のように書いてみたのですが、戻り値の書き方がどうもよくわかりません… Function xdiv(ByRef d() As Integer) As Integer   ............. End Function よろしくお願いします。

  • zuntac
  • お礼率81% (307/377)

質問者が選んだベストアンサー

  • ベストアンサー
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

こんにちは。 Function Xdiv(arg As Variant) As Integer() '配列出力の方法 Dim Divd As Double '被除数 Dim Divsr As Double '除数 Dim ret(1, 0) As Integer If TypeName(arg) = "Range" Then  Divd = arg.Cells(1)  Divsr = arg.Cells(2) ElseIf TypeName(arg) = "Variant()" Then  Divd = arg(1)  Divsr = arg(2) End If  ret(0, 0) = Divd \ Divsr  ret(1, 0) = Divd Mod Divsr  Xdiv = ret() End Function >C1とD1に「=xdiv("A1:B1")」をCtrl+Shift+Enterで入力します。 正確には、この式をC1に入れて、次に、範囲をD1にまで伸ばしてから、Ctrl + Shift + Enter で確定します。念のため、解除の仕方は、同じく範囲を選択してから、F2 を押してから、Ctrl + Enterです。 なお、これは、\, Mod を使っていますから、Long型以上の解は出てきません。また、二つ以上のセルを入れても、最初のセルと次のセルしか引数として使われません。

zuntac
質問者

お礼

回答ありがとうございます。 ElseIf TypeName(arg) = "Variant()" により{=Xdiv({523,3})}という書き方にも対応できるということですね。勉強になりました。

その他の回答 (2)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

Public Function xdiv(a As Long, b As Long) Dim ret(2) Dim q As Long, r As Long q = Fix(a / b) r = a - b * q ret(0) = q ret(1) = r xdiv = ret End Function 'この場合、望むような結果になるのは、横方向です

zuntac
質問者

お礼

回答ありがとうございます。 以下の内容で解決することができました。 エクセル側 C1,D1セル {=xdiv(A1:B1)} VBA側 Public Function xdiv(ar As Variant) As Variant   Dim ret(2) As Variant   xdiv = Array(Int(ar(1) / ar(2)), ar(1) Mod ar(2)) End Function

  • o_chi_chi
  • ベストアンサー率45% (131/287)
回答No.1

関数は設定したセルにしか結果を返せないと 思うのですが。 パラメタにするか関数を分けるかになるかと 思います。

zuntac
質問者

お礼

回答、ありがとうございます。 でも、TRANSPOSE()関数などは結果を配列で返しているので仕組みとしては存在してると思うのですが… それをなんとかVBAで書きたいと思ってます。

関連するQ&A

  • VB2005での関数への配列の参照渡しの方法

    Visual Basic 2005で、 =============================================================== Function func(ByVal a As Integer, ByRef b() As Integer) As Integer  a += 1 : b(0) = 1 : b(1) = 2 : b(2) = 3 Return 0 End Function ============================================================== という関数があったとしてメインのプロシージャに ================================================================ Dim c As Integer Dim d As Integer Dim e() As Integer = Array.CreateInstance(GetType(Integer), 10) d=7 c = func(d, e) ================================================================ と書き入れると結果はd=7(∵値渡し)、e(0)=1,e(1)=0,e(2)=0(∵参照渡し)となってしまうと思います。 e(0)=1,e(1)=2,e(2)=3としたい場合はどのように記述すればよいのでしょうか?

  • EXCEL VBA ユーザー定義関数について。

    EXCEL VBA ユーザー定義関数について。 例) FUNCTION Test(a as integer, b as integer,c as integer) as integer とした場合、に添付図のような   =Test(数値1, 数値2, 数値3) のような説明は表示できないのでしょうか? ご存知の方よろしくお願いします。

  • Functionの戻り値を配列にしたいのですが

    vbを始めたばかりですがよろしくお願いします。 Functionの戻り値を配列にしたいのですが Function fnc(ByVal a As Byte, ByVal b As Byte) As Integer() fnc(0) = a + b fnc(1) = a - b End Function というような使い方はできないのでしょうか? 一つのFunctionで二つの計算結果をかえすには どうしたらよいのでしょうか? お願いします。

  • VBAのマクロをシート内の式で使いたい

    VBAで、マクロの関数をエクセルの式で使うことは可能でしょうか? 引数や戻り値の制約も知りたいです。 引数はExcel側ではセル値B1とかになりますが、VBA側では何か対策でもあるのでしょうか? 'VBA public function test(byval a as integer, byval b as integer) as integer test = a + b end function 'エクセル側 C1セルに以下の式 =test(A1, B1)

  • ユーザー定義関数について

    ユーザー定義関数について VBA初心者です。画像1は正常、画像2に変更したときに空白レコードに#エラーが出るようになってしまいました。変更点は、ByVal gと(1)削除したのですが、どのような式を入れれば良いのでしょうか。宜しくお願い致します。 画像1: (正常です) link(T_photo!photo1,T_photo!folder1,T_photo!folder2,T_photo!folder3,T_photo!year,T_tag!domain,T_photo!folder4) Public Function link _ (ByVal a, ByVal b, ByVal c, ByVal d, ByVal e, ByVal f As String, ByVal g) As String link = IIf(Trim("" & a) = "", "", _     (1) IIf(Trim("" & b & c & d & e & a) = "", "", "" & f) & _ IIf(Trim("" & b) = "", "", "" & b & "/") & _ IIf(Trim("" & c) = "", "", "" & c & "/") & _ IIf(Trim("" & d) = "", "", "" & d & "/") & _ IIf(Trim("" & e) = "", "", "" & e & "-link/") & _ IIf(Trim("" & a) = "", "", "" & g & "-" & a)) 画像2: (#エラー) link_ec(T_photo!photo1,T_photo!folder1,T_photo!folder2,T_photo!folder3,T_photo!year,T_photo!folder4) Public Function link_ec _ (ByVal a, ByVal b, ByVal c, ByVal d, ByVal e, ByVal f As String) As String link_ec = IIf(Trim("" & a) = "", "", _ IIf(Trim("" & b) = "", "", "" & b & "/") & _ IIf(Trim("" & c) = "", "", "" & c & "/") & _ IIf(Trim("" & d) = "", "", "" & d & "/") & _ IIf(Trim("" & e) = "", "", "" & e & "-link/") & _ IIf(Trim("" & a) = "", "", "" & f & "-" & a))

  • ユーザ定義関数の引数省略について

    VBAで自分で関数を作成しているのですが、 引数を複数省略したいときはどうすれば良いでしょうか? 例えば、Test(A as integer, Optional B as integer =1, Optional C as integer =1)という関数で Test(1,0)と記述した時に"0"は引数BなのかCなのかどうやって指定するのでしょうか? それとも複数省略は出来ないのでしょうか?

  • 余りの定義について

    余りについてなんです。多項式について割り算の定義は理解しているんですが、普通の数の割り算について割られるかずが負のとき、その余りについて負も許容すると二通り以上作れませんか?それって多項式の時の割り算の定義である、商と余りは商の次数>あまりの次数の時、一通りであることに矛盾しませんか? 例えば-21=5×-(4)+(-1)=5×(-5)+4=5×(-3)+(-6) しかし合同式の定義によれば余りは負も許容してますよね? これはどういう事なんでしょうか。 よろしくお願いします。

  • 配列を引数で渡したりするには?

    初心者なので困っています。配列をほかのサブルーチンへ渡して、その中で配列の値を書き換えて、上層のルーチンへ渡すにはどうしたらよいのでしょうか? 初心者なので、みなまさまのお知恵を拝借させてください。よろしくお願いします。 Private Sub Print() Dim C_ALL(3) As Integer Dim D_ALL(3) As Integer Data_Set(C_ALL(), D_ALL()) MsgBox(C_ALL() & " " & D_ALL()) '配列内容すべて表示 End Sub Private Sub Data_set(ByRef C_ALL As Integer, ByRef D_ALL As Integer) Dim i As Integer For i = 0 To 4 C_ALL(i) += i D_ALL(i) += i i += 1 Next End Sub

  • VBAの配列

    VBAの配列の処理でこまっています。 dim test as Variant test = Array( _ Array("Aさん", 65, 70, 45), _ Array("Bさん", 80, 10, 90)) とした成績データがありまして、あとから(定義の段階でなく)、"Cさん", 70, 70, 75をtest変数に追加したい場合、どのようにすればよいのでしょうか? また、これ(test)を戻り値にした場合、正しく左辺値にはいるのでしょうか?オブジェクトの解放などの問題も知りたいです。 function seiseki () as variant ... 上の処理 seiseki = test end function ...  dim cp as Variant cp = seiseki() 'cp変数にコピーされるのでしょうか?

  • Excelマクロで定義の関数実行結果が#VALUE

    以前にマクロの記述について教えて頂いた件の再度の質問になります. Excelマクロで複素数を扱う関数を下記HPから標準モジュールに コピペしました.今度は正しくコピーできていると思います. しかし,計算結果がどうしても「#VALUE!」となってしまいます.何故でしょうか? どなたか助けて頂けませんか! http://www.geocities.jp/tomtomf/denki/AC2/ac2.htm http://www.geocities.jp/tomtomf/denki/AC1/ac1.htm 今回は関数定義の「 IMMULT」関数に関する部分に絞っています. ここまで絞ってもエラーになるのは,単純な問題なのでしょうか? 行列の積を求めるマクロの手順にも問題はなさそうです. Public Function IMPRODUCTa(ParamArray a()) As Variant IMPRODUCTa = Application.Run("atpvbaen.xlam!IMPRODUCT", a) End Function Public Function IMSUMa(ParamArray a()) As Variant IMSUMa = Application.Run("atpvbaen.xlam!IMSUM", a) End Function Public Function IMMULT(a As Range, b As Range) As Variant Dim r1 As Integer, r2 As Integer, c1 As Integer, c2 As Integer, nn As Integer Dim r As Integer, c As Integer Dim cr As Integer, cc As Integer Dim n As Integer Dim mm() As Variant r1 = a.Rows.Count r2 = b.Rows.Count c1 = a.Columns.Count c2 = b.Columns.Count If c1 = r2 Then nn = c1 Else Exit Function End If cr = r1 cc = c2 ReDim mm(1 To cr, 1 To cc) For r = 1 To cr For c = 1 To cc mm(r, c) = 0 For n = 1 To nn mm(r, c) = IMSUMa(mm(r, c), IMPRODUCTa(a.Cells(r, n), b.Cells(n, c))) Next Next Next IMMULT = mm End Function

専門家に質問してみよう