質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

4回答

1813閲覧

Variant変数にある文字列から取り出した数値を格納して大小比較をしたい

py-beginner

総合スコア9

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

1グッド

0クリップ

投稿2020/10/16 07:34

編集2020/10/16 08:00

既出の質問でしたら失礼いたします。Variant変数について質問です。
エクセルVBAを使ってMAX.値を保持する単純なソースを組んだのですが、負の値のMAX.値の判定に失敗してしまいました。

Dim A As Variant, B As Variant

if A<B then A=B

AとBには、一定のルールで作成された他のテキストファイルからInputとMid関数で該当の数値部分を取得しています。たまに数値でない文字列が入ることもあるため、Variantとして宣言しています。例えば、

A="-7.02"
B="-6.4"

という状態のとき、

if A<B then A=B

では A<B がFalse となり、 A="-7.02" のままです。
2行目を

A = Application.WorksheetFunction.Max(A, B)

とすると A=-6.4 とこちらの望む数値が返ってきます。

<や>の比較演算子は数値に対するものだと思っていたので、VariantにしていればMax関数の時と同じようにA,Bも数値として扱われるのかと思ったのですがCDblなどで変換しない限り文字列から部分取得してきた値は自動で数値になることはないのでしょうか?
だとするとMax関数の時にはなぜエラーではなく意図通りの数値が返ってくるのでしょうか?

正しい比較結果を取得するには
A = Application.WorksheetFunction.Max(A, B)
もしくは
if CDbl(A)<CDbl(B) then A=B
だと思ったのですが、他に適切なソースがございましたらご教示いただけますと幸いです。

また、単に疑問なのですが、<や>の比較演算子を文字列に使用することがあるとしたらどのような比較をするときなのでしょうか?

多分基本的なところがわかっていない故の疑問だと思うのですが、ご教示いただけますと幸いです。
よろしくお願いいたします。

使用アプリケーション:office365のExcelです。

以下追記---------

いろいろ試してみているのですが、テキストファイルから取得してきた値が負でなく正の数であればAとBが""付き(String)のままでも A<B がtrueとなり大きい方が取得できました。
ますます謎が深まっています…。

teranaomasa👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kitasue

2020/10/16 08:22

> テキストファイルから取得してきた値が負でなく正の数であればAとBが""付き > (String)のままでも A<B がtrueとなり大きい方が取得できました。 整数部の桁数が同じ場合ですよね?
py-beginner

2020/10/16 08:29

ご指摘ありがとうございます。 確かに整数部の桁が同じときの結果でした。Stringだと桁数などの比較になる、ということでしょうか…。
kitasue

2020/10/16 08:35

いえ、文字列として比較した結果が、数値として比較した結果と同じになるということです。
py-beginner

2020/10/16 08:39

無知につき失礼いたしました。 いろんな方にご教示いただけて何となくわかってきた気がします。 あとは自分でじっくり読み砕いていこうと思います。 ありがとうございました!
guest

回答4

0

ベストアンサー

VBAでは文字列でも大小比較します。基本的に文字コードを基準に比較します。

"-7.02" と "-6.4" という文字列なら先頭から文字コードで比較していきます。一文字目はどちらも"-"で同じなので、2文字目の"7"と"6"は文字コードでは 55 と 54 なので"7"の方が大きいと判断されます。

WorksheetFunction.Max() はVBAの関数ではなくエクセル関数のMAXをVBAから使えるようにしたもので、MAX関数は文字列でも数値に変換可能な場合は数値に変換して比較するという仕様になっています。逆に数値変換できない文字列"aaa"とか"bbb"とかだとエラーになります。

また、単に疑問なのですが、<や>の比較演算子を文字列に使用することがあるとしたらどのような比較をするときなのでしょうか?

文字列の大小比較をする機会はほとんどないですが、例えば成績を"A" "B" "C" というような文字列で表現する場合がありますが、その時に使えますね。いま、自分か思いつくのそれぐらいです。

投稿2020/10/16 08:17

hatena19

総合スコア34075

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

py-beginner

2020/10/16 08:32

詳細なご説明ありがとうございます。文字コードでの比較とは目から鱗です! 現象に対して納得することができました。 ご回答いただきありがとうございました!
guest

0

https://qiita.com/jnchito/items/077f6d541d53152aa680
こちらが参考になるかと。VBAではありませんが、内容は同じです。
同じことが出来る検証コードつくって遊んだので、折角なので置いておきます。

VBA

1Sub test() 2 3Dim A, B 4Dim aa As Long, bb As Long 5Dim ac As Double, bc As Double 6Dim achw As String, bchw As String 7 8A = "お好きな文字列" 9B = "お好みの文字列" 10 11For aa = 1 To Len(A) 12 ac = AscW(Mid(A, aa, 1)) 13 14 achw = achw & "," & ac 15 16Next 17 18For bb = 1 To Len(B) 19 bc = AscW(Mid(B, bb, 1)) 20 21 bchw = bchw & "," & bc 22 23Next 24 25achw = Right(achw, Len(achw) - 1) 26bchw = Right(bchw, Len(bchw) - 1) 27 28 29Debug.Print A & " > " & B 30Debug.Print A > B 31Debug.Print A, achw 32Debug.Print B, bchw 33 34End Sub

投稿2020/10/16 08:27

Usirow

総合スコア364

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

py-beginner

2020/10/16 08:37

検証コードに参考URLまで教えていただきありがとうございます! 別途しっかり拝読させていただきます。 今回ご回答いただいた諸々をしっかり取り込んで、今後のマクロ作成に活かしていきたいと思います。 ご回答いただきありがとうございました!
guest

0

既に回答が出ていますが、目的は数値として比較したいということでしたら
double型に変換して比較してはいかがでしょうか。

VBA

1Public Sub 数字比較() 2 Dim A As Variant 3 Dim B As Variant 4 A = "-7.02" 5 B = "-6.04" 6 If A < B Then 7 Debug.Print A, "<", B 8 Else 9 Debug.Print A, ">", B 10 End If 11 If CDbl(A) < CDbl(B) Then 12 Debug.Print A, "<", B 13 Else 14 Debug.Print A, ">", B 15 End If 16End Sub 17

実行結果
-7.02 > -6.04
-7.02 < -6.04

CDbl関数でdouble型にした場合は、数値として比較されます。

投稿2020/10/16 08:57

tatsu99

総合スコア5493

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

py-beginner

2020/10/19 02:37

具体例をご提示いただきありがとうございます! 土日はパソコンから離れていたのでお礼が遅くなり大変失礼いたしました。 Variantは万能、と勝手に思い込んでいたので今回質問させていただいたことで皆様のご回答、大変勉強になりました。 やはり必要な箇所ではdouble型に変換が確実、ということが理解できましたので今後にしっかり活かしていこうと思います。 ご回答ありがとうございました!
guest

0

Variant型の変数にどんな型の値が入っているかはVarType()関数の戻り値で判別できます。
ですので、Max()の内部ではおそらくこれを使って、文字列だったら「文字列」→「数値」の変換を行って比較をしているものとを思われます。

ご自身で独自の比較関数を作成する際のであればVarType()を使用されて内部の型ごとに処理を分岐する、という方法をとるのが良いと思います。

投稿2020/10/16 08:01

KoichiSugiyama

総合スコア3041

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

py-beginner

2020/10/16 08:26

ご回答ありがとうございました。 Variantという型に対して自分が期待し過ぎていたみたいです。そんな都合よく自動で型が変わったりしないですよね。 用途や必要に応じて自分でちゃんと型を判断して処理するようにしようと思います。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問