![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?08b1c8b)
Excelのマクロで、どうにも理解できない結果に困っております。
If文による大小判定なのですが、同じ判定条件文なのに一枚のシートモジュールに書いたマクロと判定文を標準モジュールに書いてシートモジュールからコールした場合の判定結果が同じ結果になりません。
このような場合には、必ず何処かに単純なミスがあるのが通例ですが、今回は何度見直してもミスが発見できません。
少々分かり難い質問文になりましたが InputBox から入力した数値が指定した範囲にあるか否かの判定をするマクロです。
1.シートモジュール Sheet1 に書いたマクロ (正常動作)
Dim データ総数 As Long
Dim 除外データ数 As Variant
Dim 処理データ数 As Variant
Dim Alm As String
Sub 血圧色分けA()
データ総数 = 300 '仮にデータ総数を300と設定
N1: 除外データ数 = InputBox("除外するデータ数を入力してください" & vbCr & _
"データ範囲は0~" & データ総数 - 1 & "個です" & vbCr & _
"最新データから除外するデータ数より以前のデータを処理します", _
"血圧色分け", 0)
If 除外データ数 = "" Then
MsgBox ("処理をキャンセルします")
GoTo N3
ElseIf IsNumeric(除外データ数) = False Then
Alm = MsgBox("数字を入れてください", vbCritical)
GoTo N1
ElseIf 除外データ数 > データ総数 - 1 Or 0 > 除外データ数 Then
Alm = MsgBox("データ範囲は0~" & データ総数 - 1 & "個です", vbCritical)
GoTo N1
End If
N3: End Sub
2.判定文を標準モジュール Module1 に書いて引数付きでシートモジュール Sheet2 に書いたマクロから引数付きでコールする場合 (動作?)
<Sheet2のマクロ>
Dim データ総数 As Long
Dim 処理項目 As String
Dim 初期値 As Long
Dim キャンセル As Boolean
Dim 除外データ数 As Variant
- - - - - - - - -
Sub 血圧色分けB()
データ総数 = 300 '仮にデータ総数を300と設定
処理項目 = "除外データ数"
初期値 = 0
Call 除外データ数取得(除外データ数, データ総数, 処理項目, 初期値)
N3: End Sub
- - - - - - - - -
<Module1のマクロ>
Dim Alm As String
- - - - - - - - -
Sub 除外データ数取得(A, B, C, D)
'A = 除外データ数
'B = データ総数
'C = 処理項目
'D = 初期値
N1: A = InputBox(C & "を入力してください" & vbCr & _
"データ範囲は0~" & B - 1 & "です" & vbCr & _
"最新データから" & C & "より以前のデータを処理します", C, D)
If A = "" Then
MsgBox ("処理をキャンセルします")
GoTo N3
ElseIf IsNumeric(A) = False Then
Alm = MsgBox("数字を入れてください", vbCritical)
GoTo N1
ElseIf A > B - 1 Or 0 > A Then
Alm = MsgBox("データ範囲は0~" & B - 1 & "個です", vbCritical)
GoTo N1
' ElseIf 除外データ数 > データ総数 - 1 Or 0 > 除外データ数 Then
' Alm = MsgBox("データ範囲は0~" & データ総数 - 1 & "個です", vbCritical)
' GoTo N1
End If
N3: End Sub
No.2ベストアンサー
- 回答日時:
厳密に言えば、どちらも正しくありません。
Excelのお節介によって前者は意図したとおりに動き、後者は意図したとおりに動いていないだけです。
前者のマクロでは変数「初期値」はLongで宣言されていますが、後者の方では変数「B」は宣言されていないためVariant(Variant型数値)になっています。
InputBoxで入力された値はどちらもVariant型の変数に代入されていますが、InputBoxが返すのは文字列型ですので、中身は文字列(Variant型文字列)になっています。
前者は、Variant型文字列とLong型の変数を比較しています。
Excelは、比較相手がLong型なので、Variant型文字列を気を利かせて数値として扱います。
後者は、Variant型文字列と、Variant型数値を比較しています。
Excelは、なぜか解りませんが、Variant型文字列とVariant型数値を比較すると、必ずVariant型文字列の方が大きいと判断します。
比較をするときは型を合わせるようにしましょう。
Variantは便利ですが、思いがけないところではまる原因になりやすいです。
最少の修正で後者を前者と同じ動きにしたいのでしたら、以下の様に修正しましょう
Sub 除外データ数取得(A, B, C, D)
↓
Sub 除外データ数取得(A, B As Long, C, D)
>Excelは、なぜか解りませんが、Variant型文字列とVariant型数値を比較すると、必ずVariant型文字列>の方が大きいと判断します。
以前何かで読んだ記憶があるのを思い出しました。
忘れた頃にVBAをやるのですっかり抜けていました。
>Excelのお節介によって前者は意図したとおりに動き、後者は意図したとおりに動いていないだけです。
意図したとおりに動く方はVariant型文字列とLong型の変数を比較していて、意図したとおりに動かない方はVariant型文字列とVariant型数値を比較しているんですね。
はまってしまった理由のひとつは、エディター画面でデバッグする時、マウスカーソルを当てた時に表示される変数の値はLong型もVariant型数値も同じ整数で表示され、型の区別が付かないためだと思います。
見た目は全く同じものを判定しているのに結果が違う。ウー何故って感じでした。
問題の判定文のところではVariant型文字列に入っているのは整数のみなので CLng 等を使用して型を変換して比較するのが間違いのない方法でしょうか。
ElseIf CLng(A) > CLng(B) - 1 Or 0 > CLng(A) Then
Alm = MsgBox("データ範囲は0~" & B - 1 & "個です", vbCritical)
GoTo N1
すっきり解決しました。ありがとうございました。
No.1
- 回答日時:
インプットボックスの後に
Debug.Print TypeName(A), TypeName(B)
と入れて走らせてみると、原因がわかります。
答えを言ってしまうと・・変数AはがString型で見られていますね。
このInputBoxは文字列型で返してくるようです。
なので、数値としての大小を比べられていない状態ですね。
とりあえずの対策。
文字列型が返るなら、数値型に変換しちゃえ、ってことで、
ElseIf Val(A) > B - 1 Or 0 > Val(A) Then
Val関数で変換しちゃうと上手くいきそうですよ。
多少強引ですけどね^^;
>文字列型が返るなら、数値型に変換しちゃえ、ってことで、
ElseIf Val(A) > B - 1 Or 0 > Val(A) Then
Val関数は便利ですね。その他にも CLng とかで型変換すれば上手く行きそうです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- Visual Basic(VBA) 【前回の続き続きです、ご教示ください】VBAの記述方法がわかりません。 2 2022/08/24 20:49
- その他(Microsoft Office) マクロVBAについて 1 2022/09/06 18:12
- Visual Basic(VBA) VBAが止まります。 3 2022/08/31 14:09
- Visual Basic(VBA) VBAでoutlook365が起動しません。 4 2022/08/25 13:31
- Excel(エクセル) VBAについて 3 2022/06/19 18:19
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- Visual Basic(VBA) 【ご教示ください】VBAの記述方法がわかりません。 2 2022/08/12 21:28
- Visual Basic(VBA) Sub 分けてソートして貼り付ける() Dim srcSheet As Worksheet Dim 6 2023/08/04 19:57
- Visual Basic(VBA) 【前回の続きです、ご教示ください】VBAの記述方法がわかりません。 2 2022/08/16 16:44
このQ&Aを見た人はこんなQ&Aも見ています
-
今年はじめたいことは?
今年はこれをはじめたい!ということを教えてください!
-
歳とったな〜〜と思ったことは?
歳とったな〜〜〜、老いたな〜〜と思った具体的な瞬間はありますか?
-
あなたの「プチ贅沢」はなんですか?
お仕事や勉強などを頑張った自分へのご褒美としてやっている「プチ贅沢」があったら教えてください。
-
洋服何着持ってますか?
洋服を減らそうと思っているのですが、何着くらいが相場なのかわかりません。
-
14歳の自分に衝撃の事実を告げてください
タイムマシンで14歳の自分のところに現れた未来のあなた。 衝撃的な事実を告げて自分に驚かせるとしたら何を告げますか?
-
VBA:同じ文字列データの比較がうまくいかない例
Excel(エクセル)
-
同じ文字列なのにfalseになってしまいます。
Excel(エクセル)
-
Excel VBA IF文がうまく動作しないわけがわかりません…
Visual Basic(VBA)
-
-
4
【VBA】特定の値が入った行をコピーして別シートに貼り付ける方法をおしえていただきたいです。
Excel(エクセル)
-
5
Vba初心者です。下記のコード助けてください Loopに対するDoがありませんと表示されます Sub
オープンソース
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・思い出すきっかけは 音楽?におい?景色?
- ・あなたなりのストレス発散方法を教えてください!
- ・もし10億円当たったら何に使いますか?
- ・何回やってもうまくいかないことは?
- ・今年はじめたいことは?
- ・あなたの人生で一番ピンチに陥った瞬間は?
- ・初めて見た映画を教えてください!
- ・今の日本に期待することはなんですか?
- ・【大喜利】【投稿~1/31】『寿司』がテーマの本のタイトル
- ・集中するためにやっていること
- ・テレビやラジオに出たことがある人、いますか?
- ・【お題】斜め上を行くスキー場にありがちなこと
- ・人生でいちばんスベッた瞬間
- ・コーピングについて教えてください
- ・あなたの「プチ贅沢」はなんですか?
- ・コンビニでおにぎりを買うときのスタメンはどの具?
- ・おすすめの美術館・博物館、教えてください!
- ・【お題】大変な警告
- ・【大喜利】【投稿~1/20】 追い込まれた犯人が咄嗟に言った一言とは?
- ・洋服何着持ってますか?
- ・みんなの【マイ・ベスト積読2024】を教えてください。
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・最強の防寒、あったか術を教えてください!
- ・【大喜利】【投稿~1/9】 忍者がやってるYouTubeが炎上してしまった理由
- ・歳とったな〜〜と思ったことは?
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
教えて下さい
-
ブレーカー落ちで壊れたりしな...
-
VBA 空白セルを削除ではない方...
-
VBAでのリストビューにおけるド...
-
UCLとLCLってなんですか?予備...
-
0が含まれる幾何平均が「#NUM!」
-
Sheet2の日付をキーにオートフ...
-
split関数の使用方法について教...
-
大学のゼミのレポートがムカつ...
-
ビットシフトについて
-
Excel 「テキストファイルのイ...
-
アクセス2000で画像データ...
-
A/DデータをSCIを利用してPCに...
-
【エクセル】測定時間がバラバ...
-
VBA 該当データがない時 ...
-
VBA 毎日取得するデータを順番...
-
ノイズの入った波形をきれいな...
-
[C言語] コメント文字列を無視...
-
重複データを書き込まないよう...
-
多量のSUMIF式を軽くしたい
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
教えて下さい
-
【エクセル】測定時間がバラバ...
-
VBA 空白セルを削除ではない方...
-
メモ帳(テキストデータ)をExc...
-
配列でデータが入っている要素...
-
ブレーカー落ちで壊れたりしな...
-
特定のデータの抽出方法を教え...
-
EXCELVBAでSQLserverからデータ...
-
エクセルで2つの時系列のデー...
-
VBAを使ってOutlookメール本文...
-
Accessで該当データにフラグを...
-
この行は既に別のテーブルに属...
-
[C言語] コメント文字列を無視...
-
ユーザーフォームのテキストボ...
-
二分探索の平均探索回数
-
Excel VBAでのオートフィルター...
-
多量のSUMIF式を軽くしたい
-
カンマからスラッシュに
-
CString型の文字列連結について
-
C# でDataTableの更新を高速化...
おすすめ情報