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出力や他システムへの取り込みなら、画面上の見た目だけでなく、
セルの値・型・出力後の形式まで確認してください。
【実行前・実行後】商品コードと日付を正しく表示する


同じRecordsetを標準書式の別範囲に転記した比較では、先頭行は「123」「46334」と表示されました。掲載コードでは、A列の値が文字列「00123」「00045」として残り、B列の内部値46334・46335が「2026/11/08」「2026/11/09」と表示されました。
同じ値でも「Recordsetでどう保持しているか」と「Excelでどう表示するか」で結果が変わります。コードと日付を含む2件の架空データで比べます。
実行前:期待する出力形式
| 商品コード(文字列) | 登録日(日付型) |
|---|---|
| 00123 | 2026/11/08 |
| 00045 | 2026/11/09 |
標準書式で転記したときの比較結果(先頭のデータ1件のセル表示)。
| 問題 | 表示例 | 確認箇所 |
|---|---|---|
| 先頭ゼロが失われた | 123 | Recordsetとセルの値・型、および転記先の書式 |
| 日付が数字で見える | 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 | 商品コード | 登録日 |
| 2 | 00123 | 2026/11/08 |
| 3 | 00045 | 2026/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日)。コード例は架空データ・一般的な環境を想定しています。本番実行前に検証してください。




