前回コードの限界
前回は配列を使って高速化し、処理速度の問題は完全に解決しました。
ここまで来ると、多くの人が「完成」と思います。
ただ、実務ではもう一つ必ず問題が出ます。
それが
項目の増減
です。
例えばこういうケースです。
・元データに列が追加される
・列の順番が変わる
・名称が微妙に変わる
このとき、今のコードはどうなるか。
普通に壊れます。
理由はシンプルで、列番号で処理しているからです。
つまり
A列だからOK
B列だからOK
という前提に依存しています。
実務ではこの前提はほぼ崩れます。
前回に引き続き、経済産業省の公開データである「第3次産業活動指数【月次】業種別原指数」のデータを使わせていただいています。
今回の修正内容(壊れないコードにする)
今回やるのはここです。
・1行目(ヘッダー)を配列に取り込む
・Dictionaryで項目名 → 列番号を管理
・列指定を「番号」ではなく「名前」で行う
これでどうなるかというと、列の位置が変わっても壊れません。
これが実務ではかなり重要です。
Dictionary オブジェクト(連想配列)に登録された値(item)を、キー(key)やインデックス番号を指定して取得する(Excel VBA)
A列の品目番号とB列の 品目名称を入れ替えても・・・

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
元データの列に依存せず、同じ結果が得られます♪

実際のCopilotとのやり取り
利用者 → Copilot
現在のコードに対して、項目の増減に対応できるように修正してください。 ■要件
・元データ(dataシート)の1行目を配列で取得
・Dictionaryを使用して「項目名 → 列番号」を保持
・列指定は列番号ではなく項目名で行う ■前提
・A列:品目番号
・B列:品目名称
・3列目以降:年月列 ■既存仕様は維持
・配列による高速処理
・クロス表 → 縦持ち変換
・年月は yyyy/m 形式
・原指数はカンマ区切り
・列幅自動調整 コード全体を修正してください。
Copilot → 利用者
以下に、項目名ベースで列を特定し、変更に強い構造へ改善したコードを提示します。
Option Explicit
Sub ConvertCrossToLong_Fast()
'--------------------------------------------
'【1】シートの定義
'--------------------------------------------
Dim wsSource As Worksheet ' 元データ:data シート
Dim wsOutput As Worksheet ' 出力先:data2 シート
Set wsSource = Worksheets("data")
Set wsOutput = Worksheets("data2")
'--------------------------------------------
'【2】出力先シートの初期化
'--------------------------------------------
wsOutput.Cells.ClearContents
'--------------------------------------------
'【3】元データの最終行・最終列を取得
'--------------------------------------------
Dim lastRow As Long
Dim lastCol As Long
lastRow = wsSource.Cells(wsSource.Rows.Count, "A").End(xlUp).Row
lastCol = wsSource.Cells(1, wsSource.Columns.Count).End(xlToLeft).Column
'--------------------------------------------
'【4】元データを配列に読み込み
'--------------------------------------------
Dim srcData As Variant
srcData = wsSource.Range(wsSource.Cells(1, 1), wsSource.Cells(lastRow, lastCol)).Value
'--------------------------------------------
'【5】Dictionary に「項目名 → 列番号」を格納
'--------------------------------------------
Dim colMap As Object
Set colMap = CreateObject("Scripting.Dictionary")
Dim i As Long
For i = 1 To lastCol
colMap(srcData(1, i)) = i
Next i
'--------------------------------------------
'【6】必須項目の列番号を取得(項目名で指定)
'--------------------------------------------
Dim colItemCode As Long: colItemCode = colMap("品目番号")
Dim colItemName As Long: colItemName = colMap("品目名称")
' 年月列は「3列目以降」=ヘッダーのうち品目番号・品目名称以外
Dim ymStartCol As Long: ymStartCol = 3
Dim ymEndCol As Long: ymEndCol = lastCol
'--------------------------------------------
'【7】出力件数を計算(行数 × 年月列数)
'--------------------------------------------
Dim itemCount As Long
Dim ymCount As Long
itemCount = lastRow - 1
ymCount = ymEndCol - ymStartCol + 1
Dim totalRows As Long
totalRows = itemCount * ymCount
'--------------------------------------------
'【8】出力用配列を作成(ヘッダー+データ)
'--------------------------------------------
Dim outArr() As Variant
ReDim outArr(1 To totalRows + 1, 1 To 4)
outArr(1, 1) = "品目番号"
outArr(1, 2) = "品目名称"
outArr(1, 3) = "年月"
outArr(1, 4) = "原指数"
'--------------------------------------------
'【9】配列に縦持ちデータを格納
'--------------------------------------------
Dim r As Long, c As Long
Dim outRow As Long
Dim ym As Variant
outRow = 2
For r = 2 To lastRow
For c = ymStartCol To ymEndCol
ym = srcData(1, c) ' 年月(ヘッダー)
outArr(outRow, 1) = srcData(r, colItemCode)
outArr(outRow, 2) = srcData(r, colItemName)
' 年月を yyyy/m 形式に統一
If IsDate(ym) Then
outArr(outRow, 3) = Format(ym, "yyyy/m")
Else
outArr(outRow, 3) = ym
End If
' 原指数
outArr(outRow, 4) = srcData(r, c)
outRow = outRow + 1
Next c
Next r
'--------------------------------------------
'【10】配列を一括で書き込み
'--------------------------------------------
wsOutput.Range("A1").Resize(UBound(outArr, 1), 4).Value = outArr
'--------------------------------------------
'【11】書式設定(カンマ区切り)
'--------------------------------------------
wsOutput.Columns(4).NumberFormatLocal = "#,##0"
'--------------------------------------------
'【12】列幅を自動調整
'--------------------------------------------
wsOutput.Columns.AutoFit
'--------------------------------------------
'【13】完了メッセージ
'--------------------------------------------
MsgBox "高速版(項目名対応):クロス表の縦持ち変換が完了しました。", vbInformation
End Sub
この修正の本当の価値
ここが一番重要です。
今回の変更は見た目では分かりません。
でも中身は大きく変わっています。
【従来】
列番号に依存
→ 変更で壊れる
【今回】
項目名に依存
→ 変更しても壊れない
つまり、メンテナンス不要のコード に近づいています。
実務でのインパクト
この改善は地味ですが、かなり効きます。
・列順が変わっても対応不要
・列追加されてもそのまま動く
・仕様変更に強い
特に、外部データを扱う場合は必須レベルです。
今回の経済産業省データのように、フォーマットが更新される可能性があるものには効果大です。
まとめ
今回で、このVBAはさらに一段上のレベルになりました。
① 動く
② 見やすい
③ 速い
④ 壊れない
ここまで来ると、完全に実務仕様です。
そして重要なのは、このすべてをCopilotとの対話で作っていることです。
自分で全部書く必要はありません。
必要なのは
・問題に気づくこと
・やりたいことを言語化すること
これだけです。
今回のように
配列にして
Dictionaryで管理して
というレベルの話でも、Copilotは普通に対応してくれます。
あとはシンプルです。
自分の業務で
・壊れやすい処理
・変更に弱い処理
を見つけたら、「項目名で処理するようにして」と投げてみてください。
それだけで、一段上のコードに進化します。
リンク
ChatGPTでExcel VBAマクロを自動生成してみた|初心者でも使える実践手順
Excel VBAのエラー修正をChatGPTに頼んだら原因が一発で分かった話
仕様が曖昧でもOK?ChatGPTにExcel VBAを作らせてみた結果
ChatGPTに作らせたExcel VBAコードは安全?使う前に確認すべきポイント
Excel VBA初心者がChatGPTを使うと挫折しにくくなる理由
CopilotでExcel作業はどこまで効率化できる?実務で使ってみた結果
Copilotに仕事を任せてみた|メール・資料作成はここまで楽になる
Copilotが向いている人・向いていない人を実体験から整理してみた
ChatGPT・Copilot・Geminiに同じ仕事を頼んだら結果が全然違った
結局どれを使えばいい?目的別に生成AIを整理してみた【初心者向け】
初心者が最初にやるべき生成AI活用① ChatGPTで「長文を理解・整理する」読むのがしんどい人ほど効果が出る使い方
初心者が最初にやるべき生成AI活用②ChatGPTに「分からないことをそのまま相談する」使い方・聞き方を気にしない安心感
初心者が最初にやるべき生成AI活用③AIを「自分専用の調べ物係」にする使い方|検索に疲れた人ほど効果が出る
ChatGPTにブログ記事を“赤ペン先生”してもらったら修正力がすごかった話―書くのが苦手な人ほど使ってほしい文章改善―
CopilotでExcel作業手順書を一瞬で作る|引き継ぎ資料が秒で完成した話
Geminiでアイデアが枯れたときの発想復活法|何も思いつかないを脱出する使い方
ChatGPT・Copilot・Geminiをブレスト役で使い分ける実例|発想が加速した方法
CopilotでExcel集計→Word報告書を一気に作る実務フロー― 月次報告が“考えずに終わる”ようになった話 ―
Copilotで会議議事録からToDo管理まで一気にやってみた実務フロー
Geminiで社内資料の画像を作ってみた|伝わらない資料が一瞬で変わった話
ChatGPTに流行りの「今まで私があなたをどう扱ってきたかを画像にして」を頼んでみた
ChatGPTのプロンプトを“自分用”に進化させる方法|頼み方で結果が激変する理由
初心者が最初にやりがちなプロンプトの失敗例と直し方
ChatGPTが急に賢くなる「前提条件」の渡し方-同じ質問なのに答えが変わるのはなぜ?-
プロンプトを毎回書かなくてよくなる“会話の残し方”
ChatGPTに「察してもらえない」と感じた時の原因と対処法|噛み合わない理由を実例で解説
AIに雑に投げても失敗しにくくなる頼み方のコツ|考えずに使っても噛み合う方法
プロンプトが思いつかない人のための“最初の一文”テンプレ集
ChatGPTを“相棒化”する人と、うまく使えない人の決定的な差
生成AIはどこまで使っていい?初心者が最初に知るべき法律の話
AI画像生成は違法?著作権で“やってはいけないこと”実例集
商用利用OK?NG?生成AIの利用規約を初心者向けに噛み砕く
AIで作った文章は誰のもの?著作権の考え方をやさしく解説
「知らなかった」では済まない?生成AIトラブル事例と回避法
ブログ・SNSでAI生成物を使うときの最低限の注意点まとめ
AIに頼りすぎて思考力が落ちた話|便利さの裏で起きたリアル失敗
AIの回答を信じて怒られた話|正しいはずが通用しなかった理由
ChatGPTにExcelマクロを直してもらったらコメントが消えた話|親切の落とし穴
Copilotの差分コードが分からなかった話|全コード出してもらう選択
ChatGPTにきれいな文章はいらなかった話|ぐちゃぐちゃでも伝わる
ChatGPTは仕事に使うだけじゃない|高校生の恋愛LINEをChatGPTに相談したら既読スルーが減った話
ChatGPTは仕事に使うだけじゃない|バツイチ48歳のマッチングアプリ不安を解消した相談実例
ChatGPTは仕事に使うだけじゃない|社内不倫の相談を法と気持ちで整理した話
ChatGPTは仕事に使うだけじゃない|離婚前に確認すべきことを全部整理してくれた話
ChatGPTは仕事に使うだけじゃない|夫が不倫しているかも…調べ方を相談してみた話
ChatGPTは仕事に使うだけじゃない|高校生の反抗期の息子への声かけを相談してみた話
ChatGPTは仕事に使うだけじゃない|大阪のマンションごみトラブルを理事会で相談した話
ChatGPTは仕事に使うだけじゃない|社内報の“ビックリマン風・ジブリ風”画像を作った話
ChatGPTは仕事に使うだけじゃない|ママ友ランチ角が立たず断れた話
ChatGPTは仕事に使うだけじゃない|会話ゼロ夫婦が再出発できた話
ChatGPTは仕事に使うだけじゃない|派遣切り50代女性の次の仕事を相談した話
ChatGPTは仕事に使うだけじゃない|これから役立つ資格をAIに本気で相談してみた話
ChatGPTは仕事に使うだけじゃない|親の介護が不安で今から準備を聞いた話
ChatGPTは仕事に使うだけじゃない|PTA役員を角が立たず断れた話
ChatGPTは仕事に使うだけじゃない|義母との距離感がしんどい悩みを整理してもらった話
ChatGPTは仕事に使うだけじゃない|家計が苦しい時に大阪市で使える制度を年齢別に聞いた話
ChatGPTは仕事に使うだけじゃない|子どものスマホルールを一緒に作ってみた話
ChatGPTは仕事に使うだけじゃない|推し活にお金を使いすぎる悩みを整理してもらった話
ChatGPTは仕事に使うだけじゃない|人間関係がしんどくて距離を置きたい時の相談実例
ChatGPTは仕事に使うだけじゃない|将来が不安で眠れない50歳手前女性の相談を整理してもらった話
Copilotでクロス表を縦持ちデータに変換|実務VBA作成の流れ
Copilotでクロス表を縦持ちデータに変換|実務仕上げ編
Copilotでクロス表を縦持ちデータに変換|配列で高速化する
Copilotでクロス表を縦持ちデータに変換|項目変更に強い構造へ












