CopyFromRecordsetで先頭の0が消える・日付が数字になる原因と対策

標準書式では123と46334、書式指定後は00123と2026/11/08

Excel VBAのCopyFromRecordsetでデータを転記したところ、商品コード「00123」が「123」になったり、日付が「46334」のような数字になったりして困ることがあります。大切なのは、元データの型とExcelの表示形式を分けて確認することです。

ケンさん(SE)

商品コードの先頭のゼロが消えてる! 転記が失敗したのかな?

チャー

転記そのものは成功しているかも。型と表示形式を確認するにゃ。

目次

先頭の0が消える原因

商品コードや伝票番号のような識別子は、見た目が数字でも計算する数値とは限りません。
「00123」を数値123として扱うと先頭の0は失われます。
Excelの表示形式だけでなく、DB側で数値型として保存・変換されていないかも確認しましょう。

貼り付け前に文字列形式を設定する

1列目の商品コードがRecordset内で文字列として得られている場合、貼り付け前に対象列を文字列書式にする方法があります。次は取得済みRecordsetを使った抜粋です。

Dim ws As Worksheet
Dim dest As Range
Set ws = ThisWorkbook.Worksheets("Sheet1")

ws.Columns("A").NumberFormat = "@"
Set dest = ws.Range("A2")
dest.CopyFromRecordset rs

注意:元の値がすでに数値123なら、この設定を追加しても「00123」は復元できません。
元データを文字列として取得するか、コード体系で決まっている桁数に従う変換が必要です。

日付が数字になる原因と対処

Excelの日付は内部的にシリアル値で保持されます。値が日付として扱える状態なら、セルの表示形式を変更することで読みやすくできます。

Dim ws As Worksheet
Dim dest As Range
Set ws = ThisWorkbook.Worksheets("Sheet1")

Set dest = ws.Range("A2")
dest.CopyFromRecordset rs
ws.Columns("B").NumberFormat = "yyyy/mm/dd"

この例では、転記後にB列の表示形式を設定します。検証環境では転記前の指定だけだと日付の「日」が1桁で表示されたため、転記後に設定して2桁にそろえました。
SQLで「20261108」のような8桁の数値や文字列を返している場合は、日付表示形式の設定だけでは解決しません。元の型を確認してください。

見た目とセルの値を区別する

  • 商品コード:元の型が文字列か。先頭0や長い識別番号が維持されるか。
  • 日付:Excelが日付シリアル値として解釈しているか。
  • 空欄:データベースのNULL、空文字、数値0を区別できているか。
  • 長い番号:Excelの数値精度の影響を避けるため、識別番号を文字列で受け取っているか。

出力後は目視だけでなく値も検証する

セルに「00123」と見えていても、実際には数値123を5桁表示しているだけのケースがあります。
次の工程がCSV出力や他システムへの取り込みなら、画面上の見た目だけでなく、
セルの値・型・出力後の形式まで確認してください。

【実行前・実行後】商品コードと日付を正しく表示する

標準書式では123と46334、書式指定後は00123と2026/11/08
Windows版Excelでの実測値をもとにした図解(架空データ)

同じRecordsetを標準書式の別範囲に転記した比較では、先頭行は「123」「46334」と表示されました。掲載コードでは、A列の値が文字列「00123」「00045」として残り、B列の内部値46334・46335が「2026/11/08」「2026/11/09」と表示されました。

同じ値でも「Recordsetでどう保持しているか」と「Excelでどう表示するか」で結果が変わります。コードと日付を含む2件の架空データで比べます。

実行前:期待する出力形式

商品コード(文字列)登録日(日付型)
001232026/11/08
000452026/11/09

標準書式で転記したときの比較結果(先頭のデータ1件のセル表示)。

問題表示例確認箇所
先頭ゼロが失われた123Recordsetとセルの値・型、および転記先の書式
日付が数字で見える46334セルの表示形式と日付型

次の検証用VBAは、商品コードを最初から文字列として保持し、日付をDate型として扱う例です。実際にデータベースから取得するときにも、この区別が重要です。

Sub DemoTextCodeAndDate()
    Dim rs As Object, ws As Worksheet
    Dim dest As Range

    Set rs = CreateObject("ADODB.Recordset")
    rs.CursorLocation = 3 ' adUseClient
    rs.Fields.Append "商品コード", 202, 10 ' adVarWChar
    rs.Fields.Append "登録日", 7           ' adDate
    rs.Open
    rs.AddNew Array("商品コード", "登録日"), _
              Array("00123", DateSerial(2026, 11, 8))
    rs.AddNew Array("商品コード", "登録日"), _
              Array("00045", DateSerial(2026, 11, 9))
    rs.MoveFirst

    Set ws = ThisWorkbook.Worksheets.Add
    ws.Range("A1").Value = "商品コード"
    ws.Range("B1").Value = "登録日"

    ' 転記する前に表示形式を決める
    ws.Columns("A").NumberFormat = "@"
    ws.Columns("B").NumberFormat = "yyyy/mm/dd"
    Set dest = ws.Range("A2")
    dest.CopyFromRecordset rs
    ws.Columns("B").NumberFormat = "yyyy/mm/dd"
    ws.Columns("A:B").AutoFit

    rs.Close
    Set rs = Nothing
End Sub

実行後:新規ワークシートで確認した表示

Excelの行A列:商品コードB列:登録日
1商品コード登録日
2001232026/11/08
3000452026/11/09

補足:貼り付ける前にNumberFormat = "@"を設定しても、Recordset側で既に数値123になっている情報から先頭ゼロは復元できません。見た目だけを00000形式にする方法と、文字列「00123」を保持する方法は別物です。別システムへ渡す識別コードは、文字列として保持できているかまで確認しましょう。

検証環境はWindows版Excel 16.0(ビルド20527)とADOです。2026年11月8日に、外部データベースを使わず架空データで検証しました。

CopyFromRecordsetをもっと詳しく学びたい方へ

基本操作からエラー対策、データの取り込みや書式設定まで体系的に学びたい方には、Kindle書籍『Excel VBA CopyFromRecordset 実践ガイド』もおすすめです。

チャー

ぜひ、読んでみてニャ🐈

まとめ

書式の問題に見えても、原因がDBのデータ型やSQLの変換にあることがあります。
データベース → Recordset → Excelの値 → 表示形式の順に追いかけると、誤った修正を防ぎやすくなります。

関連記事・もっと詳しく学ぶには

基本から確認したい方は、CopyFromRecordsetの使い方完全ガイドをご覧ください。高速化の背景はCopyFromRecordsetはなぜ速い?で解説しています。

参考資料:Microsoft Learn:Range.CopyFromRecordset メソッド(確認日:2026年11月8日)。コード例は架空データ・一般的な環境を想定しています。本番実行前に検証してください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次