Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


5049 / 13646 ツリー ←次へ | 前へ→

【52817】Caseに複数の条件 セイチ 07/12/4(火) 23:34 質問[未読]
【52820】Re:Caseに複数の条件 りん 07/12/5(水) 6:40 回答[未読]
【52840】Re:Caseに複数の条件 neptune 07/12/5(水) 20:42 回答[未読]
【52842】Re:Caseに複数の条件 ponpon 07/12/5(水) 21:57 発言[未読]
【52844】Re:Caseに複数の条件 セイチ 07/12/5(水) 23:31 お礼[未読]
【52855】Re:Caseに複数の条件 neptune 07/12/6(木) 12:05 回答[未読]
【52845】Re:Caseに複数の条件 ichinose 07/12/5(水) 23:32 発言[未読]
【52889】Re:Caseに複数の条件 セイチ 07/12/7(金) 22:46 お礼[未読]

【52817】Caseに複数の条件
質問  セイチ  - 07/12/4(火) 23:34 -

引用なし
パスワード
   皆様よりレベルの低い質問をするという事は重々承知しておりますが、どうぞお許しください。

私はExcelで、イラストロジックを途中まで解いてくれるプログラムを、最終的には作ろうと思っています。
そのために、3つのセルに、それぞれ入力されているかされていないかで、異なる動きをするプログラムを作ろうと思っています。
例えば、
「B5は入力あり」かつ「C5は入力なし」かつ「D5は入力あり」のとき「「成功!」というメッセージボックスを表示する」
当てはまらないときは、「「失敗・・・」というメッセージボックスを表示する」
といった風にです。
これをCaseで作りたく、下のように作ってみたのですが、思うように動きません。

Sub テスト()
  Select Case Range("B5,C5,D5")
      Case Is = Not Empty, Is = Empty, Is = Not Empty
        MsgBox "成功!"
      Case Else
        MsgBox "失敗・・・"
  End Select
End Sub

Caseには、複数のセルに関する条件は設定できないのでしょうか?
設定できるにしても、やり方が違っているのでしょうか?
ヒントだけでも良いので、教えていただけたら嬉しいです。
よろしくお願いいたします。

【52820】Re:Caseに複数の条件
回答  りん E-MAIL  - 07/12/5(水) 6:40 -

引用なし
パスワード
   セイチ さん、おはようございます。
>Caseには、複数のセルに関する条件は設定できないのでしょうか?
>ヒントだけでも良いので、教えていただけたら嬉しいです。

チェックした結果で分岐してみてはいかがでしょうか。

Sub テスト()
  Dim tf As Boolean
  'Check
  tf = Not IsEmpty(Range("B5").Value)
  tf = tf And IsEmpty(Range("C5").Value)
  tf = tf And Not IsEmpty(Range("D5").Value)
  'Result
> Select Case tf
>   Case True
>    MsgBox "成功!"
>   Case Else
>    MsgBox "失敗・・・"
> End Select
End Sub

こんな感じです。

【52840】Re:Caseに複数の条件
回答  neptune  - 07/12/5(水) 20:42 -

引用なし
パスワード
   ▼セイチ さん:
こんにちは

>これをCaseで作りたく、下のように作ってみたのですが、思うように動きません。

>Caseには、複数のセルに関する条件は設定できないのでしょうか?
>設定できるにしても、やり方が違っているのでしょうか?
やった事は無いですが、Select 節は1つのデータを複数の条件で評価をする
ものですから、出来ないと思います。
従って、りんさんが既に書かれている方法や関数を作ったりする方法
になると思います。

個人的には関数を作る方がメンテしやすくなるので好きです。
一例ですが、こんな感じ。
Sub t()
Dim r As Range
  Set r = Application.Union(Range("B5"), Range("C5"), Range("D5"))
  MsgBox CheckData(r)
  Set r = Nothing
End Sub

Private Function CheckData(pData As Range) As Boolean
  Dim ret As Boolean
  '「B5は入力あり」かつ「C5は入力なし」かつ「D5は入力あり」のとき「「成功!」
  If (Not IsEmpty(pData(1, 1)) And IsEmpty(pData(1, 2))) And Not IsEmpty(pData(1, 3)) Then
    ret = True
  Else
    ret = False
  End If
  CheckData = ret
End Function

【52842】Re:Caseに複数の条件
発言  ponpon  - 07/12/5(水) 21:57 -

引用なし
パスワード
   よくわかってませんが、こんなんじゃダメなんですかね?

Sub テスト()
  Select Case True
      Case Range("B5") <> Empty And Range("C5") = Empty And Range("D5") <> Empty
        MsgBox "成功!"
      Case Else
        MsgBox "失敗・・・"
  End Select
End Sub

【52844】Re:Caseに複数の条件
お礼  セイチ  - 07/12/5(水) 23:31 -

引用なし
パスワード
   りんさん、neptuneさん、ponpon さん、こんばんは。
3人もの方々からお返事をいただけて、非常に嬉しいです!
皆さん本当に有難う御座います。

りんさんへ
なるほど!そういうやり方もあるんですね。
最初にtfのように設定してしまうというのを思いついたことがなかったですし、
Caseの後にTrueを持ってくるやり方も知らなかったですし、
まさに「目から鱗」という感じです。
有難う御座いました。

neptuneさんへ
>>Caseには、複数のセルに関する条件は設定できないのでしょうか?
>>設定できるにしても、やり方が違っているのでしょうか?
>やった事は無いですが、Select 節は1つのデータを複数の条件で評価をする
ものですから、出来ないと思います。
そうなんですか。長い間分からなかったことが、やっと分かりました。
非常に勉強になりました。有難う御座います。
重ねて質問してしまって申し訳ないのですが、
Sub t()
Dim r As Range
  Set r = Application.Union(Range("B5"), Range("C5"), Range("D5"))
  MsgBox CheckData(r)
  Set r = Nothing
End Sub
のプログラムで、何故私の求める動きが出来るのでしょうか?
この中に、
「B5は入力あり」かつ「C5は入力なし」かつ「D5は入力あり」
の条件が含まれているのですか?
説明しにくいことだと思いますので、もしもよろしかったら教えて下さい。
それにしても、関数を作ったことがないのですが、関数を使うと、こんなに短くて済むんですね。素晴らしいです!
これからは、関数の勉強をもっとしようと思います。

ponponさんへ
分かりやすいプログラムですね!
初心者の私でも、とても理解しやすいです。
こんなに簡単に出来たんだ、と思ってしまうほどです(笑)
有難う御座いました。

【52845】Re:Caseに複数の条件
発言  ichinose  - 07/12/5(水) 23:32 -

引用なし
パスワード
   こんばんは。

>私はExcelで、イラストロジックを途中まで解いてくれるプログラムを、最終的には作ろうと思っています。

これにCase文が本当に合っているか否かは???ですが・・・。


>そのために、3つのセルに、それぞれ入力されているかされていないかで、異なる動きをするプログラムを作ろうと思っています。
>例えば、
>「B5は入力あり」かつ「C5は入力なし」かつ「D5は入力あり」のとき「「成功!」というメッセージボックスを表示する」
>当てはまらないときは、「「失敗・・・」というメッセージボックスを表示する」
>といった風にです。
>これをCaseで作りたく、下のように作ってみたのですが、思うように動きません。
>
>Sub テスト()
>  Select Case Range("B5,C5,D5")
>      Case Is = Not Empty, Is = Empty, Is = Not Empty
>        MsgBox "成功!"
>      Case Else
>        MsgBox "失敗・・・"
>  End Select
>End Sub
本当に上記のように二つの分岐なら、IF文で十分ですよね??

それとも拡張性を重視してのCase文(将来的に条件が増えても対応可能なため)
なんでしょうか?

あるいは、上記コードは例題としてと言う意味で実際には、もっと
条件が増えることが前提なのでしょうか?

等がわかりませんが・・。

標準モジュールに
'===================================================
Sub main()
  Dim rng As Range
  Dim result As Variant
  Set rng = Range("b5:d5")
  result = Join(Evaluate("if(" & rng.Address & "="""",0,1)"), "")
  Select Case result
   Case "111"
     MsgBox "有有有"
   Case "001"
     MsgBox "無無有"
   Case "101"
     MsgBox "有無有"
   Case Else
     MsgBox Replace(Replace(result, "0", "無"), "1", "有")
   End Select
End Sub

アクティブシートにセルB5〜D5に適当なデータを入力後(未入力も含む)、
上記のmainを実行してみてください。
B5,C5,D5の順序で1がデータ有り、0がデータ無しを意味します。

試してみてください。

【52855】Re:Caseに複数の条件
回答  neptune  - 07/12/6(木) 12:05 -

引用なし
パスワード
   ▼セイチ さん:
こんにちは


>重ねて質問してしまって申し訳ないのですが、
>Sub t()
>Dim r As Range
>  Set r = Application.Union(Range("B5"), Range("C5"), Range("D5"))
>  MsgBox CheckData(r)
>  Set r = Nothing
>End Sub
>のプログラムで、何故私の求める動きが出来るのでしょうか?
>この中に、
>「B5は入力あり」かつ「C5は入力なし」かつ「D5は入力あり」
>の条件が含まれているのですか?
↑はFunction CheckDataで判定しています。ステップ実行で1行ずつ実行
してみて下さい。動きがわかりますから。この辺りは基本ですから
よく勉強して於いてくださいね。

ちょっとサンプルを改造しました。若干ですが、説明を加えましたから
これで解っていただけますかね???

Sub t()
Dim r As Range
'  '変数を使う書き方
'  Set r = Application.Union(Range("B5"), Range("C5"), Range("D5"))
'  If CheckData(r) = True Then
'    MsgBox "条件を満たしています。"
'  Else
'    MsgBox "条件を満たしていません。"
'  End If
'  Set r = Nothing

  '変数を使わない
  If CheckData(Range("B5,C5,D5")) = True Then
    MsgBox "条件を満たしています。"
  Else
    MsgBox "条件を満たしていません。"
  End If
End Sub

'判断部分のみを関数化
'Boolean型を戻しているが、必要に応じ何型でもOK、独自に型を作っても良い
(EnumステートメントをHelpで調べて下さい。)
'引数
'pData Range型:評価したいRange
'戻り値:Boolean型 条件を満たす TRUE、満たさないFALSE を返す
Private Function CheckData(pData As Range) As Boolean
  Dim ret As Boolean
  '「B5は入力あり」かつ「C5は入力なし」かつ「D5は入力あり」のとき「「成功!」
  If (Not IsEmpty(pData(1, 1)) And IsEmpty(pData(1, 2))) And Not IsEmpty(pData(1, 3)) Then
    ret = True
  Else  '他の条件があればelseifにしてここに記述を追加する
    ret = False
  End If
  CheckData = ret
End Function

こうするメリットは、判断条件が変わっても関数部分を書き換えるだけで
Mainプロシージャは変更しなくてすみます。大きなメリットです。

※これはサンプルなので、データチェック、エラーハンドルなどは省略してます
から、そのままで実践には使わない方が身の為です。

詳しくはHelpの
visual basic プログラミングのヒント
 →Sub プロシージャと Function プロシージャの呼び出し
 →オブジェクト変数の作成
などをご覧下さい。

【52889】Re:Caseに複数の条件
お礼  セイチ  - 07/12/7(金) 22:46 -

引用なし
パスワード
   neptuneさん、ichinoseさん、こんばんは。
お返事が遅くなってしまって申し訳ありません。昨晩、何故かサイトにうまく接続出来なかったのです。どうぞお許しください。

neptuneさんへ
詳しい解説を有難う御座います!
おかげで大分理解することが出来ました。
関数は難しそうに感じていて、実はちょっと敬遠していたところがありました。
でも、やっぱり関数は使えた方が良いですよね。
むしろ関数が使えなきゃ、という気もします。
あきらかに勉強不足な私に親切丁寧に教えてくださって、本当に有難う御座いました。
そのような状態で質問したことを、今は少し後悔・反省しています。
(少し、なのは、それでも質問したことで色々学べたからです)
勉強不足な上での質問は、された方はあまり気分の良いものではないかと思います。
申し訳ありませんでした。
これを参考に、もっと勉強して、自分の力で完全に理解してみせようと思います。
言い換えれば、ちょっと出直してきます。
有難う御座いました。

ichinoseさんへ
>本当に上記のように二つの分岐なら、IF文で十分ですよね??
>それとも拡張性を重視してのCase文(将来的に条件が増えても対応可能なため)なんでしょうか?
>あるいは、上記コードは例題としてと言う意味で実際には、もっと条件が増えることが前提なのでしょうか?
そうです。私が挙げたコードは、例えという感じです。
これから、条件がいくつかに増えるので、Caseを使いたいと思いました。
しかし、それ以前に3つのセルにまたがる条件の書き方が分からなかったので、質問させていただきました。
分かりにくかったですよね。申し訳ありませんでした。
そして、参考プログラムを有難う御座います!
参考にさせていただきます。

イラストロジックを解くプログラムは、いくら時間がかかっても良いから、必ず完成させようと思っています。
(出来れば途中までではなくて、最後まで解けるプログラムを)
なので、もしかしたらまた何か質問させてもらいにくるかもしれません。
その質問は、今よりもっとレベルの高い質問だと良いなぁと思います。
その時は、また、よろしかったらご指導ください。

有難う御座いました。

5049 / 13646 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free