LWP | 最終行まで処理したのに、3件足りない
最終行まで処理したのに、3件足りない
「どこまで」と「何件」を、オイカワ部長たちと整理する
Copyright © 2026 LWP 山中 一弘
本資料は、出典を明記いただければ、商用・非商用を問わず、ご自由に複製・改変・再配布していただけます。なお、著作権表示は改変せず、そのまま記載してご利用くださいますようお願いいたします。
ストーリー
月次の明細を出力し終えたところで、フナさんが照合表を持ってきました。「9件あるはずなのに、出力は6件です」。オイカワ部長とVBA担当のシャケモンが、一緒に処理の終点を確かめます。
この会話と数値は架空の説明例です。基本の表は1行目が見出し、2〜10行目が9件の明細。A列のIDは全件に入り、任意入力のB列の備考は7行目を最後に空欄になっています。フィルターや非表示行は使っていません。
1 全部処理したのに、3件足りない
処理がエラーなく終わっても、必要な明細がそろったとは限りません。まず、元の件数と出力の件数を照合します。

図1|「全部」の確認は、完了メッセージだけでは終わらない。
2 調べていたのは、備考列
シャケモンが確認すると、処理はB列を下からたどっていました。B7には備考があり、B8〜B10は空欄です。そこで7行目までを処理したため、見出しを除く6件で終わっていました。

図2|任意入力の列の末尾と、明細全体の末尾は一致しない。
3 同じ表でも、終点が違う
A列なら10行目、B列なら7行目。同じシートでも、指定する列によって答えが変わります。列を指定して求めた行番号を、そのまま「表全体の最終行」と呼ぶと、前提が抜け落ちます。

図3|最終行の話には「どの列を見たか」が必要。
4 1件の基準を、先に決める
フナさんの業務では、明細にIDが必須で、備考は任意です。その条件を確認してから、処理の基準列を選びます。必須のIDが欠けた行を見つけた場合も、黙って捨てず、照合が必要な行として扱います。

図4|図中の表は、必須項目と任意項目を示す模式例。
5 空欄に見えても、式がある
ここで別の条件を試して考えます。A20に空文字を返す数式 `=""` が入っていると、表示が空欄でもセルには式が存在します。今回の下からたどる方法では、A20が終点になります。これは20件あるという意味ではありません。

図5|「空に見える」と「値も式もない」は違う。
6 行番号を、そのまま件数にしない
最終行が10行目でも、明細が10件とは限りません。今回の基本例で9件になるのは、1行目だけが見出しで、2〜10行目に明細が連続し、全行が対象だからです。途中に空行や対象外の行がある表では、行番号の差だけでは件数を求められません。

図6|「10 − 1 = 9件」は、この表の条件があってこその計算。
7 境界の3ケースも確かめる
列が完全に空でも、この方法は行番号1を返します。見出しだけの場合も行番号1ですが、データ件数は0件です。さらに、シートの最下行そのものに値がある場合は、そこを起点に領域の端へ移動するため、単純な「最後の非空セル探し」としては扱えません。

図7|通常の表で便利な方法にも、確かめるべき境界がある。
8 「全部」の条件がそろった
オイカワ部長とフナさんは、「IDを持つ明細を対象とし、元の明細と出力を照合する」と確認しました。処理の終点を直すだけでなく、何をもって完了とするかも共有できました。

図8|「全部できた」と言う前に、対象と照合条件をそろえる。
まとめ
最終行は、調べる列と調べ方によって変わります。まず業務上の1件を決め、必須項目の欠落や数式のある空欄も考慮して終点を選びます。そのうえで、行番号とは別に対象件数と出力内容を照合します。
今回の仕掛け
TakiLibの `rngLastRow` は、指定列をシートの最下行から `End(xlUp)` でたどったセルの行番号を返します。引数を省略すると対象は `ThisWorkbook.ActiveSheet`、列は1列目ですが、この記事の例では誤解を避けるため両方を明示します。
Microsoftの仕様では、`Range.End` は起点を含む領域の端のセルを返す操作です。「業務上の明細を数える関数」ではありません。空文字数式や最下行の扱いが重要になるのは、この移動操作を利用しているためです。
今回のソースコードのサンプル
入力・概要
次のコードは、TakiLibを導入済みのブックに置く、単独で実行できる確認用マクロです。公開安定版3.5.4の通常CP932版 `taki3lib.bas` をVBEからインポートし、「明細」というワークシートを用意します。読解用の `taki3libUTF8.bas` をインポートする手順ではありません。
「明細」のA1を「ID」、B1を「備考」とします。A2〜A10に9件分のIDを連続して入れ、B7に「確認済」を入れてください。B8以降、A11以降には値や式を入れません。B2〜B6の入力有無はこの例の終点には影響しません。出力はVBEのイミディエイトウィンドウで確認します。
サンプルコード 列を指定して最終行を比べる
01 |
|
|---|---|
02 |
|
03 |
|
04 |
|
05 |
|
06 |
|
07 |
|
08 |
|
09 |
|
コードの説明
同じワークシートを渡し、列番号だけを1と2に変えてTakiLibを直接呼び出しています。戻り値はどちらも行番号です。このマクロ自体は明細の出力や件数の集計を行いません。
サンプルコード 直接呼び出す関数の原典抜粋
01 |
|
|---|---|
02 |
|
03 |
|
この3行はTakiLibの読解用抜粋です。すでに導入したライブラリと重複するため、ブックへ追加するコードではありません。内部の `rngLastRowRange` は、シートと列番号を補ったうえで、`a_sheet.Cells(a_sheet.Rows.Count, a_col_num).End(xlUp)` を返します。
結果
上記の入力条件では、ID列の終点は10、備考列の終点は7になると、ソースと公式仕様から読み取れます。A20に `=""` を入れた別条件では、ID列の終点は20になります。空列・見出しだけの場合はいずれも行番号1です。
掲載コードは今回Excelで実行検証していません。ここに示した値は、確認したソースと入力条件に基づく期待値です。実際の表に適用するときは、必須IDの欠落、空文字数式、対象外の行など、業務の条件を加えて確認してください。
出典メモ
元ネタ:TK-074「最終行は『何をデータと呼ぶか』で変わる」(2026年9月7日整理)。
TakiLib 3.5.4、通常CP932版 `taki3lib.bas` の `rngLastRow` と `rngLastRowRange`。2026年9月27日確認。
Microsoft Learn「Range.End property (Excel)」。2026年9月27日確認。
