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

複数セルでの処理を高速化したい-その2 Unionメソッドを使用する Excelマクロ・VBA

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

エクセルマクロ・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
         &nbsp
;  ‘[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]の部分でセルに対する具体的な処理を書きます。

直感的にもご理解いただけるかもしれませんが、このやり方のほうが、対象のセルを見つける都度処理をするより、だいぶ処理が高速化されます。

前回のブログ: 「複数セルに値を入れる処理を高速化したい」もあわせてお読みください。

ではでは。

キーワード

コメント

コメントを残す

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

最新の記事

人気記事

最新記事

カテゴリ

最新コメント

タグクラウド