Excelのユーザ定義関数をVBA無しで作る

Spreadsheets/Excel Advent Calendar 2019の昨日(18日目)の枠が空いていたので,またネタを書いてみます.

Excelのユーザ定義関数をVBA無しで作るのってできるのか?

2019年12月現在,Office 365またはOffice Onlineであれば,Officeアドインを使ってJavaScriptでユーザ定義関数を作れます. (参考: Excel でカスタム関数を作成する - Office Add-ins | Microsoft Docs

ただし,npmを入れてJavaScriptで書くので,慣れない人には若干ハードルがありそうです. また,Excel 2019などは未対応です.

それ以外の方法,VBAJavaScriptも使わないでユーザ定義関数を作る方法は無いのかというと, かなり制限付きであるにはあります.

数式に名前

まず定番(?)なのは,数式に名前を付けて関数の代わりにする方法です.

例えば,B1セルを選択した状態で,「名前の管理」>「新規作成」をクリックし, 「名前」にADDONE,「参照範囲」に=!A1+1と入力します.

ここで,参照の前に!を付けてシートの限定を防ぐことと,$はつけない相対参照にすることがミソです. というのは,単にクリックで=A1と指定しようとすると,勝手に=Sheet1!$A$1などと変換されて,「特定のシートの,特定のセル」に参照先が限定されてしまいます.

これで,B1セルに=ADDONEと入れると,A1セルの値に1加算された結果が返ります.

f:id:kamocyc:20191219072807p:plain

別のセルに=ADDONEと入れても,常に左隣のセルの値に1加算された結果が返ります.また,ADDONEの結果をそのまま数式で利用することも可能です.

f:id:kamocyc:20191219072927p:plain

FORMULATEXT + REPT("...",0) でうまいことやる

でもこれだと関数の引数を常に別のセルに入れないといけないので,使いづらいですね.

ということで,はい.このサイト (microsoft excel - Custom user function without using VBA - Super User) に書いている人がいました.

仕組みを理解するには,一番わかりやすいのはこの人がリンク貼っているDropboxからExcelファイルを落としてきて,数式の検証でステップ実行すればいいのですが,簡単に解説すると,

  1. =TCase&REPT("これが引数",0)と数式を入れる
  2. TCaseの名前の定義の参照範囲(数式)の中で,FORMULATEXT(INDIRECT("rc",0))により,「自身のセルの数式」を取得
  3. 「自身のセルの数式」から,SEARCH関数やMID関数で,"これが引数"の部分を抽出
  4. 抽出した引数を使って何かしら処理する(TCaseではSUBSTITUTE).ここまでTCaseの定義の中でやっている.
  5. REPT("これが引数",0)自体は「0回繰り返し」なので空文字列になって,結果に影響しない.

という感じです.

とても賢いやり方ですが,数式の書き方が=TCase&REPT("これが引数",0)という形式である必要があり,結果を更に計算につかうとかを同じセルでできないのが難点です. また,2引数以上だと修正が必要です.

EVALUATE

ExcelにはEvaluate関数という文字列の数式を評価する関数があります.

ただ,普通にセルに関数を入れても使えなくて,先ほど解説した数式に名前をつけるやり方でないと使えません.

このリンク先に全部書いてありました: Office TANAKA - Excel Tips[セルに入力した数式を別のセルで計算する]

EVALUATE関数の実行はVBAと同じ扱いになるので,マクロ有効ブックで保存する必要があります. なので,VBAを使わないことのメリットは小さいかもしれません.

まとめ

VBAを使えるなら使うのが楽.