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

【VBA】Do While...Loopの使い方!条件を満たす間処理を繰り返す基本構造

VBAで繰り返し処理を行う際、For...Next と並んでよく使われるのが Do While...Loop です。「変数が10未満の間」や「セルが空欄でない間」といった、柔軟な条件指定ができるため、実務でのデータ処理において非常に重宝します。

1. 基本文法:Do While...Loop

ループの開始時に条件を判定し、その条件が True(真) である間、中の処理を繰り返し実行します。条件が False になった瞬間にループを抜けます。

[ 構文 ]
Do While 条件式
    ' 繰り返したい処理
Loop

2. 実践サンプル:1から10までカウントアップ

ポイント:ループ内で条件に関わる変数を更新する

以下の例では、変数 i が10になるまで処理を繰り返します。ループの中で i = i + 1 を忘れると、条件がいつまでも満たされたままになり、無限ループに陥るため注意が必要です。

Sub MySub()
  Dim i As Integer
  
  i = 0  ' 初期化
  
  ' i が 10 より小さい間は繰り返す
  Do While i < 10
    i = i + 1
    Debug.Print i
  Loop
End Sub

3. 実行結果

イミディエイトウィンドウに、1から10までの数値が順番に出力されます。

1
2
3
4
5
6
7
8
9
10

4. エンジニアの視点:For文との使い分けと「無限ループ」対策

1. 使い分けの基準: 回数が決まっている時は For...Next、回数が決まっておらず「データが終わるまで」のような動的な条件の時は Do While を使います。特に、外部ファイル(CSVやDBのレコード)を1行ずつ読み込むような「いけいけ」な処理には Do While が最適です。
2. 無限ループの回避: 条件式が常に True になってしまうと、Excelがフリーズします。もし止まらなくなったら [Ctrl] + [Pause/Break] キーで中断しましょう。開発中は、念のためループ内に DoEvents を入れておくと、強制終了しやすくなるのでおすすめです。
3. 条件判定のタイミング: Do While は最初に判定しますが、Loop While と書くと最後に判定(一度は必ず実行)するようになります。このあたりの制御を使いこなせるようになると、IT技術者としてより緻密なロジックが組めるようになります。


5. まとめ

「条件が整っている間、ひたすら回す」。このシンプルな考え方が、複雑な業務自動化を支えます。変数の更新タイミングと条件式の関係をしっかりマスターして、自由自在にループを操れるようになりましょう。

PR

【VBA】数値判定(IsNumeric)の使い方!計算エラーを未然に防ぐデータバリデーション

VBAで計算処理を行う際、変数の中身が数値ではないのに計算しようとすると「型が一致しません」というエラーが発生してしまいます。IsNumeric関数を使えば、対象のデータが数値として扱えるかどうかを事前に判定できるため、安全なプログラムを書くことが可能になります。

1. 基本文法:IsNumeric関数

引数に指定した値が、数値として認識できる場合は True、認識できない場合は False を返します。整数だけでなく、小数や「数値として解釈可能な文字列」も判定対象となります。

[ 構文 ]
IsNumeric( 判定したい値 )

2. 実践サンプル:データの数値判定

ポイント:文字列の「"123"」もTrueになる柔軟な判定

数値そのものはもちろん、計算可能なデータであれば True を返す特性を理解しておきましょう。

Sub Macro1()
  Debug.Print IsNumeric(1)        ' 結果: True (整数)
  Debug.Print IsNumeric(0.5)      ' 結果: True (小数)

  Dim str1 As String
  str1 = "aa"
  Debug.Print IsNumeric(str1)    ' 結果: False (アルファベット)
End Sub

3. 実行結果

イミディエイトウィンドウには、判定結果が論理値で表示されます。

True
True
False

4. エンジニアの視点:IsNumericの「癖」に注意

1. 意外な判定結果: IsNumeric は非常に柔軟です。例えば IsNumeric("1,234") や IsNumeric("&HFF")(16進数)も True を返します。厳密に「数字だけ」を許可したい場合は、他のチェックとの併用も検討しましょう。
2. 実務での活用法: ユーザーに入力させた値が数値でない場合に、「数値を入力してください」と警告(MsgBox)を出すガード句として使うのが一般的です。これにより、マクロが途中で落ちるという「いけいけ」でない状況を防げます。
3. データクリーニング: データベース(PostgreSQLやOracle等)へデータを移行する前の事前チェックとしても有効です。型エラーによるインポート失敗を防ぐために、VBA側で IsNumeric を使ってエラー行を抽出するロジックは非常に「理系」的で効率的です。


5. まとめ

「計算する前に、まず IsNumeric」。この習慣をつけるだけで、マクロの信頼性は飛躍的に向上します。外部から来る不確定なデータを扱う際こそ、この関数でデータの正当性をしっかりと見極めていきましょう。



【VBA】乱数(Rnd)の使い方!ランダムな数値を生成して処理に変化を持たせる方法

プログラムの中で、実行するたびに異なる数値を使いたい場面があります。VBAでは Rnd関数 を使うことで、0以上1未満の乱数を発生させることができます。ゲームの要素だけでなく、データのサンプリングやテストデータの自動生成など、実務でも幅広く活用される機能です。

1. 基本文法:Randomize と Rnd

乱数を使用する際は、必ず Randomize ステートメントを先に実行するのが鉄則です。これを行わないと、マクロを起動し直した際に「毎回同じパターンの乱数」が発生してしまい、本当の意味でのランダムになりません。

Randomize
乱数ジェネレータをシステムタイマーの値で初期化します。

Rnd()
0以上、1未満の範囲(0.000... ~ 0.999...)の小数を返します。

2. 実践サンプル:乱数の発生と出力

ポイント:実行前に必ず「Randomize」で初期化する

最もシンプルな、0から1の間の小数をイミディエイトウィンドウに出力するコードです。

Sub Macro1()
  ' 乱数系列を初期化(これ重要!)
  Randomize

  ' 0以上1未満の乱数を発生させて出力
  Debug.Print Rnd()
End Sub

3. 実行結果

実行するたびに、以下のようなランダムな小数が出力されます。

0.7055475
0.533424
0.2869222

4. エンジニアの視点:実務で使える「整数の乱数」の作り方

1. 範囲指定のテクニック: 実務では「1から100までの整数」が欲しい場合が多いです。その場合は、以下の公式を使います。
Int((最大値 - 最小値 + 1) * Rnd + 最小値)
例えば1〜100なら、Int(100 * Rnd + 1) と記述すればOKです。
2. Randomizeのタイミング: Randomize は一つのマクロ処理の中で一度だけ実行すれば十分です。ループの中で何度も実行すると、逆にランダム性が損なわれることがあるため注意しましょう。
3. 再現性の確保: あえて Randomize を使わずに、Rnd(-1) などの引数を与えて「決まったパターンの乱数」を出すこともあります。これはデバッグ時に「前回と同じ乱数でバグを再現したい」といった場合に役立つ「いけいけ」な高等テクニックです。


5. まとめ

「まずは Randomize、次に Rnd」。このセットを覚えるだけで、VBAに「偶然」の要素を取り込むことができます。データのシャッフルや抽選ツールなど、乱数を使いこなして一味違うツール作成に挑戦してみてください。


【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プログラムを目指しましょう。


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