- ベストアンサー
エクセルVBAの Select Case構文
Range("A1")に数式が入っています。 Select Caseで エラーだった場合 計算結果が正数だった場合 計算結果が負数だった場合 計算結果が"特定の文字"だったばあい その他 で分岐したいのですが、どのように記述すればよいのでしょうか? 以下、わたしの失敗例です。AAAでもプラスと出てしまいます。エラー値の判別がわかりません。 Sub TEST() Select Case Cells(1, 1) Case Is > 1: MsgBox "プラス" Case Is < 0: MsgBox "マイナス!" Case "AAA": MsgBox "AAA" Case Else: MsgBox "やり直し" End Select End Sub
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。Wendy02です。 私の回答は、あまり、merlionXXさんご自身の問題解決には役に立たないような気がしますが、これは、参考程度に読んでくださいね。 >Case Is >= Chr(0)で文字列と判定できるという理解でよいのでしょうか? そうです。それ以下はありませんね。現実には、ワークシート上の文字、コード31(x1F) ぐらいだったと思います。それ以下は、制御文字になってしまいます。 「値0の文字列」というのは、私も詳しくはありませんが、お調べになったように、vbNullChar の空の文字列 (")です。 例えば、Window プロパティのCaption に文字列を設定する場合は、違いがありませんが、Excel.Application 上では、以下のような違いがあります。 Application.Caption = vbNullChar 'Chr(0) 'Caption のMicrosoft Excel が消える Application.Caption = "" 'Caption は消えない=設定できない。 >計算結果がエラー値の場合はどうSlelect Caseのなかに取り込めるでしょうか? 単に、エラー値を数字に変えればよいのですが、数字との比較が先にありますから、文字列にして、接頭辞を与えました。 If IsError(myValue) Then myValue = "#" & Str(CInt(myValue)) End If エラーは、この時点で捕まえていますが、それを更に厳密に分類したりする場合は、この数字を使えばよいです。ワークシート関数にも、ERR.TYPE関数がありますが、VBA側だけにしました。# をつける理由は特にありませんが、文字列の数字であっても、分類する必要があるような気がしました。 文字列比較なら、Text プロパティで取れば、例えば、 "#VALUE!"と出すことも出来ます。 #NULL! 2000 #DIV/0! 2007 #VALUE! 2015 #REF! 2023 #NAME? 2029 #NUM! 2036 #N/A 2042 コードとしては、もうありえない段階に入っているような気がしますが、実験的に、こういうものって、こちらもやっていて発見があります。 Sub Test4() Dim myValue As Variant myValue = Cells(1, 1).Value2 If IsError(myValue) Then myValue = "#" & Str(CInt(myValue)) End If If myValue = "" Then MsgBox "やり直し!": Exit Sub Select Case myValue Case "AAA": MsgBox "AAA" Case "# 2000" To "# 2042": MsgBox "エラーです。" Case Is >= Chr(0): MsgBox "やり直し" '^@を含む、それ以上 Case Is > 0: MsgBox "プラス" Case 0: MsgBox "ゼロ" Case Is < 0: MsgBox "マイナス!" End Select End Sub
その他の回答 (5)
- KenKen_SP
- ベストアンサー率62% (785/1258)
皆さん、こんにちは。 データ型判定するなら、ベーシックに TypeName 関数で分岐処理すれば良い と思います。下記のようなコードでセルが取りうるデータ型は全て網羅できます。 余談ですが、IsNumeric 関数は、 「数値として評価できるか?」 を ブール値(True/False)で返すだけで、実際のデータ型判定をしている わけではありません。例えば、イミディエイトウインドウで、 ? IsNumeric("1") とすると True が返ってきますので注意が必要です。 諸事情によりまた暫らく消えます(´・ω・`)が、ご参考までに。では。 Option Explicit Sub TEST() Dim strMsg As String With ActiveCell Select Case UCase$(TypeName(.Value)) Case "STRING" strMsg = "文字列" ' 特定文字判定(大文字・小文字区別しない) ' InStr で vbTextCompare でも判定できます If StrComp(.Value, "AAA", vbTextCompare) = 0 Then strMsg = "AAA" End If Case "DOUBLE" If InStr(.NumberFormat, ":") > 0 Then strMsg = "日付/時刻" Else If .Value = 0 Then: strMsg = "ゼロ" If .Value > 0 Then: strMsg = "正数" If .Value < 0 Then: strMsg = "負数" End If Case "DATE": strMsg = "日付" Case "BOOLEAN": strMsg = "ブール値" Case "ERROR": strMsg = "エラー値" Case "EMPTY": strMsg = "空" End Select End With MsgBox strMsg End Sub
お礼
> 例えば、イミディエイトウインドウで、 ? IsNumeric("1") イミディエイトウインドウの使い方がよくわからないので Sub TEST() MsgBox IsNumeric("1") End Sub としたらTrue が返ってきました!勉強になりました。 ありがとうございます。
- onlyrom
- ベストアンサー率59% (228/384)
質問はあくまでも文字列、数値等の比較の勉強のためだろうと推測します。 先にも書きましたが、文字列、数値、エラー値は別物ですからそれぞれに比較するべきです。 そのほうが簡単明瞭ですし。 また皆さんがその回答を参考にされるであろうWendy02さんもそう仰っていますから。 興味があれば、セルA1の表示形式を「文字列」にして、Wendy02さんのコードを試して見てください。 新しい発見があると思われます。
お礼
ありがとうございました。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんばんは。 一応、念のために、変数に代入しました。 文字も数字も、同じデータとして、文字と数字の区切りライン(Chr(0))をつければよいのではないでしょうか? なお、大文字・小文字を同じにさせるために必要でしたら、TextCompare モードの Option Compare Text にするか、StrConv で変換します。 なお、セルには、エラー値は入らないものとしています。また、#1さんのご指摘の日付比較は、シリアル値に対し行うように、Value2 プロパティにしました。通常は、私は、文字列比較と数値比較は別けますが、質問の中のコードに合わせて一緒にしてみました。 'Option Compare Text Sub Test3() Dim myValue As Variant myValue = Cells(1, 1).Value2 If myValue = "" Then MsgBox "やり直し!": Exit Sub '長さ0の文字列と空白-0とは扱わない Select Case myValue Case "AAA": MsgBox "AAA" Case Is >= Chr(0): MsgBox "やり直し" '^@を含む、それ以上 Case Is > 0: MsgBox "プラス" Case 0: MsgBox "ゼロ" Case Is < 0: MsgBox "マイナス!" ' Case Else: MsgBox "やり直し" 'おそらくは要りません End Select End Sub
お礼
Wendy02さん、いつも助けていただきありがとうございます。 Chr(0)???調べたら「値 0を持つ文字」ということらしいのですが意味がわかりません。 Case Is >= Chr(0)で文字列と判定できるという理解でよいのでしょうか? Value2プロパティも初めて知りました!これは調べて納得です。ありがとうございました。 計算結果がエラー値の場合はどうSlelect Caseのなかに取り込めるでしょうか?
- onlyrom
- ベストアンサー率59% (228/384)
文字列 > 数値 だからです。 何れにしろ、文字列と数値(数字)は別々に比較すべきものです。 特に今回のような場合は。 ----------------------------------------------- Sub test() If IsNumeric(Cells(1, 1)) Then Select Case Cells(1, 1) Case Is >= 0 MsgBox "ぷらす" Case Else MsgBox "まいなす" End Select Else Select Case Cells(1, 1) Case "AAA" MsgBox "AAA" Case Else MsgBox "やり直し" End Select End If End Sub ------------------------------------------------
お礼
ありがとうございます。 やはり文字と数値は分けて判定になるのですね。 エラー値の場合はどうしたらよいのでしょう?
- uissst
- ベストアンサー率41% (7/17)
こんなんでどうでしょう?? Sub TEST() 'セルが空白かどうか判定 If Not IsEmpty(Cells(1, 1).Value) Then 'セル内が数値の場合 If IsNumeric(Cells(1, 1).Value) Then Select Case Cells(1, 1).Value Case Is >= 0: MsgBox "プラス" Case Is < 0: MsgBox "マイナス!" End Select 'セル内が日付の場合 ElseIf IsDate(Cells(1, 1).Value) Then MsgBox "日付です。" 'セル内が日付、数値以外(たぶんテキストの場合) Else Select Case Cells(1, 1).Value Case Is = "AAA": MsgBox "aaa" Case Else: MsgBox "やり直し" End Select End If Else MsgBox "空白です。" End If End Sub
お礼
ここまで分類していただきありがとうございます。 やはり文字と数値は分けて判定になるのですね。 エラー値の場合はどうしたらよいのでしょう?
お礼
ありがとうございました! とても勉強になりました。今後ともよろしくご指導くださいませ。