VBAの関数「Val関数」と、ワークシート関数「VALUE関数」の違いを解説します。
と、その前に。
「Val VALUE 違い」という検索流入があり、
自分も昔同じ勘違いをしていたのでこの記事を書きました。
実は「VALUE」と「Val」は、ほとんど違う関数です。
ワークシートのVALUE関数と対応するVBAの関数は、
Val関数ではなくCDbl関数です。
それを頭の片隅に入れつつ、解説へどうぞ。
同じところ
両者とも「文字列(String)」を「数値(Long,Double)」に変換します。
"123" ⇒ 123 という変換が行われる点は、どちらの関数も同じです。
違うところ ~VALUE、Val、CDbl、CLngの比較表~
冒頭でも書きましたが、↑の単純な変換以外は、
VALUEとValはほとんど違う関数です。
まずは整理するために、主要な「文字列」⇒「数字」の関数を並べてみますね。
- VALUE関数 … ワークシート関数。数値に変換。
- CLng関数 … Long型に変換
- CDbl関数 … Double型に変換
- Val関数 … 無理やり数値に変換
というイメージです。
C○○の関数名が略語なのでわかりにくいですが、
CはConversion(覚えやすければChangeと覚えてもOK)、
LngはLongの、DblはDoubleの母音省略です。
※ 他にCIntとCSngとかもあるけどほぼ使わないと思います。
なんとなく予想できると思いますが、IntegerとSingleに変換します。
さてこれらの違いですが、ずらずら解説を読むより、
いろんな文字列を変換した表を見た方が早いと思います。
百聞は一見に如かず。
※ 型が一致~ は「型が一致しません」エラーの意味です
パッと見でも、Valだけ仲間外れってことが分かると思います。
↑で書いた「Val関数は無理やり数値にする関数」というニュアンスも伝わるでしょうか。
Val関数は「文字列の先頭から、数字以外が出てるくまでの部分を数値化する関数」です。
「123円⇒123」ができる代わりに、「10,000⇒10000」には、できません。
さて、冒頭の通り、VALUE関数とCDbl関数は、ほとんど同じ値を返します。
1/2 ⇒ 2020/1/2 や、5:00 ⇒ 5:00:00 の変換のように、
ワークシート特有の「日付や時刻っぽい文字列を自動変換するおせっかい機能」が、VALUE関数にも備わっているだけで、あとは違いはありません。
この違いなのに、やけにVal関数に知名度があるのは、
- WorksheetFunction.Value が無い!
- WorksheetFunction.Leftがないのと一緒で、同名の関数があるのかな?
- Valってのがあるのか。ふむふむ文字列⇒数字の関数。これだ!
という(私もしていた)勘違いが主な原因と推測します。
ConvDouble関数ならよかったのに、CDblという謎の子音列にしたMSさんのせいでもあると思いますけど。
ワークシート「VALUE関数」 ⇔ VBA「CDbl関数」
が正しい関数の対応ですので覚えておきましょう。
ちなみに、CLng関数もCDbl関数とほぼ一緒ですね。
Longにするとき、切り捨てではなく四捨五入という点だけ注意してください。
使い分け
単純に「数字の文字列」を「数値」にしたい場合
↑に比較した通り、VALUE関数とCDbl関数にはほとんど違いはありませんので、
ExcelとVBAで、この2つを使い分ければOKです。
ついでに四捨五入するならCLng関数を使いましょう。
ただ、ひとつ意識していただきたい点として、
VBAには「暗黙の型変換」があり、変数に代入すれば勝手に変換されます。
Dim Long型の変数 as Long Long型の変数 = "1234"
これでCLngを使わなくても、1234という「数値」がちゃんと変数に入ります。
まちがって文字を入れた時のエラーも全く同じ。
変数の型に合わせて値をしっかり変換しないと代入できない他の言語と違い、
VBAは変数に入れてしまえば勝手に変換されるので、
C○○関数はあまり使う場面は多くないと思います。
1000円から1000を取り出したい
Val関数の用途はこっちになります。
と言いたいところなのですが…
1000円から1000を取り出すシチュエーションを思い浮かべながら、
もう一度比較表を見て見ましょう。
こんな風に困ります。
この緑だけ取り上げて「単位取るのに便利だよ!」とか詐欺やろ…。
特に「桁区切りカンマ」「日本語入力」がアウトなのが致命的ですね。
↑の1000円から1000を取り出すシチュエーションということは、
「セルの書式設定が0"円"になっておらず、円がベタ打ち」されているシートです。
そんなシートで、
日本語入力の「1000円」や、「1,000円」が、それぞれ0と1になる
Val関数は危険すぎて使い物になりません。
しかもエラーが出ないから、予期せぬ問題が発生しても気付けないというおまけ付き。
ガス検知機の切れた停電ガソリンスタンドに、
「これで明るくなるよ!」
とライターを渡して行かせるようなもんです。
残念ですが「Val関数は基本使わない」という方針で行きましょう。
ということで、「数値以外の文字が混じったテキストから数値を取り出す」関数は、
必要に応じて自分で作る必要があります。
私が作った汎用関数
- 123みかん456りんご789 ⇒ 123456789(全部持ってくる)
- 1,100円(税10%) ⇒ 1,100(最初の数値部分だけ持ってくる)
の2パターンが↓の記事にありますので、よろしければどうぞ。