和風スパゲティのレシピ

日本語でコーディングするExcelVBA

汎用マクロ・便利ツール用の共通関数について

本ブログで紹介している、汎用マクロ・便利ツールは、
特に頻出の処理を、共通の関数として抽出して使っています。

共通関数のソースコードと解説を以下に記しておきますので、
コードの説明が読みたい方はご利用ください。


※ 各マクロのページに共通関数のソースコードも記載されていますので、
  このページからコピペする必要はありません。

Excelの自動更新系のON/OFF

ソースコード

' 自動更新の停止
Sub エクセルの自動更新を停止する(isブック計算をOFFに As Boolean _
    , Optional is画面更新をOFFに As Boolean = True _
    , Optional isイベントをOFFに As Boolean = True)
    
    If isブック計算をOFFに Then Application.Calculation = xlCalculationManual
    If is画面更新をOFFに Then Application.ScreenUpdating = False
    If isイベントをOFFに Then Application.EnableEvents = False
    
End Sub

' 自動更新の開始
Sub エクセルの自動更新を開始する()
    With Application
        .Calculation = xlCalculationAutomatic
        .ScreenUpdating = True
        .EnableEvents = True
        .StatusBar = False
        .DisplayAlerts = True
    End With
End Sub

使用例

Sub マクロを実行するプロシージャ
    Call エクセルの自動更新を停止する(False)

    ここにメインの処理を書く
    ↓
    ↓

    Call エクセルの自動更新を開始する
End Sub

解説

マクロの高速化で「OFFにすると早くなるよ!」でおなじみのトリオです。
画面の描画・数式の自動計算・シートイベントのON/OFF」をまとめたやつですね。


並んで書くことの多い仲良しコードは、こんな感じで関数にまとめちゃうと、
書くときも楽だし、行数が減って読むときも楽なのでおすすめです。


使用例を見ての通り、非常に使い勝手が良いので、
便利マクロだけでなく、すべてのマクロでの共通関数として使用しています


3つの機能をまとめていますが、どれをOFFにするかは場合によって変わる可能性があるため、OFFにするものを引数で指定できます。

描画とEventは大抵は停止するので省略可=省略時は停止としていますが、
ブックの自動計算は、シート関数を利用してマクロを組むときや、
すでにブックにある関数がしっかり更新されないといけない場面もあるため、
誤って停止させないよう、引数は省略不可としています。
 

Call エクセルの自動更新を開始する

こちらのONにする方の関数は特に引数はないです。
ついでにステータスバーの初期化と、警告メッセージのONも行っています。


ちなみに、この自動更新開始のプロシージャは、
描画を停止したマクロがエラーで止まった場合に、手動で描画を再開したい
という場面でも使えますので、これ自体が便利マクロにもなります。

このマクロも、ついでにクイックアクセスツールバーなどに登録してしまいましょう。

おまけ:ユーザー辞書に登録

余談ですが、私はこの関数を↑の通り「すべてのマクロの共通関数」として使うので、
作るマクロの「すべての実行プロシージャで1回ずつ」レベルで登場します。

なので、

キー 読み 単語
eof えおf Call エクセルの自動更新を停止する(False)
eon えおん Call エクセルの自動更新を開始する

ユーザー辞書に登録しています。
(ユーザー辞書は子音ならアルファベットを読みに登録可能)


「日本語変数はキーボードのIME切り替えが面倒」とよくやり玉に挙げられますが、
開き直って日本語入力ONのまま、頻出コードを変換で出しちゃうと便利ですね。

行・列・シートを全選択して実行時のエリア調整

ソースコード

' 全体選択のSelectionを縮小
Function 選択範囲をUsedRangeで切り取って縮小する() As Range
    
    ' 行全体・列全体・シート全体が選択されている場合は、
    ' UsedRangeで切り取った範囲を選択しなおし
    If Selection.Address = Selection.EntireRow.Address _
    Or Selection.Address = Selection.EntireColumn.Address Then
        Set 選択範囲をUsedRangeで切り取って縮小する _
            = Intersect(Selection, ActiveSheet.UsedRange)
        選択範囲をUsedRangeで切り取って縮小する.Select
    
    ' それ以外はそのまま
    Else
        Set 選択範囲をUsedRangeで切り取って縮小する = Selection
    End If

End Function

使用例

Dim 実行エリア As Range
Set 実行エリア = 選択範囲をUsedRangeで切り取って縮小する

以降Selectionではなく実行エリアに対して便利マクロを記述

解説

便利マクロを「すべてのセル・行全体・列全体」から実行した場合に、
シートの使っている範囲「UsedRange」との交差部分で、
切り取った範囲を選択しなおしてからメイン処理に入るための関数です。


↓この青色を選択して実行した場合に、緑色だけに処理を行うための関数ですね。

UsedRangeによる実行エリア切り取り

わざわざドラッグで選択しなくても、
全選択から実行できた方がショートカットとして優秀なマクロも多いですし、
うっかり全選択で実行した場合に、範囲が広すぎて固まる対策にもなります。

おまけ:共通関数で共通関数を使う

列全体を選択しているかどうかは、
 Selectionのアドレスが、
 Selectionを含む列全体(EntireRow)のアドレスと等しいかどうか
で判定しています。
 

If Selection.Address = Selection.EntireRow.Address Then

↑この部分ですね。


ですが私の実際のコードでは、

Function IsRange列全体(ByVal 判定Range As Range) As Boolean
    IsRange列全体 = (判定Range.Address = 判定Range.EntireColumn.Address)
End Function

この関数を使って、

If IsRange列全体(Selection) Then

こう書いてあります。


コピペしてくださいコードが、関数が関数を呼んでるのはよくないかな~と思って、一応バラしました。


Rangeがどんな形をしているか?を判定する文は、
理屈は単純な割に、同じ文が何回も出てきて冗長な感じになっちゃうので、
関数化しておくと見やすくなりますね。