Copilotでクロス表を縦持ちデータに変換|項目変更に強い構造へ

前回コードの限界

前回は配列を使って高速化し、処理速度の問題は完全に解決しました。

ここまで来ると、多くの人が「完成」と思います。

ただ、実務ではもう一つ必ず問題が出ます。

それが

項目の増減

です。

例えばこういうケースです。

・元データに列が追加される
・列の順番が変わる
・名称が微妙に変わる

このとき、今のコードはどうなるか。

普通に壊れます。

理由はシンプルで、列番号で処理しているからです。

つまり

A列だからOK
B列だからOK

という前提に依存しています。

実務ではこの前提はほぼ崩れます。

前回に引き続き、経済産業省の公開データである「第3次産業活動指数【月次】業種別原指数」のデータを使わせていただいています。

今回の修正内容(壊れないコードにする)

今回やるのはここです。

・1行目(ヘッダー)を配列に取り込む
・Dictionaryで項目名 → 列番号を管理
・列指定を「番号」ではなく「名前」で行う

これでどうなるかというと、列の位置が変わっても壊れません。

これが実務ではかなり重要です。

Dictionary オブジェクト(連想配列)に登録された値(item)を、キー(key)やインデックス番号を指定して取得する(Excel VBA)

A列の品目番号とB列の 品目名称を入れ替えても・・・

Copilotでクロス表を縦持ちデータに変換|項目変更に強い構造へ

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

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

Copilotでクロス表を縦持ちデータに変換|項目変更に強い構造へ

■■■スポンサーリンク■■■

実際の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でクロス表を縦持ちデータに変換|項目変更に強い構造へ

■■■スポンサーリンク■■■

ChatGPTは仕事に使うだけじゃない|家計が苦しい時に大阪市で使える制度を年齢別に聞いた話

家計が苦しい大阪市のシングルマザー・ひとり親家庭向けに、ChatGPTへ実際に相談したやり取りを全文掲載。児童扶養手当、医療費助成、就学援助など、子どもの年齢別に使える行政サービスと優先順位まで初心者向けに解説します。

ChatGPTは仕事に使うだけじゃない|義母との距離感がしんどい悩みを整理してもらった話

義母との関係がつらい、帰省が憂鬱、夫にどう相談すればいいか分からない人向けに、ChatGPTへ実際に相談したやり取りを全文掲載。義母との距離感の作り方、トラブルになりにくい考え方、元夫への伝え方まで初心者にも分かりやすく解説します。