VBAの「+演算子」の挙動が怖すぎる

VBAで文字列と数値に「+演算子」を使用すると、他言語では見られない独特の挙動を示します。 本まとめは、Twitterで不定期で行われている #VBAクイズ@KotorinChunChun が出題した問題のまとめです。
数値 文字列 プログラム VBA プログラミング VBAクイズ 演算 演算子
39
リンク えくせるちゅんちゅん 3 users えくせるちゅんちゅん ことりがエクセルをちゅんちゅんするブログ
出題
ことりちゅん@えくせるちゅんちゅん @KotorinChunChun
#VBAクイズ Debug.Print "1" + "2" Debug.Print "1" + 2 Debug.Print 1 + "2" Debug.Print -"1" + "2" 上から答えは?
ことりちゅん@えくせるちゅんちゅん @KotorinChunChun
見事に割れているので、もし宜しければ、 ・どれを選んだのか ・何を根拠に選択したのか 意見が聞きたい。

Togetter読者の皆様へ

興味のある方は、自分の答えを出してからこの先をお読みいただくと、より勉強になります。

皆の解答
FukuCyndi papa @FukucyndiP
実際に確かめちゃいましたけど、勉強になりました! あ。投票はしてないです┏○ペコ twitter.com/kotorinchunchu…
Excel Ubara @yamaoka_ss
@KotorinChunChun これ面白い、というか、良い問題だと思う。 悩む人多い気がしますね。 選択肢なかったら、私もちょっと悩む気がする。
ほえほえ@LWP @hoehoe1234
@KotorinChunChun これ、最難関www。ワイも多分、まちがえてるとおもう。。。左型優先変換か型の広さ優先変換かまったくわからんwww。
シンノユウキ @shinno1993
ヤバイ。全然わかんない。 最初の以外は全部エラーになるんじゃね?って思ったくらい。 なんとなくで一番上を選択。文字列の結合には&を使いたい派です。 twitter.com/KotorinChunChu…
Taichi AOKI @aoki_taichi
そもそも文字列に&以外の演算子が使えるとは知らなかった。 どういう仕組みなんだろう?演算子が+-*/^のときは、被演算子にCDblでも働かせることになっているのかな? 自作のクラスに対しても、そういう演算子オーバーロードのようなことができるなら、面白そう。 twitter.com/kotorinchunchu…
W.D. @WD4096
@KotorinChunChun 帰宅後確認しますけど、演算順序が最初のパラメーターの型で演算が開始されると思うのです。 で、残りのパラメーターは暗黙の型変換される理解。
W.D. @WD4096
@KotorinChunChun 間違っていて凄くびっくり。 ううむ。わかりにくい仕様ですね。 これは気を付けないと。
サモイタ@VBAって凄すぎ @biitarou
①が文字列と文字列の結合なのはわかる。 あとは、全部エラー。 と思ったら選択肢がない。。。 twitter.com/KotorinChunChu…
とりにくEXCELVBA @jbaske_032j
@KotorinChunChun 1は文字列結合 2、3は数値に変換されて演算 4は想像もつかなかったけど、選択肢で4番目を回答しました。
俊爺 @toshi81350036
うひゃー、最後のやつ見て4番にしたけど…後で確かめてみよう。ま、こんなコード書かないに越したことはないけどねw。この辺りが暗黙変換の落とし穴だよなあ。 twitter.com/KotorinChunChu…
うなぎ犬 @porineshia1
あまり自信はありませんが、 1.文字列同士の結合なので、+は&と同じ 2と3. 片方が数値だと、数値と判断できる文字列は自動型変換され、計算される 4.よく分かりませんが、文字列にマイナスはないため、数値とみなされた。あとは2と3と同様。 twitter.com/KotorinChunChu…
答え合わせ
ことりちゅん@えくせるちゅんちゅん @KotorinChunChun
それでは、解答です。 正解は4番目の「12 3 3 1」です! まず、今回の出題では、敢えて "1" + "2" の答えを全て 12 にして、「プラス演算子でも「&」のように文字列の連結がされるんだよ」とアピールさせてもらいました。 その上で「じゃあ数値と文字列の場合はどうなるの?」を問いました。 pic.twitter.com/e7LFgoxuaI
拡大
ことりちゅん@えくせるちゅんちゅん @KotorinChunChun
> "1" + 2 と > 1 + "2" は、普通、以下の3パターンが考えられますが ・エラーになる ・左辺の型に合わせる ・両辺の幅広い表現に対応できる型に合わせる VBAは ・(何故か)数値に揃えて加算する という動きをするようです。
ことりちゅん@えくせるちゅんちゅん @KotorinChunChun
また、 > "a"+1 や > 1+"a" は、「型が一致しません。」というエラーになります。 両辺が文字列の場合のみ「+」演算子は「&」演算子の代替として機能するような感じです。
ことりちゅん@えくせるちゅんちゅん @KotorinChunChun
従って、「+」演算子が登場したときは、両辺の値を数値型に暗黙的にキャストが行われてから、計算が行われる仕様なのだろうと私は推測しました。 もっと詳しい検証は、ほえほえさんがしてくれました。 twitter.com/hoehoe1234/sta…
残りを読む(24)

コメント

ゆーき @yuki073 2020年1月25日
PHPは==が邪悪すぎるからなぁ。文字列を数値扱いするのは、当時はいいアイデアだと思ったのかもしれないけれど混乱するだけだったな。
LCO @f_lco 2020年1月25日
複数言語に渡って使ってると こういうの良くハマりがち…
ぼんぼ (唐揚げに大根おろし&ポン酢醤油) @tm_bonvo 2020年1月25日
静的型付け信奉者としては「そういうとこやぞ」と言わざるを得ない
まりも @potimarimo 2020年1月25日
この仕様もジョエル・スポルスキが決めたのだろうか。
orange @orange_in_space 2020年1月25日
tm_bonvo めちゃくちゃ細かいことを言うと、これは静的型付けかどうかじゃなく、その言語や環境のタイピングルールがどうかなので厳密には違うかも?><(静的型付けな環境の方が暗黙の型変換を嫌う事が多い傾向がとても強いのはその通りだけど><)(私も動的型付けすごく嫌いだし暗黙の型変換も嫌い><)
飛鷹隼 @junhiyoh 2020年1月25日
VBAが異なる型間での+演算子の仕様が数値優先になるのは使用ケースとして最も多いのがExcelのマクロ処理だからだろうなぁ、と あと文字列結合を+処理するとたまにエラー吐くので文字列結合は&でやるのが鉄則だな
ねや @AriaSub 2020年1月25日
演算子オーバーロードで、引数が文字文字の時に結合動作になるだけなんだけどなぁ 数値型がある限り数値として扱うってルールも一貫してるしそんなにおかしいかな? そういうの無い言語しかしらないと不思議かも知れないのか
orange @orange_in_space 2020年1月25日
orange_in_space 1時間くらい経って「あ゛><;」ってなった><; ごめんなさい><; 違くなくて関係あるね><;
kartis56 @kartis56 2020年1月25日
全然怖くない。仕様通りでしょで終わる話
kartis56 @kartis56 2020年1月25日
曖昧なものを曖昧なまま使うんじゃなくて、曖昧なら仕様を調べるべき
よず:フロサポ兼投擲系システムエンジニア @sp1185 2020年1月25日
上3つは分かったので正答したけど4番目はそんな挙動なのか。 VBAはこんな緩さも特徴なのね、と再認識
SAKURA87@多摩丙丁督 @Sakura87_net 2020年1月25日
Visual Basicの派生は全部これだから「文字列を扱うときは+じゃなくて&を使え」とどの言語のどの参考書にもくどいくらい書いてる。
ziggy @zigizagu 2020年1月25日
VBAは2度と触りたくない言語第1位(個人調べ)
⛩️ のーみん丁 ⛩️ @noumin_T 2020年1月25日
VBAもたまに使うので分かった。この挙動は「特に注意が必要なやつで有名」なので知ってる人も多いのでは。わかっていればそこまで奇抜な動作ではないけど、たまにコレが原因でバグ出る。
Hacchi @2mocccck 2020年1月25日
VBAはゴミという大前提が脳内にあったので正解できた。VBAは悪名高いしどこ見ても叩かれてるけど、根拠がないわけじゃなくて理由があるんだよね。たまにVBAのソースみるけど本当に小汚いから絶対VBAのプロジェクトには自分からは関わらないと心に決めてる。
yot2019 @yot2019 2020年1月25日
もともとBASICは、こんな挙動だったような。C言語は明確な型宣言が必要だが、PythonとかまたBASIC回帰のような気がする。Pythonでは、どんな結果になるんでしょうかね?
aki @Yy7_f 2020年1月26日
そんなことより私は-1^2の結果がExcelとVBAで違うことを問題視している。
kisara @kisara50 2020年1月26日
静的型でも型推論あるMLとかだとあるのかなこの手の難題(MLは仕様書だか読んだだけで使ったことない)
しょーた @shota243 2020年1月26日
Pythonは TypeError: unsupported operand type(s) for +: 'int' and 'str' になりますね。数字だけからなる文字列から整数への暗黙の型変換は持ってない。
じょにい@インコ㌠ @Jun_kkc 2020年1月26日
VBAは頻繁に使うけど、いつも明示的に型変換してるから、文字列型と数値型の混在は考えたことなかったなぁ…。演算子や結合子もキッチリ使い分けてる…。
でー@でとこーだ @detcoder 2020年1月29日
標準入出力経由でテキストを弄るPerlや、HTMLをいじくりまわす古のPHPやJavaScriptが暗黙の型変換するのはわからないでもないけど、表計算用途でそれはちょっと……
ねや @AriaSub 2020年1月29日
detcoder「¥1,000」や「▲20百万円」という文字列を数字として扱わないと行けない表計算だからこそ何じゃない?
でー@でとこーだ @detcoder 2020年1月30日
AriaSub 確かにそれも一理ありますね。ですが、そういった書式が絡むものはシートView側(NumberFormatLocalとか)の処理として分割しておきたいとも個人的には思います
ログインして広告を非表示にする
ログインして広告を非表示にする