KB0070: thinkcell が有効な場合、Excel マクロが遅いのはなぜですか?

  1. ホーム
  2. リソース
  3. ナレッジ ベース
  4. KB0070

VBA マクロでパフォーマンスの問題を引き起こす一般的な原因は、.Select 関数の使用です。Excel でセルが選択されるたびに、すべての Excel アドイン(thinkcell を含む)にこの選択変更イベントが通知されるため、マクロが大幅に遅くなります。マクロ レコーダーを使用して作成されたマクロでは、特にこの種の問題が発生しやすくなります。

Microsoft も、パフォーマンス向上のために VBA コードで .Select ステートメントを避けることを推奨しています:

  • MSDN: Improving Performance in Excel 2007: "Reference Excel objects such as Range objects directly, without selecting or activating them"("Faster VBA Macros" セクション内)。

例: .Select ステートメントの使用を避ける方法

次の簡単なマクロ AutoFillTable を見てみましょう。

Sub AutoFillTable()
    Dim iRange As Excel.Range
    Set iRange = Application.InputBox(prompt:="Enter range", Type:=8)
    Dim nCount As Integer
    nCount = iRange.Cells.Count
    For i = 1 To nCount
        Selection.Copy
        If iRange.Cells.Item(i).Value = "" Then
            iRange.Cells.Item(i).Range("A1").Select
            ActiveSheet.Paste
        Else
            iRange.Cells.Item(i).Range("A1").Select
        End If
    Next
End Sub

この関数は、ユーザーにセル範囲の指定を求める入力ボックスを開きます。 この関数は、範囲内のすべてのセルを移動します。 空でないセルが見つかると、そのセルの内容をクリップボードにコピーします。 この関数は、クリップボードの内容を後続のすべての空のセルに貼り付けます。

AutoFillTable は、セルの内容をコピーするためにクリップボードを使用します。 そのため、この関数では、操作対象の各セルを選択して、Excel がどのセルからコピーし、どのセルに貼り付けるべきかを認識できるようにする必要があります。 推奨される解決策は、次の関数 AutoFillTable2 に示されています。

Sub AutoFillTable2()
    Dim iRange As Excel.Range
    Set iRange = Application.InputBox(prompt:="Enter range", Type:=8)
    Dim iCellMaster As Excel.Range
    For Each iCell In iRange.Cells
        If iCell.Value = "" Then
            If Not iCellMaster Is Nothing Then
                iCellMaster.Copy (iCell)
            End If
        Else
            Set iCellMaster = iCell
        End If
    Next iCell
End Sub

AutoFillTable2 は、前の関数と比べて 2 つの重要な点が異なります。

  1. 最も重要なのは、セルを選択する必要がなくなったことです。 代わりに、空でないセルが見つかると、そのセルが変数 iCellMaster に保存されます。 その後、空のセルが見つかるたびに、iCellMaster のすべての内容が iCell にコピーされます。
  2. Visual Basic の言語機能 For Each … Next を使用して、範囲内のすべてのセルを順に処理します。 これだけでも可読性の向上につながります。