★独学者が1年後にExcelVBAを爆発的に伸ばすための最低限の基礎知識メモ(ダイジェスト):Vol0016:VBAで小数計算ミスをしないようにするために
バックナンバー目次ページは→こちらです。
まぐまぐのページは以下です。
https://www.mag2.com/m/0001691660.html
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■独学者が1年後にExcelVBAを爆発的に上達させるための最低限の基礎知識メモ(ダイジェスト)
Vol.0016
タイトル:VBAで小数計算ミスをしないようにするために
バックナンバー目次とサンプル号
https://euc-access-excel-db.com/tips/ct07_se/ct075012_xls2k_vba_tips/mag2-01
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
前回、パソコンやExcelの小数計算のミス(誤差)は「正常」「あたりまえ」というお話をしましたが、今回はそれについて、色々と補足したいと思います。
「パソコンがバカ」なら、「どうしたらVBAで小数計算ミスをしないようにすることができるのか?」ということの補足です。
まず、Variant型の変数を宣言した時、その変数に小数を代入すると、基本、内部的に、勝手に「Double型」の値に変換されます。
例えば
Dim aaa As Variant
と、変数「aaa」を「Variant型」のデータ型として宣言しておいてから
aaa = 1.4567
などと書いて実行すると、
変数「aaa」は、「Variant型のはずなんですが」
(と表現するよりも、「Variant型の変数であると同時に」という表現のほうが合っているかも)、
内部的に、「Double型」に変換されます。
それはVBEの「ローカルウィンドウ」とF8キーでのステップ実行(1行ずつ、ゆっくり、止まりながら、実行していくこと)で確認できます。
「ローカルウィンドウ」は、VBEにて「表示→ローカルウィンドウ」で表示されます。
ここには、すべての変数の型と中身の値が表示されます。
(オブジェクト変数の場合はその中身のオブジェクトの階層構造もある程度わかりますし、全部ではないですが、各種プロパティの「現在値」もわかります。)
このことを『 実際に目で確認する 』には、VBEにローカルウィンドウを表示しておいてから、例えば以下のプログラムを標準モジュールにコピペして実行してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
' ' Sub testtest001() Dim aaa As Variant aaa = 1.4567 Stop End Sub ' ' |
このコードの場合、「Stop」の行で黄色く反転表示されてプログラムの実行が一時停止されます。
そのタイミングで、ローカルウィンドウを見てみます。
↓こちらの図もご参考にしてみてください。
ローカルウィンドウの「式」の列に「aaa」、
「値」の列に「1.4567」、
「型」の列に「Variant/Double」、
と出ています。
これは
「変数 aaa は」、
「中身の値は 1.4567 で」、
「データ型は 一応 Variant型 なんだけども、内部的には Double型に勝手に変換しちゃったよ!」、
みたいな感じの意味になります。
では、このとき、
「勝手に変換されるのが Double型 だと、計算結果に小数誤差が出ちゃうから、
どうせ内部的に変換されちゃうんなら、
また、小数部分は4桁まで充分だから、
その範囲で誤差の出ない通貨型(Currency)に決め打ちしたい・・・
Variant型であっても・・・・。」
という場合、どうすればよいでしょうか?
そのほか、
「基本、VariantでDoubleに内部変換されちゃってもいいんだけど、
このときだけは明示的にCurrencyにしたい!」
という場合等々もです。
そのような場合は、以下のようなプログラムにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
' ' Sub testtest001() Dim aaa As Variant aaa = 1.4567@ Stop End Sub ' ' |
「aaa = 1.4567」
の行に
「@」
を付け加えて
「aaa = 1.4567@」
とするだけです。
これで、変数aaaは、
「Variant型なんだけど、内部的には通貨型(Currensy)だよ!」
ということになります。
Stopでプログラムがいったん停止したときに、ローカルウィンドウをチェックしてみてください。
「式」:aaa
「値」:1.4567
「型」:Variant/Currency
となっているはずです。
「1.4567」に「@」を付加したことで、付加しなければ自動的にDouble型に内部変換されてしまうところを、ムリヤリ、Currency型に内部変換させています。
以上のように、VBAなどで「数値」を扱う場合は、
(文字列や日付には今回のことはあてはまりません)
「Variant型の変数を使った場合」や、
「変数を使わずに直書きで計算をしたい場合」
などに、
前述の「@」のような記号を使うと、
「思いどおりの型」に「変換」あるいは「明示的な指定」が、できます。
これは小数だけでなく、整数でも同じようなことができます。
このような「@」のような記号のことを
「型文字」
とか、
「型宣言文字」
というそうです。(存在は知っていましたが、呼び方を知りませんでした。)
VBAの場合は「型宣言文字」と呼ぶことが多いらしいですね。
※参考
『 VBE 用語集 』
https://docs.microsoft.com/ja-jp/office/vba/language/glossary/vbe-glossary#type-declaration-character
※Ctrl+Fして、「型宣言文字」でページ内を検索してください。
「型宣言文字・型文字」は、消費税の税率や、前号でもお示したように「バーゲン価格の割り出し」などに使えると思います。
特に、変数で使うよりも「定数化」したいときに使えるっぽいです。
(もちろん、変数を使って明確に代入してもOKです。シーンや目的によって必要に応じて使い分けるかたちになるんだろうと思います。)
参考になるWebページは以下です。
『 VBE 用語集 』
https://docs.microsoft.com/ja-jp/office/vba/language/glossary/vbe-glossary#type-declaration-character
※Ctrl+Fして、「型宣言文字」でページ内を検索してください。
『 型文字 (Visual Basic) 』
https://docs.microsoft.com/ja-jp/dotnet/visual-basic/programming-guide/language-features/data-types/type-characters
『 リテラルと強制型変換 (Visual Basic) 』
https://docs.microsoft.com/ja-jp/dotnet/visual-basic/programming-guide/language-features/constants-enums/constant-and-literal-data-types
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
' ' データの種類 囲み文字 追加する型文字 Boolean (なし) (なし) Byte (なし) (なし) Char " C Date # (なし) Decimal (なし) D または @ Double (なし) R または # Integer (なし) I または % Long (なし) L または & Short (なし) S Single (なし) F または ! String " (なし) ' ' |
『 定数宣言のConstと型宣言文字 』
https://excel-ubara.com/excelvba1/EXCELVBA313.html
とかも大変参考になると思いますので、ご参考にしてみてください。
変数について既にある程度分かっている向けのページなので初心者の方にはちょっと難しく感じるかもしれませんが、学びが進むにつれてとても重要なことを言っていることがわかると思います。
とても有用だと思いますので、ファイルとしてPC内に保存しておくことをおススメします。
IEなら「mht」か「HTM(完全)」、
Chromeなら「Shtml」か「html」などで保存するといいと思います。
https://docs.microsoft.com/ja-jp/dotnet/visual-basic/programming-guide/language-features/constants-enums/constant-and-literal-data-types
によると、
「@」は十進型(Decimal型)のようですが、VBAの場合(?)は、通貨型になるようです。
VBじゃなくてVBAだからなのか何なのか、僕にはそこまではわかりませんが、とにかく、上記の一覧の「追加する型文字」のうち、記号の方が使えるようです。
アルファベットの大文字の方は、使ってみましたけど、エラーになってしまいました。
エラーが出ないようにする方法もあるかもしれませんので、もしお時間があったらご自分でも調べてみてください。
なお、
https://docs.microsoft.com/ja-jp/dotnet/visual-basic/programming-guide/language-features/data-types/type-characters
によると、
・記号の方の型文字を、「識別子の型文字」と呼び、
・アルファベットの方の型文字の事を「リテラルの型文字」
と呼ぶようです。
(VBAじゃなくてVBの作法かも・・・)
また、記号の方の型文字=「識別子の型文字」では、変数宣言の時に型文字を使って、例えば整数型(Integer型)を宣言する時に、
Dim bbb As Integer
bbb = 456
と書くところを、AS と型名を置き換えて、
Dim bbb%
bbb = 456
と書いても良いようです。
これは僕も今調べてて知りました。
ちなみに、前号の、
「2900円×0.3」の計算も、
(※ 0.3はSingle型。そして、つまり、バーゲンの7割引の値段算出等々。)
Single型を使うのをやめて、
もしVariant型を使うなら
Dim ccc As Variant
ccc = 0.3@
と書けば、2900がInteger型でもLong型でも、小数計算の答えには、誤差が出ません。
例えば以下のようなコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
' ' Sub aakaaaaa() Dim ccc As Long Dim ddd As Variant ccc = 2900 ddd = 0.3@ Debug.Print ccc * ddd Stop End Sub ' ' |
※参考図
(「0.3」に「@」を付加したことで、付加しなければ自動的にDouble型に内部変換されてしまうところを、ムリヤリ、Currency型に内部変換させています。)
もしくは、最初から変数で、VariantじゃなくてCurrencyを使うか、です。
(上記コードなら変数「ddd」に。)
あと、今回ここまで書いた後に、Web検索してたらたまたま見つかったページをご紹介しておきます。
とても有用だと思いますので、こちらも、ファイルとしてPC内に保存しておくことをおススメします。
IEなら「mht」か「HTM(完全)」、
Chromeなら「Shtml」か「html」などで保存するといいと思います。
『 VBAでも発生する演算誤差をリテラル文字で解決する - Qiita 』
https://qiita.com/Q11Q/items/94de5a587e5998351e6d
以上は小数部分が4桁だったり、各データ型の扱える数値の範囲内だけのお話になります。
では、小数が5桁以上だったり、各データ型の扱える範囲外のときはどうすればいいのでしょうか?
それは僕は扱ったことが無いのでわかりませんが、
https://excel-ubara.com/excelvba4/EXCEL_VBA_427.html
の、「整数に直して計算」
というところなどをご参考にしてみてください。
上記ページを表示したのち、Ctrl+F、にて、「整数に直して計算」で検索してもらえばパッと表示されます。
・・・・というわけで・・・・
色々ゴチャゴチャと書いて参りましたが、
Excelの小数誤差で気を付けないといけないのは、
「VBAで起こる誤差が、セルではなぜか表面化しない」
「VBAで起こる誤差が、セルではなぜか、誤差があるのに、勝手に丸められている?かも?」
という
「わけのわからない挙動をする」、
「1つのソフトウェアの中で動きが統一されていない」
という点に、
「気づいておく」
「あらかじめ、知っておく、学んでおく」
ということです。
(※学んでおくことは、今のExcelVBA教育界のレベルが低すぎるので、なかなかできないかもしれませんが。でも、今号を読まれた方は、今後、多少なりとも注意することができるのではないかと思います。)
逆に言うと、
「セルでは小数誤差が表面化しないのに、VBAではなぜか表面化する」
という
「1つのソフトウェアの中で動きが統一されていない」
「おかしな動きをする」
ので
「すごく気づきにくい」
あるいは
「まったく気づけないで、3分で済むエラー解決に、3日も4日気付けないでハマる」
ということです。
同時に、
「パソコンもExcelも」
「まともに動かない」
「コンピュータやExcelを無条件で盲目的に信じることこそが、最も・愚か」
「そもそもデジタルなんぞ信じるな(もちろんある程度までは信じても)」
「デジタルなんぞ、なんでも疑ったほうが無難」
「とんでもないバグが隠されているかも?」
という姿勢を持つことも重要だと思いますです。
でないと、「コンピュータやExcel」といった、
「そもそももともと不良品で、今になっても治ってないところいっぱいあるじゃん。一般機能の面だけでも(特に画面通り印刷できないとか)。」という不良品たちに、
「僕ら人間様が振り回される」
という羽目になってしまうからです。
デジタルやコンピュータやExcelなんて、
適当なところで「だいたいのところが分かった段階で」
「見限って」、
「現場を分かっている人」
「あるいは、逆にまったくわからないお客様目線の人」の
「人間の勘」を信じるほうが、
「上手く行く」
場合もあります。
いや、むしろ、そのほうが、「圧倒的に早く問題が解決できる」場合も、「未だに少なくない」です。
「人間の脳だって、意外と、思ったより、優れている」、ということです。
たとえば、藤井聡太棋聖なんてほんとうにすごい、素晴らしいと思います。
そもそも「勘」の悪い人は「数字見ても」「スルー」です。
「目に映ってるだけ」で、「見えて」ません。(それ、僕です。)
松下幸之助先生も、「勘の悪い人は数字が読めない」というような旨のことをおっしゃっていたらしいです。何かの本で読んだ気が・・・
「勘が」「アナログが」「いかに大事か」がわかると思います。
たとえば「分析」などでは、
『 クソみたいなプログラムなんか作ってモタモタしとるより、勘のほうが、100倍速いわね。』
・・・ということも「決して少なくない」ということです。(僕にはムリですが)
スティーブジョブズ先生が、常々、「数字なんかクソ!バカや能無しが”言い訳”に使うだけ!」と言っていたらしい???ですが、事実かどうかわかりませんが、でもそういう話が出るほどなので、そのことも、その証明になるのではないでしょうか?
我々凡人には、そんなことはとても言えず、どうしても「数字が必要」ですが、でも、プログラムを作るときは、そのことを「たまには」思い出してみる・考えてみることも「大切だ」と思います。
「数字なんかクソ」
「Excelなんかゴミ」
「こいつらは信用ならない」
ということをです。
じゃないと、
「直しても直しても永遠に直らない不良品」
を
「完全なモノ」
と錯覚して疑わなくなってしまうので、
「ドツボにハマる」
回数が増えてしまうからです。
(※もちろん、ある程度は信用してもよいですが。ある程度は信用しないと何もできませんので・・・。ただ、「コンピュータが計算間違いや誤作動なんてするはずない」、と、盲目的に信じるのだけはやめたほうがいい、という意味です。メンテの現場や、ネットワークの現場、その他の現場、では、誤作動だらけです。特にWindowsは。Macは僕はわかりませんが・・・。)
コンピュータやExcel、デジタル、「不良品」を信じて(というか信じすぎて)、「かえって深みにはまる」「ドツボにハマる」、ということほど、愚かなことは無いと思います。
小数の話からまったく関係ない方向に行ってしまってすみません。
デジタルというものがあまり好きではないので・・・。
==============================
今回は以上です。
==========================================================================
バックナンバー目次とサンプル号
https://euc-access-excel-db.com/tips/ct07_se/ct075012_xls2k_vba_tips/mag2-01
----------------------------------------------------------------------
■独学者が1年後にExcelVBAを爆発的に上達させるための最低限の基礎知識メモ(ダイジェスト)
発行システム:『まぐまぐ!』 http://www.mag2.com/
配信中止はこちら https://www.mag2.com/m/0001691660.html
----------------------------------------------------------------------