前回ご案内した方法で、該当の項目の位置を特定することができました。
前回は、レコードが7つだけだったので、そこまで重い処理ではありませんでしたが、
これが何千何万というレコードになると、処理が長くなってしまったり、
最悪画面がホワイトアウトして、何も出来なくなってしまう場合もあります。
1レコードの処理が終わる度に発生する、
ActiveCell.Offset(1).Select が、実は重くなる原因なのです。
都度「今選択されているセルの、1つ下のセルを選択する」という作業が、入ってくるためです。
とかくマクロは、セルを選択/セルの削除/列の追加•削除/行の追加•削除等の、
実際人の手で行う場合、右クリックを伴うようなことをすると、重くなります。
試しに、こんな表を用意してみました。
ただセルの位置をセルに記載しただけのものです。
セルの位置を指定する方法として、3つありますが、
その中でも、Cells(行の番号,列の番号) を、使いたいと思います。
ご覧いただいた通り、行と列の番号を用いて、座標のように位置を指定することができます。
つまり、Cells(2,3)とすると、2行目の3列目になりますので、C2セルが選択されることになります。
そして、この指定方法は、変数を使うことができます。
早速、変数を設定し、C2セルを選択してみたいと思います。
〜〜〜ここから〜〜〜
Sub 変数を使ってC2セルを選択()
Dim r As Integer
r = 2
Dim i As Integer
i = 3
Cells(r, i).Select
End Sub
〜〜〜ここまで〜〜〜
和訳すると、以下ようになります。
Dim r As Integer(変数rを整数型として設定)し、
r = 2(rを2)にします。
Dim i As Integer(変数iを整数型として設定)し、
i = 3(iを3)にします。
Cells(r, i).Select(r行目のi列目のセルを選択する)
これで、しっかりC2セルが選択されます。
前回は、レコードが7つだけだったので、そこまで重い処理ではありませんでしたが、
これが何千何万というレコードになると、処理が長くなってしまったり、
最悪画面がホワイトアウトして、何も出来なくなってしまう場合もあります。
1.処理が重くなる原因
その理由は、「セルを選択する」という処理が、レコードの数だけ発生してしまうからです。1レコードの処理が終わる度に発生する、
ActiveCell.Offset(1).Select が、実は重くなる原因なのです。
都度「今選択されているセルの、1つ下のセルを選択する」という作業が、入ってくるためです。
とかくマクロは、セルを選択/セルの削除/列の追加•削除/行の追加•削除等の、
実際人の手で行う場合、右クリックを伴うようなことをすると、重くなります。
2.変数を使ってセルを指定する
都度セルを選択しない方法として、変数を使用していきます。試しに、こんな表を用意してみました。
ただセルの位置をセルに記載しただけのものです。
セルの位置を指定する方法として、3つありますが、
その中でも、Cells(行の番号,列の番号) を、使いたいと思います。
ご覧いただいた通り、行と列の番号を用いて、座標のように位置を指定することができます。
つまり、Cells(2,3)とすると、2行目の3列目になりますので、C2セルが選択されることになります。
そして、この指定方法は、変数を使うことができます。
早速、変数を設定し、C2セルを選択してみたいと思います。
〜〜〜ここから〜〜〜
Sub 変数を使ってC2セルを選択()
Dim r As Integer
r = 2
Dim i As Integer
i = 3
Cells(r, i).Select
End Sub
〜〜〜ここまで〜〜〜
和訳すると、以下ようになります。
Dim r As Integer(変数rを整数型として設定)し、
r = 2(rを2)にします。
Dim i As Integer(変数iを整数型として設定)し、
i = 3(iを3)にします。
Cells(r, i).Select(r行目のi列目のセルを選択する)
これで、しっかりC2セルが選択されます。
3.都度セルの移動をせずに、処理を進める
それでは、今までの方法を踏まえて、都度セルの移動をせずに処理を進めてみたいと思います。
前回のマクロは、以下の通りです。
〜〜〜ここから〜〜〜
Sub 人口5000千以上に○()
Dim ColumnNo_人口 As Integer
ColumnNo_人口 = 1
Do
If Cells(1, ColumnNo_人口).Value = "人口(1,000人)" Or Cells(1, ColumnNo_人口).Value = "" Then
Exit Do
End If
ColumnNo_人口 = ColumnNo_人口 + 1
Loop
Cells(2, ColumnNo_人口).Select
Do
If ActiveCell.Value = "" Then
Exit Do
ElseIf ActiveCell.Value >= 5000 Then
ActiveCell.Offset(0, 1).Value = "○"
End If
ActiveCell.Offset(1).Select
Loop
End Sub
Sub 人口5000千以上に○()
Dim ColumnNo_人口 As Integer
ColumnNo_人口 = 1
Do
If Cells(1, ColumnNo_人口).Value = "人口(1,000人)" Or Cells(1, ColumnNo_人口).Value = "" Then
Exit Do
End If
ColumnNo_人口 = ColumnNo_人口 + 1
Loop
Cells(2, ColumnNo_人口).Select
Do
If ActiveCell.Value = "" Then
Exit Do
ElseIf ActiveCell.Value >= 5000 Then
ActiveCell.Offset(0, 1).Value = "○"
End If
ActiveCell.Offset(1).Select
Loop
End Sub
〜〜〜ここまで〜〜〜
まずは、赤字にした部分を改修していきます。
まずは、赤字にした部分を改修していきます。
- Cells(2, ColumnNo_人口).Select
ここの部分については、変数を設定するだけでOKです。
Dim r As Integer
r = 2 - ActiveCell.Value
ここの部分は、Cellsと変数を用いて表現します。
Cells(r, ColumnNo_人口).Value - ActiveCell.Offset(0, 1).Value
ここも同様に、Cellsと変数を用います。
但し、列については、1つ右になりますので、変数+1とします。
Cells(r, ColumnNo_人口 + 1).Value - ActiveCell.Offset(1).Select
最後にここは、セルの選択が不要で、行を示しているrという変数が
1ずつ増えいけばいいので、以下のようになります。
r = r + 1
(rの値を、r+1の値にしてくださいという処理)
では、書き換えていきましょう。
〜〜〜ここから〜〜〜
Sub 人口5000千以上に○()
Dim ColumnNo_人口 As Integer
ColumnNo_人口 = 1
Do
If Cells(1, ColumnNo_人口).Value = "人口(1,000人)" Or Cells(1, ColumnNo_人口).Value = "" Then
Exit Do
End If
ColumnNo_人口 = ColumnNo_人口 + 1
Loop
Dim r As Integer
r = 2
Do
If Cells(r, ColumnNo_人口).Value = "" Then
Exit Do
ElseIf Cells(r, ColumnNo_人口).Value >= 5000 Then
Cells(r, ColumnNo_人口 + 1).Value = "○"
End If
r = r + 1
Loop
End Sub
〜〜〜ここまで〜〜〜
これで、セルを選択する処理が無くなったので、軽くなりました。
また、セルの選択が無いので、画面上の動きも無くなります。
マクロを起動する際に、選択されていたセルは、そのままになります。
4.まとめ
行番号を変数として、処理を進めていくマクロが組めれば、
データ精査系については、ほぼ出来るようになったと言っても過言ではないかと思います。
効率的な業務と、スピーディな処理のために活用いただければ幸いです。
それではまた
コメント
コメントを投稿