タイトル | : Re: 数値の1と文字列の"1"が同じになる理由 |
記事No | : 16601 |
投稿日 | : 2020/12/07(Mon) 12:05 |
投稿者 | : 魔界の仮面弁士 |
> 最近ExcelのVBAを少しやっています。 VB6 も VBA も言語エンジンは一緒なので、判断基準は変わりません。 VBA の最新は 7.1 なので、言語仕様的には VB6 の方が古いですが。
> '↓本来、If CStr(b) = a Thenの様に > ' 型を合わせてから比較、と書くべきとは思うのですが… > If b = a Then 比較式の一方が数値型で、他方が文字列型ですね。 この組み合わせの場合、両端が Double 型へと暗黙の型変換されてから比較される仕様です。
こうした変換ルールは一応ヘルプにも書いてあるのですが、ちょっと分かりにくいですよね。 https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/comparison-operators
要するに今回の場合、 If b = a Then という処理が If CDbl(b) = CDbl(a) Then に相当する判定式として処理されることになります。
そのため以下の組み合わせは、いずれも「If a = b Then」が True として判定されます。 a = "&HA" b = 10
a = "(100)" b = -100
一方、文字列側を数値に変換できないようなケース…たとえば a = "" b = 1 のような場合には、CDbl(a) 相当の型変換が行えないため、 VB6 や VBA では『実行時エラー '13': 型が一致しません。』 .NET 版の VB では『System.InvalidCastException: 'String "" から型 'Double' への変換は無効です。』 というエラーになります。
> Dim a As String > Dim b As Integer > a = "1" > b = 1 二つの項に対する演算において、それぞれの項のデータ型が異なる場合、 それが比較演算であれ代入演算であれ算術演算であれ、まずは暗黙の型変換が働きます。
今回の場合、比較式の一方が数値型だったので、数値同士の演算として処理されたわけです。
これが代入処理であったならば、たとえば Dim a As String Dim b As Integer a = -1 '文字列型変数に整数値を代入 … CStr(-1) 相当で "-1" b = "2.5" '整数型変数に文字列値を代入 … CInt(CDbl("2.5")) 相当で 2 b = "3.5" '整数型変数に文字列値を代入 … CInt(CDbl("2.5")) 相当で 2 と書いたとしても、特にエラーにはなりません。
比較演算であれ、四則演算であれ、同様の型変換が行われます。 11 + 11 は 22 になります。 11 + "11" は 22.0 になります。 "11" + 11 は 22.0 になります。 "11" + "11" は "1111" になります。 11 & 11 は "1111" になります。 11 & "11" は "1111" になります。 "11" & 11 は "1111" になります。 "11" & "11" は "1111" になります。
蛇足ですが、VBA において x / y という除算演算は、基本的には Double 型として演算されます。
Debug.Print TypeName("24" / "2") ' "Double" Debug.Print TypeName(CCur(1) / CInt(1)) ' "Double" Debug.Print TypeName(CLng(1) / CLng(1)) ' "Double" Debug.Print TypeName(CCur(1) / CCur(1)) ' "Double" Debug.Print TypeName(CDec(1) / CDec(1)) ' "Decimal" Debug.Print TypeName(CSng(1) / CSng(1)) ' "Single"
x / y という割り算の結果は、ほとんどが Double 型となりますが、例外的な組み合わせとして x と y の一方が Decimal の場合は、演算結果は Decimal 型になります。 x と y の一方が Single で、他方が Byte, Integer, Single いずれかなら、Single 型に演算されます。 x と y の一方または両方が Null なら、演算結果も Null です。 (なお、Empty 値を渡した場合には、数値ゼロとして扱われます) https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/forwardslash-operator
> ご享受して頂けないでしょうか。 享受:与えられたものを自分のものとして受け入れ、味わい楽しむこと →「インターネットの恩恵を享受する」 教授:専門的な学問や技芸を教え授けること →「書道を教授する」 教示:知識や方法などを教え示すこと →「御教示を賜りたい」 http://www.tt.rim.or.jp/~rudyard/torii009.html
> ※VB6.0や、VB2005以降だと数値と文字が違うと VB6 やそれ以前でも同じですし、 VB.NET (2002)、VB.NET 2003、VB2005 はもちろん、 VB2008、VB2010、VB2012、VB2013、VB2015、VB2017、VB2019 でも この点は変わっていません。
ただし .NET では、『Option Strict On』指定でコンパイルした場合には、 データ型の違いまでチェックされるようになっています。
|