3日がかりのその仕事、3分で終わらせる方法教えます!
パソコンスキルの心技体

複数のInstr関数の結果を上手に利用するには – Excel マクロ・VBA

2011年12月31日
  • このエントリーをはてなブックマークに追加
  • follow us in feedly

エクセルマクロ・VBA達人養成塾 小川です。

キューバ旅行記、その71です。

キューバ屈指の外人向けリゾート地、バラデロにて。

エクセルマクロ達人養成塾塾長ブログ-朝食のあと、散歩に出ました。

宿の近所にある観光案内所が9時に開くので、それまでの時間つぶし。
宿で簡単な朝食を済ませたあと、さっそく朝の散歩にでました。

エクセルマクロ達人養成塾塾長ブログ-現地のトカゲ君にごあいさつされました。

すぐにでくわしたのが、この子。
現地のトカゲ君にごあいさつされました。足の踏ん張り方がかわいい ヾ(´ー`)ノ

エクセルマクロ達人養成塾塾長ブログ-通りを渡って、いよいよビーチへ!

大通りを渡ると、いよいよビーチです。
実は、バラデロに到着した前の晩にもビーチには行ってみたのですが、そのときはまっくらやみでした。これが2回目。

エクセルマクロ達人養成塾塾長ブログ-海が見えてきた~! ヾ(´ー`)ノ

海が見えてきた~! ヾ(´ー`)ノ

エクセルマクロ達人養成塾塾長ブログ-つきました!パラでロビーチ! ヾ(´ー`)ノ

つきました!パラでロビーチ! ヾ(´ー`)ノ

すっげー開放感!! ヾ(´ー`)ノ

全長22kmあるというビーチと、ひたすらカリブ海 ヾ(´ー`)ノ ヾ(´ー`)ノ ヾ(´ー`)ノ

そのあまりの気持ちよさに、思わず、魂が抜け出しそうになりました ヾ(´ー`)ノ

..それにしても、この旅行記。
年越ししてしまうとは…(汗

塾長のキューバ旅行記、最初から読みたい方はこちらから


複数のInstr関数の結果を上手に利用するには – Excel マクロ・VBA

今日は、何かというと。

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の中の文字列に、「%」という文字が含まれているかを判断するには、以下のような感じです。

Sub sample1()
    If InStr(Range(“A2”).Value, “%”) > 0 Then
        Range(“C2”).Value = “存在します”
    Else
        Range(“C2”).Value = “存在しません”
    End If
End Sub

さて、そこで。

今度は、こんなお話。

[1] セルA2かB2かの、どちらかに「%」という文字列があるか
[2] セルA2かB2かの、両方に「%」という文字列があるか

を判定したい場合、どうしましょう?

…ということなんですが。

ベタなやり方だと、論理演算子「Or」や「And」を使って、こんな感じ↓にやります。

Sub sampleor()
    If InStr(Range(“A2”).Value, “%”) > 0 Or InStr(Range(“B2”).Value, “%”) > 0 Then
        Range(“C2”).Value = “少なくともどちらかに存在します”
    Else
        Range(“C2”).Value = “どちらにも存在しません”
    End If
End Sub

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 samplead()
    If InStr(Range(“A2”).Value, “%”) + 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

どういうことかというと。

[1] セルA2かB2かの、どちらかに「%」という文字列があるか

「複数Instr関数のどれかが0以外の値を返せばよい」ということだから、

Instr関数の戻り値をすべて足していって、その結果が0かどうかを判定すればよい

[2] セルA2かB2かの、両方に「%」という文字列があるか

「複数Instr関数のすべてが0以外の値を返せばよい」ということだから、

Instr関数の戻り値をすべてかけ算していって、その結果が0かどうかを判定すればよい

ということになります。

もともと、論理演算子「Or」とか「And」は、それぞれ、「論理和」、「論理積」を求める演算子です。

算術演算子を使って表現しても、やはり、「 + 」か、「 * 」なんですね。

もっとも、これでも、複数のセル(例えば、セルA2~A11のすべてについて調べる)なんていうときには、
ちょっと大変すぎます。

なので、最後に、そういう場合の解き方を。

例えば、

[3] セルA2~A11のどれかのセルに「%」が含まれているかどうかを調べる
[4] セルB2~B11のすべてのセルに「%」が含まれているかどうかを調べる

というケースについて考えてみましょう。

この[3], [4] は、それぞれ、以下のやり方で解決できます。

Sub sampleallad()
    Dim gyo As Long
    Dim b As Boolean
    
    b = False
    For gyo = 2 To 11
        If InStr(Range(“A” & gyo).Value, “%”) > 0 Then
            b = True
            Exit For
        End If
    Next
    If b Then
        Range(“A12”).Value = “少なくともひとつは条件を満たしています”
    Else
        Range(“A12”).Value = “条件を満たしているものはひとつもありません”
    End If
End Sub

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 sampleallad_damesample()
    Dim gyo As Long
    
    Range(“A12”).Value = “条件を満たしているものはひとつもありません”
    For gyo = 2 To 11
        If InStr(Range(“A” & gyo).Value, “%”) > 0 Then
            Range(“A12”).Value = “少なくともひとつは条件を満たしています”
            Exit For
        End If
    Next
End Sub

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年になってからご紹介しようと思います (^^;;;;;;

それでは、よいお年を (^^)/~

キーワード

コメント

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

最新の記事

人気記事

最新記事

カテゴリ

最新コメント

タグクラウド