いかたけの備忘録

忘れっぽい

VBAで自作関数の引数にセルの値を指定するときに良い感じにしたい。

この記事はSpreadsheets/Excel Advent Calendar 2018の10日目の記事です。https://adventar.org/calendars/3080

記事のほとんどがSpreadsheetsとライトノベル(?)なのでVBA派は少し肩身が狭いですが、やっていきましょう。ところで楽しく働けるならSpreadsheetsの中でも良いですね。 

さて、記事の内容に入ります。VBAで自作の関数を作る時があり、セルの値を引数に取ることがあると思いますが、このときの工夫について記載したいと思います。

Excelのセルから値を取るときに、取得対象とするセルの数や範囲が不定であるときがあります。この場合、取得するセルの数を別のセルに記載する、といった解決策も考えられますがあまりスマートではありませんね。

「sum関数みたいに、代入する範囲をガーッと指定して動かしたいぜ」という欲求をかなえる方法が、Range型の引数にする。というものです。コードとしては以下のようになります。

Function 連立一次方程式を解く(係数行列 As Range, 定数ベクトル As Range) As Variant

この関数は連立一次方程式をベクトル方程式Ax=bを解く関数になります。係数行列がAで、定数ベクトルがbですね。行列やベクトルの値をExcelのセルに記載して、それらを引数にします。行列・ベクトルの大きさを変更しても、引数の選択範囲を変更するだけで良いので、使う側としては楽になります。

引数として関数内に渡されたRange型のオブジェクトからはこのように値を取り出したりして使っていきます。

For i = 0 To (length - 1)
   For j = 0 To (length - 1)
      a(i * length + j) = CDbl(Cells(係数行列.Row + i, 係数行列.Column + j).Value)
   Next j
Next i
For i = 0 To (length - 1)
   y(i) = CDbl(Cells(値行列.Row + i, 値行列.Column).Value)
Next i

なお、上記で記載したの関数の中身は以下に置いていますので、よろしければご覧ください。

github.com

以上、自作関数の引数にセルの値を指定するときに良い感じにする手法について、記載いたしました。

明日は まだ担当の方がいらっしゃいませんので、ライトノベルの第4話が公開されるかもしれません。お楽しみに。