【条件分岐処理でセルの操作を分ける】
1 もしA列がXのときはエックスを実行
2 もしA列が、Xのときはエックス、Yのときはワイを実行
3 もしA列が、Xのときはエックス、その他のときはソノタを実行
4 もしA列がXかつB列がXのときはエックスを実行
5 もしA列がXまたはB列がXのときはエックスを実行
「三つ目の基本構造、それは条件分岐処理です。
条件分岐処理をつかえば、条件によって処理を分けることができます。
ここで、条件分岐処理のもっとも基本的な構文として、If文を紹介します。」
「If文とはどういう意味ですか。」
「Excel VBA/マクロのIf文とは、
もしA列がXのときはエックスを実行するというように、
条件式に当てはまったとき、処理を実行するということです。
信号機に例えると、
もし赤のときは止まれ
ということです。
今回は、セルの値が特定の文字のときに、その右隣りのセルに文字を書きこむようにします。
予め、1~5行目・1列目のセルに『X』、『Z』、『Y』、『』、『X』という値を入れておきましょう。」
「セルの値がAのとき、同じ行で別の列のセルに変数を書きこむというケースでは、次のような構文になります。」
「1行目・1列目のセルの値が『X』のときは、1行目・2列目のセルに『エックス』と書きこんでみましょう。
列番号を定数『読取列』と『書込列』、行番号を変数『行番号』としましょう。」
「1行目・1列目のセルの値を読みとり、1行目・2列目のセルの値に書きこむのだから、
『読取列』の値を1として定数宣言 Const 読取列 = 1
『書込列』の値を2として定数宣言 Const 書込列 = 2
『行番号』を整数型として変数宣言 Dim 行番号 As Integer
そして、変数『行番号』に1を設定 行番号 = 1と記述します。
次に、セルの値がAのとき、同じ行で別の列のセルに変数を書きこむ書きこむ構文をつかってみます。
1行目・1列目のセルの値が『X』のときは、1行目・2列目のセルに『エックス』と書きこむのだから、
If Cells(行番号, 読取列).Value = "X" Then
Cells(行番号, 書込列).Value = "エックス"
End If
で良いのでしょうか。」
Sub 一つの条件式に当てはまったときに処理1()
Const 読取列 = 1
Const 書込列 = 2
Dim 行番号 As Integer
行番号 = 1
If Cells(行番号, 読取列).Value = "X" Then
Cells(行番号, 書込列).Value = "エックス"
End If
End Sub
「その通りです。『If Cells(行番号, 読取列).Value = "X" Then』から『End If』までが、
条件分岐処理のブロックとなっていて、If文の条件式に当てはまったときだけ
『Cells(行番号, 書込列).Value = "エックス"』が実行される処理となっています。
If文の条件式でつかわれる『=』は、左辺と右辺が等しいことを意味する等号記号です。
『Cells(行番号, 読取列).Value = "X"』は、指定したセルの値と『X』が等しいという意味です。
つまり、
If Cells(行番号, 読取列).Value = "X" Then
Cells(行番号, 書込列).Value = "エックス"
End If
とは、指定したセルの値が『X』のとき、特定のセルに『エックス』と書きこむという意味です。」
「『End If』はどういう意味ですか。If文を記述するときに『End If』を省略することはできますか。」
「『End If』は、条件分岐処理のブロックの終わりを意味します。
今回は、『Cells(行番号, 書込列).Value = "エックス"』というように、条件式に当てはまったときに
実行される処理が一つだけですが、条件式に当てはまったときに実行される処理は、場合によっては
一つだけとは限らず2・3個から数十個のときもあります。
そうしたときに、条件式に当てはまったときに実行される処理が
どこまでかを明確にするために、『End If』がつかわれます。
『If』から条件分岐処理を記述するときは必ず『End If』で締めくくる必要があり、
If文を記述するときに『End If』を省略することは絶対にできません。」
「わかりました。条件分岐処理の始まりとして『If』を書き始めたときは、
条件分岐処理ブロックの締めくくりとなる『End If』をブロックの最後に必ず記述するようにします。」
「それでは、そのマクロを実行してみましょう。」
「1列目、1行目のセルの値が『X』だったので、2列目、1行目のセルに『エックス』と書きこまれました。」
「次は、2行目・1列目のセルの値が『X』のときは、2行目・2列目のセルに『エックス』と書きこんでみましょう。」
「今度の問題は、一つ前につくったIf文が利用できそうですね。」
「その通りです。実は一つ前につくったマクロを一か所書きかえるだけでいいのです。」
「一つ前の問題は、『1行目・1列目のセルの値が『X』のときは、1行目・2列目のセルに『エックス』と書きこむ』のに対して、
今度の問題は、『2行目・1列目のセルの値が『X』のときは、2行目・2列目のセルに『エックス』と書きこむ』ということで、
変数『行』の値が変わるだけですね。さきほどのマクロの『行番号 = 1』を『行番号 = 2』に書きかえます。」
Sub 一つの条件式に当てはまったときに処理2()
Const 読取列 = 1
Const 書込列 = 2
Dim 行番号 As Integer
行番号 = 2
If Cells(行番号, 読取列).Value = "X" Then
Cells(行番号, 書込列).Value = "エックス"
End If
End Sub
「『行番号 = 2』に書きかわりました。それでは、そのマクロを実行してみましょう。」
「1列目、2行目のセルの値は『X』ではないので、2列目、2行目のセルに『エックス』は書きこまれませんでした。」
「1~5行目・1列目のセルの値が『X』のときは、同じ行で2列目のセルに『エックス』と書きこんでみましょう。」
「1~5行目のセルの値を読みとるということは、行番号をカウントアップするループ処理が利用できそうですね。」
「いいところに気が付きましたね。多数のセルの値を読みとるときは、ループ処理を利用すれば、
プログラム量が一気に圧縮できて、読みやすいコードとなりますし、マクロの処理時間も短縮されます。
今回は、For文(ループ処理)のブロックの中に、If文(条件分岐処理)のブロックを組みこんでみましょう。
次のような構文になります。」
「変数宣言は、先ほどと同じにします。次に、For文(ループ処理)のブロックの中に、
If文(条件分岐処理)のブロックを組みこむ構文をつかってみます。
1~5行目・1列目のセルの値が『X』のときは、同じ行で2列目のセルに『エックス』と書きこむのだから、
For 行番号 = 1 To 5
If Cells(行番号, 読取列).Value = "X" Then
Cells(行番号, 書込列).Value = "エックス"
End If
Next
で良いのでしょうか。」
Sub ループブロックで一つの条件式に当てはまったときに処理1()
Const 読取列 = 1
Const 書込列 = 2
Dim 行番号 As Integer
For 行番号 = 1 To 5
If Cells(行番号, 読取列).Value = "X" Then
Cells(行番号, 書込列).Value = "エックス"
End If
Next
End Sub
「その通りです。それでは、いったん2列目のセルの値をクリアしてから、そのマクロを実行してみましょう。」
「1列目、1・5行目のセルの値が『X』だったので、2列目、1・5行目のセルに『エックス』と書きこまれました。」
「1~5行目・1列目のセルの値が『Y』のときは、同じ行で2列目のセルに『ワイ』と書きこんでみましょう。」
「変数宣言は、先ほどと同じにします。次に、For文(ループ処理)のブロックの中に、
If文(条件分岐処理)のブロックを組みこむ構文をつかってみます。
1~5行目・1列目のセルの値が『Y』のときは、同じ行で2列目のセルに『ワイ』と書きこむのだから、
For 行番号 = 1 To 5
If Cells(行番号, 読取列).Value = "Y" Then
Cells(行番号, 書込列).Value = "ワイ"
End If
Next
と記述します。」
Sub ループブロックで一つの条件式に当てはまったときに処理2()
Const 読取列 = 1
Const 書込列 = 2
Dim 行番号 As Integer
For 行番号 = 1 To 5
If Cells(行番号, 読取列).Value = "Y" Then
Cells(行番号, 書込列).Value = "ワイ"
End If
Next
End Sub
「その通りです。それでは、いったんセル範囲『B1:B5』の値をクリアしてから、そのマクロを実行してみましょう。
毎回、手作業でセルの値をクリアするのは面倒でしょうから、ここで自動でセルの値をクリアするメソッドを伝えておきます。」
「『ClearContents』は、セルの値をクリアするときに使うメソッドです。
メソッドとはオブジェクトを操作する命令文のことです。
セル範囲『B1:B5』の値をクリアするため、
Range("B1:B5").ClearContents
という一文を変数宣言の後、ループブロックの前に記述しましょう。
このように、予めセルの値をクリアしておくような処理、
つまり、本処理を行う前の準備処理のことを初期化処理といいます。」
Sub ループブロックで一つの条件式に当てはまったときに処理2C()
Const 読取列 = 1
Const 書込列 = 2
Dim 行番号 As Integer
Range("B1:B5").ClearContents
For 行番号 = 1 To 5
If Cells(行番号, 読取列).Value = "Y" Then
Cells(行番号, 書込列).Value = "ワイ"
End If
Next
End Sub
「それでは、そのマクロを実行してみましょう。」
「1列目、3行目のセルの値が『Y』だったので、2列目、3行目のセルに『ワイ』と書きこまれました。」
「1~5行目・1列目のセルに値が入ってないときは、同じ行で2列目のセルに『空白』と書きこんでみましょう。
値が空っぽの状態は、『””』(ダブルコーテーションY2) と表すことができます。
セルに値が入ってない状態は、
『Cells(行, 列).Value = ""』と表すことができます。」
「変数宣言は、先ほどと同じにします。
初期化処理として、セル範囲『B1:B5』の値をクリア。
そして、For文(ループ処理)のブロックの中に、If文(条件分岐処理)のブロックを組みこむ
構文をつかいます。
1~5行目・1列目のセルに値が入ってないときは、同じ行で2列目のセルに『空白』と書きこむのだから、
For 行番号 = 1 To 5
If Cells(行番号, 読取列).Value = "" Then
Cells(行番号, 書込列).Value = "空白"
End If
Next
と記述します。」
Sub ループブロックで一つの条件式に当てはまったときに処理3()
Const 読取列 = 1
Const 書込列 = 2
Dim 行番号 As Integer
Range("B1:B5").ClearContents
For 行番号 = 1 To 5
If Cells(行番号, 読取列).Value = "" Then
Cells(行番号, 書込列).Value = "空白"
End If
Next
End Sub
「その通りです。それでは、そのマクロを実行してみましょう。」
「1列目、4行目のセルの値が『』、つまり、値が入っていなかったので、2列目、4行目のセルに『空白』と書きこまれました。」
「1~5行目・1列目のセルに値が入っているときは、同じ行で2列目のセルに『英字』と書きこんでみましょう。
セルに値が入っている状態は、『Cells(行, 列).Value <> ""』と表すことができます。
If文の条件式でつかわれる『<>』は、左辺と右辺が等しくないことを意味する不等号記号です。
『Cells(行, 列).Value <> ""』は、セルの値が空白でない、つまり、セルに値が入っている
という意味です。」
「変数宣言は、先ほどと同じにします。
初期化処理として、セル範囲『B1:B5』の値をクリア。
そして、For文(ループ処理)のブロックの中に、If文(条件分岐処理)のブロックを組みこむ
構文をつかいます。
1~5行目・1列目のセルに値が入っているときは、同じ行で2列目のセルに『英字』と書きこむのだから、
For 行番号 = 1 To 5
If Cells(行番号, 読取列).Value <> "" Then
Cells(行番号, 書込列).Value = "英字"
End If
Next
と記述します。」
Sub ループブロックで一つの条件式に当てはまったときに処理4()
Const 読取列 = 1
Const 書込列 = 2
Dim 行番号 As Integer
Range("B1:B5").ClearContents
For 行番号 = 1 To 5
If Cells(行番号, 読取列).Value <> "" Then
Cells(行番号, 書込列).Value = "英字"
End If
Next
End Sub
「その通りです。それでは、そのマクロを実行してみましょう。」
「1列目、1・2・3・5行目のセルの値が『』でなかった、つまり、値が入っていたので、
2列目、1・2・3・5行目のセルに『英字』と書きこまれました。」
「1~5行目・1列目のセルの値が『X』でないときは、同じ行で2列目のセルに『エックスでない』と書きこんでみましょう。
セルの値がAでない場合という条件式を表すときは、左辺と右辺が等しくないことを意味する
不等号記号『<>』がつかわれます。」
「変数宣言は、先ほどと同じにします。
初期化処理として、セル範囲『B1:B5』の値をクリア。
そして、For文(ループ処理)のブロックの中に、If文(条件分岐処理)のブロックを組みこむ
構文をつかいます。
1~5行目・1列目のセルの値が『X』でないときは、同じ行で2列目のセルに『エックスでない』と書きこむのだから、
For 行番号 = 1 To 5
If Cells(行番号, 読取列).Value <> "X" Then
Cells(行番号, 書込列).Value = "エックスでない"
End If
Next
と記述します。」
Sub ループブロックで一つの条件式に当てはまったときに処理5()
Const 読取列 = 1
Const 書込列 = 2
Dim 行番号 As Integer
Range("B1:B5").ClearContents
For 行番号 = 1 To 5
If Cells(行番号, 読取列).Value <> "X" Then
Cells(行番号, 書込列).Value = "エックスでない"
End If
Next
End Sub
「その通りです。それでは、そのマクロを実行してみましょう。」
「1列目、2・3・4行目のセルの値が『X』でなかったので、2列目、2・3・4行目のセルに『エックスでない』
と書きこまれました。」
「このように、For文(ループ処理)のブロックの中に、If文(条件分岐処理)のブロックを組みこむ
構文をつかえば、ループブロックで一つの条件式に当てはまったときに特定の処理をすることができます。
試しに、『開始行』・『終了行』の各変数に設定する値、条件式の右辺に設定する値、セルに書きこむ値を
適当な数字や文字に書きかえて、マクロを実行して、ループブロックで一つの条件式に当てはまったときに
特定の処理を自由自在にすることができることを確かめてみましょう。
(1) 1~5行目・1列目のセルの値が『Z』のときは、同じ行で2列目のセルに『ゼット』と、
(2) 2~4行目・1列目のセルの値が『Z』のときは、同じ行で2列目のセルに『ゼット』と、
(3) 1~5行目・1列目のセルの値が『Z』でないときは、同じ行で2列目のセルに『ゼットでない』と、書きこんでみましょう。
演習(1):マクロ『ループブロックで一つの条件式に当てはまったときに処理』
1~5行目・1列目のセルの値が『Z』のときは、同じ行で2列目のセルに『ゼット』と書きこむ
Sub ループブロックで一つの条件式に当てはまったときに処理()
Const 読取列 = 1
Const 書込列 = 2
Dim 行番号 As Integer
Range("B1:B5").ClearContents
For 行番号 = 1 To 5
If Cells(行番号, 読取列).Value = "Z" Then
Cells(行番号, 書込列).Value = "ゼット"
End If
Next
End Sub
演習(2):マクロ『ループブロックで一つの条件式に当てはまったときに処理』
2~4行目・1列目のセルの値が『Z』のときは、同じ行で2列目のセルに『ゼット』と書きこむ
Sub ループブロックで一つの条件式に当てはまったときに処理()
Const 読取列 = 1
Const 書込列 = 2
Dim 行番号 As Integer
Range("B1:B5").ClearContents
For 行番号 = 2 To 4
If Cells(行番号, 読取列).Value = "Z" Then
Cells(行番号, 書込列).Value = "ゼット"
End If
Next
End Sub
演習(3):マクロ『ループブロックで一つの条件式に当てはまったときに処理』
1~5行目・1列目のセルの値が『Z』でないときは、同じ行で2列目のセルに『ゼットでない』と書きこむ
Sub ループブロックで一つの条件式に当てはまったときに処理()
Const 読取列 = 1
Const 書込列 = 2
Dim 行番号 As Integer
Range("B1:B5").ClearContents
For 行番号 = 1 To 5
If Cells(行番号, 読取列).Value <> "Z" Then
Cells(行番号, 書込列).Value = "ゼットでない"
End If
Next
End Sub
今回は、For文(ループ処理)のブロックの中に、If文(条件分岐処理)のブロックを組みこむ構文をつかえば、
ループブロックで一つの条件式に当てはまったときに特定の処理をすることができるという話でした。
では、ループブロックで二つ以上の各条件式に当てはまったときに、それぞれの処理を実行するには
どうすればよいのでしょうか。
これについては、次回『もしA列が、Xのときはエックス、Yのときはワイを実行』で紹介します。」
◇もしもPython-xlwingsだったら、
2023-03-19
2021-12-20
2021-12-12