エクセルマクロ・VBA達人養成塾 小川です。
キューバ旅行記、その75です。
キューバ屈指の外人向けリゾート地、バラデロにて、自転車でフラフラ移動中です。
あまりの暑さに思わず日陰を求めて入ったレストラン。
これは、アルコールの入った氷。名前忘れた。
鶏肉のプレート。
店に飾られた、キューバとその他の国の国旗。
日本のものもありました。
そして、ややよっぱらいつつも、また海へ ヾ(´ー`)ノ
塾長のキューバ旅行記、最初から読みたい方はこちらから
複数セルでの処理を高速化したい – その2
えー。前回と、タイトルが微妙に異なっていますが…。
前回のつづきです。
前回のブログ: 複数セルに値を入れる処理を高速化したい
昨日、ご紹介したコード。
Sub KaihenCode2()
Dim wsSche As Worksheet
Dim dtTo As Date
Dim cHiduke As Long
Dim cName As Long
dtTo = #1/1/2012#
Set wsSche = Worksheets(“スケジュール”)
Dim rB As Range
Set rB = wsSche.Range(“C13,C16,C19,C22,C25,C28,C31,C34,C37,C40,C43”)
Do While Month(dtTo) = 1
cHiduke = Day(dtTo)
‘入力月の日付を入力
wsSche.Range(“C10”).Offset(, cHiduke).Value = Day(dtTo)
‘曜日を入力
wsSche.Range(“C11”).Offset(, cHiduke).Value = WeekdayName(Weekday(dtTo), True)
If Weekday(dtTo) = 1 Or Weekday(dtTo) = 7 Then
With rB.Offset(, cHiduke)
.Value = “○”
.Font.Size = 11
.Font.Bold = True
.HorizontalAlignment = xlCenter
End With
End If
dtTo = DateAdd(“d”, 1, dtTo)
Loop
End Sub
まだ、実際にセルに値を入れたりフォントサイズを変更したり、といった実際の処理をする回数が多い。
ということで、僕なら、さらにこうします。
Sub KaihenCode3()
Dim wsSche As Worksheet
Dim dtTo As Date
Dim cHiduke As Long
Dim cName As Long
dtTo = #1/1/2012#
Set wsSche = Worksheets(“スケジュール”)
Dim rB As Range
Set rB = wsSche.Range(“C13,C16,C19,C22,C25,C28,C31,C34,C37,C40,C43”)
Dim rTgt As Range ‘[1]
Do While Month(dtTo) = 1
cHiduke = Day(dtTo)
‘入力月の日付を入力
wsSche.Range(“C10”).Offset(, cHiduke).Value = Day(dtTo)
‘曜日を入力
wsSche.Range(“C11”).Offset(, cHiduke).Value = WeekdayName(Weekday(dtTo), True)
If Weekday(dtTo) = 1 Or Weekday(dtTo) = 7 Then
‘[2]
If rTgt Is Nothing Then
Set rTgt = rB.Offset(, cHiduke)
Else
Set rTgt = Union(rTgt, rB.Offset(, cHiduke))
End If
 
; ‘[3]
End If
dtTo = DateAdd(“d”, 1, dtTo)
Loop
‘[4]
With rTgt
.Value = “○”
.Font.Size = 11
.Font.Bold = True
.HorizontalAlignment = xlCenter
End With
End Sub
えー、何かと言いますと。
「Unionメソッド」というメソッドがありまして。
「引数として受け取ったセル範囲をすべて含んだセル範囲を返す」というものです。
以下、簡単なサンプルコード。実行してみてください。
Sub UniSample1()
Dim r As Range
Set r = Union(Range(“A1:C5”), Range(“B4:F8”))
r.Select
End Sub
ヘルプを見ると分かりますが、「Unionメソッド」は、最低でも、2つの引数を必要とします。
そして、2つの引数は、ともに、 Nothing ではダメです。
例えば、以下の例では、Unionメソッドを実行しようとしたところで、エラーが出て処理が止まります。
Sub UniSample2_NG()
Dim r As Range
Set r = Union(Nothing, Range(“B4:F8”))
r.Select
End Sub
ということで、以下、For Next構文で、所定の条件を満たすセルの集合を取得する場合のやり方。
Range型(オブジェクト型)の変数 r に設定されている参照は、は、For Next 構文に入る前は Nothing ですから、最初に調べたセルに対する処理と、それ以降に見つけたセルに対する処理では、やり方が異なります。
以下の例では、セルD13~D43の中で、値が入っていないセルを調べ、その集合を取得します。
Sub Unisample3()
Dim r As Range
Dim c As Long
For c = 13 To 43
If IsEmpty(Range(“D” & c)) Then
‘[5]
If r Is Nothing Then
Set r = Range(“D” & c)
Else
Set r = Union(r, Range(“D” & c))
End If
‘[6]
End If
Next
‘[7]
r.Select
End Sub
ということで。
当初紹介した「KaihenCode3」の、[2]~[3], [4]の部分でやっていること、ご理解いただけたでしょうか。
「KaihenCode3」の、[2]~[3], [4]のそれぞれに相当するのが、「Unisample3」の[5]~[6], [7]になります。
そうして、ループを抜けた後、一回だけ[4]の部分でセルに対する具体的な処理を書きます。
直感的にもご理解いただけるかもしれませんが、このやり方のほうが、対象のセルを見つける都度処理をするより、だいぶ処理が高速化されます。
前回のブログ: 「複数セルに値を入れる処理を高速化したい」もあわせてお読みください。
ではでは。