シート関数・VBA関数
Excelの新関数には便利なものがたくさんありますが、XLOOKUPは2021以降、TEXTAFTER/BEFOREは2024以降でないと#NAME?エラーになってしまいます。これを365ユーザー側で検知するためにリスト化するマクロを紹介します。
文字列型になっている数値をInteger型(整数型)に変換する、CInt関数について説明します。本関数はCLng関数の完全下位互換ですので、よほどのことがない限りは使用しないと思います。
文字列型になっている数値をLong型(長整数型)に変換する、CLng関数の使い方を解説します。数値型に変換する以外にも、Integer型のオーバーフロー問題への対応や、文字列型同士の足し算問題の対応でも使用します。
VBAの組み込み関数である、CStr関数とStr関数の違いを解説します。どちらも値を文字列(String型)に変換する関数ですが、Str関数は少し特殊な仕様を持っている関数ですの、基本的にCStr関数を使っておけばOKです。
Str関数は数値を文字列(String)型に変換する関数とありますが、実際はBoolean型やDate型も文字列に変換します。正の値に半角スペースを入れるなど不要な挙動も多いので、文字列変換には素直にCStr関数を使いましょう。
数値などの値を文字列型に変換する、CStr関数の使い方を解説します。といってもVBAには暗黙の型変換機能があるため、文字列が必要な場面では自動で文字列に変換してくれます。使う場面は少ないかもしれません。
TypeName関数とVarType関数の違いを解説します。どちらも変数や値のデータ型を調べるための関数ですが、返り値のわかりやすさとオブジェクトの判定機能の分TypeName関数が完全上位といってよいです。
値が何型かどうかを調べる方法のひとつにVarType関数がありますが、「普通にデータ型を調べる分にはTypeNameの下位互換」な関数ですので、ただデータ型を調べたいだけならTypeName関数をご使用ください。
変数や値が何型の変数(As ○○)かを調べるにはTypeName関数を使用します。TypeName関数は何型で宣言されているかではなく、今なんの型が入っているかを判定してくれる上、NotingやEmptyの判定も可能です。
変数や配列の要素がオブジェクトかどうかを調べるIsObject関数を解説します。変数の型が決まっている場合は中身の有無にかかわらずその型に応じた結果となるため、実際はVariant変数の中身を判定する関数です。
Transpose関数と、同じ処理を愚直にFor文で代入する方法の速度比較を行いました。結果は愚直に代入した方が早かったですが、両方とも十分高速なため、よほどの規模を相手にしない限りは誤差の範囲と思ってよいようです。
Transpose関数は配列の要素数が65,537を超えると要素をエラーもなく破棄してしまう仕様があります。配列をセルに出力したときなぜか#N/Aエラーになる現象などはこの仕様による不具合を疑ってください。
配列の要素数を求める方法を解説します。最大要素番号を求めるUbound関数と、最小要素番号を求めるLbound関数を用いて、「Ubound - Lbound + 1」で求めます。二次元配列の場合は各次元を第2引数で指定します。
「あああ」や「AAA」など同じ文字を繰り返した文字列を作りたいときは、String(繰り返し回数, 繰り返す文字)で生成できます。繰り返す文字が複数の場合は、WorksheetFunction.Rept関数の方を使用してください。
IsArray関数は変数などが配列かを調べる関数ですが、Rangeオブジェクトに対してもTrueを返すという性質があります。IsArrayがTrueなのにUbound/Lboundがエラーになるなどにお悩みの方はこの仕様を疑ってください。
変数が配列か調べるには、IsArray関数を使用します。この関数は変数に限らず、関数の返り値や、配列を取得するプロパティも判定してくれます。一点、Rangeに対してもTrueになる点だけ注意して使ってください。
5行かかるIf~Else~EndIfの分岐を1行で済ますIIf関数はとても便利なのですが、若干遅いためそれを検証してみます。結論としては、IIfが条件がTrueでもFalse部分も計算してしまうという遅さがあるが、それを除けば実務上実感できる差は出ません。
「+」を文字列に対して使うと連結演算子(&と同じ)になります。足し算の結果がかなり大きな誤った値になったり、セルの表示書式を「文字列」にすると正しく計算されないような不具合が発生した場合は、この仕様を疑ってください。
現在時刻を取得するTime関数とTimer関数の違いを解説します。単位(型)と精度が異なります。Time関数がDate型で表示形式や各種関数に利用できるのに対し、Timer関数は1/00秒まで計測できるSingle型のため、実行速度計測などに向いています。
文字列が文字列を含んでいるかどうかを判定する2つの方法「Instr関数/Like演算子」について、どちらが早いかを検証しました。Like演算子が安定して速かったですが、最終結論は「どちらも十分早いので書きやすい/読みやすい方を使えばよい」です。
マクロの処理時間を計測する方法を解説します。現在時刻を約ミリ秒単位で取得するTimer関数を使うと簡単に取得することができます。開始時刻 = Timerと、終了時刻 = Timerをマクロに設置し、終了時刻 - 開始時刻を計算することで取得できます。
検索によく用いられるFindメソッドさんですが、実は危なくて遅い地雷メソッドです。非表示セルを見つけられない、ユーザーと設定を共有する、MATCH関数より十数倍レベルで遅い、の三重苦なので、なるべく使わないようにしましょう。
Functionプロシージャの名前に句読点を使用すると、ワークシート上でユーザー定義関数として呼び出せなくなります。読点「、」とカンマ「,」、句点「。」とピリオド「.」が自動変換されることが原因のように思えますが定かではありません。
ExcelVBAにおいて文字列を置換する処理に使う、Replace関数とReplaceメソッドの違いを解説します。Replace関数には、「シート関数のREPLACE」と、「VBA関数のReplace」の2つがありますので、ここでは3つのReplaceについて解説します。
WorksheetFunctionはとても便利ですが、コードが長いという弱点があります。そこで、WorksheetFunctionオブジェクトをそのまま返すだけの関数をWfやFxなど短い関数名で作っておけば、その関数名だけでWorksheetFunctionを呼び出せます。
あいまい検索に使用するワイルドカード「*」と、掛け算に使用する「*」は同じ文字です。よって、掛け算を置換する際に、「*」も含めた置換をすると、*の部分は任意の文字列のため、置換が暴走します。「~*」とすることで、記号をターゲットに置換できます。
セルの数式をVBAで入力するための「Formulaプロパティ」の使い方を解説します。Range("D10").Formula = "=SUM(D4:D9)"のように、数式をRangeオブジェクトのFormulaプロパティに代入することで、数式をVBAから入力することができます。
ワークシート関数をVBA上で計算するWorksheetFunctionオブジェクトの使い方を解説します。自分でコードを書くと大変だけど、関数だと1発で書けるというメリットに加え、シート関数は自分で書くより圧倒的に高速です。積極的に使っていきましょう。
VLOOKUPの高速化手法は、《簡単》データが連続していることを活用した計算スキップ法と、《超高速》ソート済であることを活用した近似一致法の2種類があります。どちらも使いこなせばとても便利ですので、是非習得していってください。
数式を値に固定したあと、#N/Aエラーを消去するマクロを紹介します。何がやりたいかは明らかですね(笑)お忙しい方は、ソースコードをコピーして、使い方例のように実行しちゃえばOKです。コードをしっかり読みたい方は、解説もどうぞ。