エクセルマクロ・VBA達人養成塾 小川です。
キューバ旅行記、その71です。
キューバ屈指の外人向けリゾート地、バラデロにて。
宿の近所にある観光案内所が9時に開くので、それまでの時間つぶし。
宿で簡単な朝食を済ませたあと、さっそく朝の散歩にでました。
すぐにでくわしたのが、この子。
現地のトカゲ君にごあいさつされました。足の踏ん張り方がかわいい ヾ(´ー`)ノ
大通りを渡ると、いよいよビーチです。
実は、バラデロに到着した前の晩にもビーチには行ってみたのですが、そのときはまっくらやみでした。これが2回目。
海が見えてきた~! ヾ(´ー`)ノ
つきました!パラでロビーチ! ヾ(´ー`)ノ
すっげー開放感!! ヾ(´ー`)ノ
全長22kmあるというビーチと、ひたすらカリブ海 ヾ(´ー`)ノ ヾ(´ー`)ノ ヾ(´ー`)ノ
そのあまりの気持ちよさに、思わず、魂が抜け出しそうになりました ヾ(´ー`)ノ
..それにしても、この旅行記。
年越ししてしまうとは…(汗
今日は、何かというと。
Instr関数の使い方の、もうちょっとコア…というか、マニアックなお話。
関連する記事は、数日前からのこのあたりです↓。
『「If True Then」なんて書き方でテスト』
『文字列内にある文字列を含んでいるかどうかの判定には、 Instr 関数を! – マクロ・VBA』
Instr関数の結果が0か0より大きいかである文字列の中に指定した文字列があるかどうかを判断できる、というのが前回の内容でした。
例えば、以下のようなデータがあったとしましょう。
|A列 |B列 |C列 |
-------------------------------------------------------------------------------------------
1 行目 |英語 |日本語 |結果 |
-------------------------------------------------------------------------------------------
2 行目 |Breaking out of 25 year base at 2.2%|25年間のベースである2.2%を突破| |
-------------------------------------------------------------------------------------------
ここで、セルA2の中の文字列に、「%」という文字が含まれているかを判断するには、以下のような感じです。
さて、そこで。
今度は、こんなお話。
[1] セルA2かB2かの、どちらかに「%」という文字列があるか
[2] セルA2かB2かの、両方に「%」という文字列があるか
を判定したい場合、どうしましょう?
…ということなんですが。
ベタなやり方だと、論理演算子「Or」や「And」を使って、こんな感じ↓にやります。
Sub sampleand()
If InStr(Range(“A2”).Value, “%”) > 0 And InStr(Range(“B2”).Value, “%”) > 0 Then
Range(“C2”).Value = “両方に存在します”
Else
Range(“C2”).Value = “両方には存在しません”
End If
End Sub
なんですが。
ちょっと、条件判断をしている箇所が、バタバタした感じで落ち着かないですよね。。。
ということで、たまには、こんな書き方↓をしてみたいです。
Sub samplesq()
If InStr(Range(“A2”).Value, “%”) * InStr(Range(“B2”).Value, “%”) > 0 Then
Range(“C2”).Value = “両方に存在します”
Else
Range(“C2”).Value = “両方には存在しません”
End If
End Sub
どういうことかというと。
「複数Instr関数のどれかが0以外の値を返せばよい」ということだから、
Instr関数の戻り値をすべて足していって、その結果が0かどうかを判定すればよい
「複数Instr関数のすべてが0以外の値を返せばよい」ということだから、
Instr関数の戻り値をすべてかけ算していって、その結果が0かどうかを判定すればよい
ということになります。
もともと、論理演算子「Or」とか「And」は、それぞれ、「論理和」、「論理積」を求める演算子です。
算術演算子を使って表現しても、やはり、「 + 」か、「 * 」なんですね。
もっとも、これでも、複数のセル(例えば、セルA2~A11のすべてについて調べる)なんていうときには、
ちょっと大変すぎます。
なので、最後に、そういう場合の解き方を。
例えば、
[3] セルA2~A11のどれかのセルに「%」が含まれているかどうかを調べる
[4] セルB2~B11のすべてのセルに「%」が含まれているかどうかを調べる
というケースについて考えてみましょう。
この[3], [4] は、それぞれ、以下のやり方で解決できます。
Sub samplealleq()
Dim gyo As Long
Dim b As Boolean
b = True
For gyo = 2 To 11
If InStr(Range(“B” & gyo).Value, “%”) = 0 Then
b = False
Exit For
End If
Next
If b Then
Range(“B12”).Value = “すべてが条件を満たしています”
Else
Range(“B12”).Value = “少なくとも一つは条件を満たしていません”
End If
End Sub
Bool型の変数を用意し、For Next構文の始まる前に初期値を設定しておきます。
そして、For Next構文の中で、必要があれば、その変数の値を変更する。
そして、For Next構文が終わったあと、Bool型の変数の値を評価して、条件分岐します。
条件分岐のところの書き方は、数日前のブログ『「If True Then」なんて書き方でテスト』でもやったやり方ですね。
こういうロジックを考えるときには、「For Next構文には、Bool型で宣言した変数の値を変更する以外のことは期待しない」という具合に、機能を絞ったほうがよいです。
機能を絞らず、「For Next構文の中で、条件判断の結果、すぐに結果を出力しよう」とかすると、とたんにややこしくなります。
実際に、ややこしく書いてみた例を紹介しますね。
どちらのほうがプログラム内で個々の作業がより分離しているか、感じ取ってみてください。
Sub samplealleq_damesample()
Dim gyo As Long
Range(“B12”).Value = “すべてが条件を満たしています”
For gyo = 2 To 11
If InStr(Range(“B” & gyo).Value, “%”) = 0 Then
Range(“B12”).Value = “少なくとも一つは条件を満たしていません”
Exit For
End If
Next
End Sub
上記の例では、結果を出力する箇所が、For Next構文の外と中に分離して存在します。
おまけに、「あらかじめセルに値を書き込む」なんてしているので、「エクセルの中の小人ちゃん」がする作業も大がかりになってしまいます。
また、条件を変更したいとか、「結果として出力する文字列を変更したい」といったときにも、メンテナンスが面倒です。
こんな感じのプログラムばっかりだと、行数が増えたときにも、可読性が落ちますね。
参考にしてください。
..ということで。
今日は「複数のInstr関数の結果を上手に利用するには」というお話でした。
本当は、今日、予告していた「若干ヘンタイ」なプログラムを紹介したかったのですか。
当初思っていたより長い記事になってしまったので、「若干ヘンタイ」なプログラムのお話は、年越しで、2012年になってからご紹介しようと思います (^^;;;;;;
それでは、よいお年を (^^)/~