前回の記事はこちら
前回の記事で、
・抽出担当者のデータのみを抜き出して転記する
という、マクロのメイン機能は作成完了しました。
ただ、まだまだ改良の余地はあります。
今回の記事を通して、RangeとCellsを組み合わせ、前回書いた記事をもう少しスマートにしてみましょう。
前回書いた記事は以下の通りですね。
Sub 担当者ごと抽出()
Dim targetName As String
Dim rowLong As Long
Dim exRowLong As Long
targetName = Cells(1, 9).Value
exRowLong = 2
For rowLong = 2 To 16
If Cells(rowLong, 6).Value = targetName Then
'一緒だった時の処理
Debug.Print "担当者名が" & targetName & "と同じです!"
Cells(exRowLong, 11).Value = Cells(rowLong, 1).Value
Cells(exRowLong, 12).Value = Cells(rowLong, 2).Value
Cells(exRowLong, 13).Value = Cells(rowLong, 3).Value
Cells(exRowLong, 14).Value = Cells(rowLong, 4).Value
Cells(exRowLong, 15).Value = Cells(rowLong, 5).Value
Cells(exRowLong, 16).Value = Cells(rowLong, 6).Value
exRowLong = exRowLong + 1
Else
'そうでない時の処理
Debug.Print "担当者名が" & targetName & "ではありません!"
End If
Next
End Sub
20行ほどのコードなので、大して長いわけでもありません。
ただ、A列~F列の値をK列からP列に代入する部分がちょっと長ったらしいですね。
今回はここをスマートにしてみます。
Rangeの使い方
「え?Rangeの使い方はもうやったでしょ?」と思われそうですが、実はRangeの使い方は
Range("A1")
のような書き方以外にもあります。
そもそもRangeは「範囲」という意味だと一度説明したことがありますよね。
「範囲」なのに、これまで"A1"のように、一つのセルしか表現してきませんでした。
「範囲」と言うくらいなので、当然複数のセルを表現することが出来ます。
例えばこんな感じです。
Range("A1:A10")
このように書けば、A1セルからA10セルまでの連続した範囲を表現できます。
ただ、この書き方をするのには少しデメリットがあります。
もし今回作ったマクロのように、「何行目」という数値を変数を使って表したい場合、以下のように書く必要があります。
Range("A" & rowA & ":A" & rowB)
…なんか、めちゃくちゃ見づらくないですか?
何をしているかと言うと、何行目という数値を無理やり&を使って結合し、結果としてRangeの中に"A1:A10"のような文字列が出来るようにしているんですね。
駄目ではないですが、正直オススメはしません。
Rangeで範囲を表すには、以下の書き方を使うようにしましょう。
Range(Cells(1,1),Cells(2,3))
はい、こっちの方が慣れるまでは難しく見えると思いますが、慣れるとすごく楽です。
どういう書き方かと言うと、Rangeの中に2つのセルを指定しています。
1つ目のセルから2つ目のセルまでの範囲がこの書き方で表現出来る、ということです。
Cells(1,1)=A1セル
Cells(2,3)=C2セル
つまりRange(Cells(1,1),Cells(2,3))は
上の画像のような範囲、ということになります!
今回のマクロではA列からF列の値をK列からP列に代入するので、
Cells(exRowLong, 11).Value = Cells(rowLong, 1).Value
Cells(exRowLong, 12).Value = Cells(rowLong, 2).Value
Cells(exRowLong, 13).Value = Cells(rowLong, 3).Value
Cells(exRowLong, 14).Value = Cells(rowLong, 4).Value
Cells(exRowLong, 15).Value = Cells(rowLong, 5).Value
Cells(exRowLong, 16).Value = Cells(rowLong, 6).Value
この部分が…
Range(Cells(exRowLong, 11),Cells(exRowLong, 16)).Value = Range(Cells(rowLong, 1),Cells(rowLong, 6)).Value
こうなります!
6列分それぞれ1行ずつ書いていたものが、1行で済むのは楽ですよね。
というわけで、コード全体はこんな感じになりました。
Sub 担当者ごと抽出()
Dim targetName As String
Dim rowLong As Long
Dim exRowLong As Long
targetName = Cells(1, 9).Value
exRowLong = 2
For rowLong = 2 To 16
If Cells(rowLong, 6).Value = targetName Then
'一緒だった時の処理
Debug.Print "担当者名が" & targetName & "と同じです!"
Range(Cells(exRowLong, 11),Cells(exRowLong, 16)).Value = Range(Cells(rowLong, 1),Cells(rowLong, 6)).Value
exRowLong = exRowLong + 1
Else
'そうでない時の処理
Debug.Print "担当者名が" & targetName & "ではありません!"
End If
Next
End Sub
実行結果は同じですが、かなりスマートになりましたね!
このように、RangeとCellsを組み合わせて使うと、同じことをやっていても簡単に書けたりするので、知識があるのと無いのとではかなり違ってくることが分かると思います。
知識は重要!でもやり過ぎ注意!
VBAを学ぶにつれて、色々工夫した書き方を知ることになると思います。
ただ、スマートな書き方を追求するあまり、コード自体は短くても他人が見て何をしているか分からないような書き方をしてしまうと本末転倒です。
他人が分からないということは、時間が経てば自分自身にもわかりにくい書き方をしてしまっている、ということになります。
スマートな書き方をするのが目的ではなく、あくまで目的は求めている処理を実現するマクロを作ることであり、その処理を実現するために分かりやすい書き方や、処理速度の速い書き方をするのだ、ということを忘れないようにしましょう。
次回予告
少し短いですが、今回はここまでにします。(前回の記事が長かったですし)
Excelマクロを作る以上、セルの範囲指定は基本ですがとても重要です。Cellsを使う方法、Rangeを使う方法だけでなく、CellsとRangeを組み合わせた今回のような書き方も、出来れば調べずに書けるようにしておきましょう。
さて、次の記事では「繰り返し回数を行数に応じて変化させる方法」を紹介します。
現在のマクロでは決まった行数以上のデータになると対応出来ないので、行数が存在する分繰り返し処理が行われるような買い方をいくつか紹介します。
今回の内容で分かりづらかったこと、「こういうやり方はどうか」という質問などございましたら、ぜひ有料サポートをご利用下さい。出来るだけ迅速に、丁寧に対応致します。
今回もお疲れ様でした!