忍者ブログ
バイオインフォマティックス技術者試験、情報処理試験など、IT系の試験を基礎から勉強します。また、Javaなどプログラミングを勉強します。

【VBA】Static(静的変数)の使い方!プロシージャが終わっても値を保持する魔法の宣言

通常、VBAのプロシージャ内で Dim を使って宣言した変数は、処理が終わるとメモリから消去され、値はリセットされます。しかし、Static キーワードを使うと、プロシージャが終了しても値を保持し続けることができます。実行回数をカウントしたり、前回の状態を引き継ぎたい時に非常に便利です。

1. 基本概念:静的変数(Static)とは?

静的変数は、マクロが実行されている間、そのプロシージャ専用の「個別のメモリ領域」に居座り続けます。他のプロシージャからは見えない(カプセル化されている)のに、値は消えないという特性を持っています。

[ 特徴 ]
・プロシージャが終了しても値が破棄されない。
・そのプロシージャ内からしかアクセスできない(安全性が高い)。
・ブックを閉じたり、コードを書き換えてリセット(終了)ボタンを押すと初期化される。

2. 実践サンプル:呼び出し回数をカウントする

ポイント:Dim の代わりに Static を使うだけ!

以下の例では、Sub1 が呼ばれるたびに変数 x がカウントアップされます。Dim であれば毎回 1 に戻りますが、Static なので増え続けます。

' --- 呼び出される側のプロシージャ ---
Sub Sub1()
  Static x As Integer  ' 静的変数の宣言

  x = x + 1
  Debug.Print x
End Sub

' --- 実行用プロシージャ ---
Sub Sub2()
  Dim i As Integer
  
  ' 10回連続で Sub1 を呼び出す
  For i = 1 To 10
    Call Sub1
  Next i
End Sub

3. 実行結果

Sub2 を実行すると、イミディエイトウィンドウにはリセットされることなく加算された結果が表示されます。

1
2
3
4
5
6
7
8
9
10

4. エンジニアの視点:モジュールレベル変数との使い分け

1. ここがメリット!: 値を保持するためにモジュールの一番上で Public や Private 変数を使うこともできますが、それだと「他のプロシージャから間違えて書き換えられる」リスクがあります。Static はそのプロシージャ内に閉じているため、影響範囲を最小限に抑えられます。
2. 実務での活用例: ログ出力の連番振り、再帰処理の深さ制限、または「初回呼び出し時のみ実行したい初期化処理」のフラグ管理(Static isInitialized As Boolean)などに非常に有効です。
3. Javaエンジニアの視点: メソッド内の static 変数に近い挙動です。状態(State)をプロシージャレベルで保持できるため、クラスを作るまでもないちょっとした「記憶機能」を実装するのに最適で「いけいけ」な手法です。


5. まとめ

「プロシージャを抜けても値を忘れてほしくない」。そんな時は Static の出番です。グローバル変数を無暗に増やさず、必要な場所だけで値を保持するこのテクニックをマスターして、より堅牢でスマートなVBAプログラムを目指しましょう。


PR

【VBA】構造体の配列でデータを一括管理!複数の関連データを効率よくループ処理する方法

「ユーザー定義型(構造体)」の真価は、配列と組み合わせたときに発揮されます。例えば、新旧の対応表や名簿データなど、同じ構造を持つ大量のデータをメモリ上で高速に、かつ整理された状態で扱うことができます。

1. 実践サンプル:新旧対応表(変換テーブル)の管理

複数の要素(old, new)を持つ構造体を配列にすることで、関連するデータをセットにしたままループ処理が可能になります。

' --- 標準モジュールの先頭で宣言 ---
Option Explicit

' 構造体の定義
Public Type TransforTable
    old As Integer
    newVal As Integer ' ※newは予約語のためnewValとしています
End Type

Sub Macro2()
    ' 構造体の配列を宣言(要素数2)
    Dim TransforTables(1 To 2) As TransforTable

    ' 1番目のデータセット
    TransforTables(1).old = 1
    TransforTables(1).newVal = 10

    ' 2番目のデータセット
    TransforTables(2).old = 2
    TransforTables(2).newVal = 20

    Dim i As Integer
    For i = 1 To 2
        Debug.Print TransforTables(i).old
        Debug.Print TransforTables(i).newVal
    Next i
End Sub

2. アルゴリズムのポイント

重要:ループ内ではカウンタ変数「i」を正しく使う

配列をループで回す際は、TransforTables(i).newVal のように添字に変数 i を指定します。ここを固定値(1など)にしてしまうと、せっかくのループでも同じデータしか参照できないため注意が必要です。

3. 実行結果

各要素の old と newVal が順番に出力されます。

1
10
2
20

4. なぜ「構造体の配列」が最強なのか?

1. ここがメリット!: oldValues() と newValues() という2つの別々な配列を作るよりも、構造体の配列1つにする方が「データの整合性」が保てます。1行分のデータが常にセットで動くため、並べ替えや引数の受け渡しが非常に「いけいけ」でスムーズになります。
2. エンジニアの視点: これはデータベースのレコードをメモリ上にロードする際の基本形です。JavaやC#での「オブジェクトのリスト」に近い感覚でVBAを扱えるようになります。大規模な変換ロジックを組む際は、まずこの構造を検討しましょう。
3. デバッグのコツ: ローカルウィンドウを表示すると、配列の中にある構造体の各要素がツリー形式で表示されます。変数の中身が一目瞭然になるため、開発効率が劇的に向上します。


5. まとめ

構造体と配列の組み合わせは、VBAにおける「データ管理の決定版」です。バラバラだった変数を構造化し、配列で一括制御することで、コードの可読性と保守性は格段に高まります。複雑なデータ加工が必要な時こそ、この手法を思い出してください。




【VBA】定数(Const)の基本と活用術!マジックナンバーを排除して読みやすいコードへ

プログラムの中で何度も出てくる数値や文字列。それらを直接書き込むのではなく、「名前」を付けて管理するのが定数(Const)の役割です。定数を適切に使うことで、コードの意図が明確になり、修正ミスを劇的に減らすことができます。

1. 基本文法:Constステートメント

定数を宣言するには Const を使用します。変数とは異なり、一度値を決めたらプログラムの実行中に書き換えることはできません。型(As type)は省略可能ですが、明示的に指定するのが「理系」スタイルの堅牢な書き方です。

[ 構文 ]
Const 定数名 [ As データ型 ] = 値

2. 実践サンプル:定数を使った計算

ポイント:意味のある名前(PIなど)を付ける

数値をそのまま書く(マジックナンバー)のを避け、定数として定義することで、後から見返したときに何を表しているのかが一目でわかります。

Sub Macro1()
  ' 定数の宣言
  Const PI As Double = 3.14

  ' 定数を使用した出力
  Debug.Print PI
End Sub

3. 実行結果

マクロを実行すると、イミディエイトウィンドウに定義した値が出力されます。

3.14

4. なぜ「変数」ではなく「定数」を使うのか?

1. ここがメリット!: 定数は誤って書き換えられる心配がないため、システムの根幹をなす値(消費税率や円周率など)の管理に最適です。また、一箇所を直せばプログラム全体に反映されるため、保守性が非常に高くなります。
2. エンジニアの視点: コンパイル時に値が確定するため、実行速度の面でも(微々たるものですが)有利に働きます。Java 17でいう final 定数と同じく、不変性(Immutability)を担保する設計は、バグの少ない「いけいけ」なコードを生む基本です。
3. スコープの活用: モジュールの先頭で Public Const と宣言すれば、プロジェクト内のどこからでも参照できる「共通定数」になります。前回の記事で紹介した MConst モジュールに集約させるのが、プロレベルの管理術です。


5. まとめ

「その値は変わる可能性があるか?」を自分に問いかけ、変わらないものは積極的に Const にしていきましょう。ハードコーディングを卒業し、定数を使いこなすことで、あなたのVBAコードは一段とプロフェッショナルな輝きを放ち始めます。


        
  • 1
  • 2
  • 3