この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
横に長いデータを指定した列数ごとに改行して縦長のデータに整理するマクロを(エクセル初心者に向けて)紹介します。
はじめに
初めまして、新卒でゲームプランナーをやっている者です。プランナー職ではゲーム内のデータをエクセルで管理・編集するため、エクセルに慣れていないとつまずくことが多々あります。本記事では、エクセルをあまり使ったことがない人に向けて、検索しても出てこなかったエクセルの簡単なマクロを紹介したいと思います。
前置き
ゲーム内の種々のデータ、例えばキャラやエネミーのパラメータ等の多くは、プランナーがエクセルで管理しています(マスターデータと言います)。スマホ向けゲームでもそのデータ量は膨大で、作業の多くはエクセルの関数などで機械的に行わないと、とてつもない時間が掛かってしまいます。これが、そもそも私がエクセルのマクロを使い始めた理由です。
エクセルのマクロ機能の紹介
今回は私のような初心者の方を想定して、エクセルのマクロとは何なのか、というところから記しておこうと思います。
エクセルには様々な機能がまとまっていますが、それらの機能を人が動かすのではなく、プログラムで動かしてやることができます。それがマクロです。正しく使えれば、人間では膨大な時間がかかるような作業を瞬時に行うことが可能です。
エクセルのタブに開発というタブがあれば、すでにマクロが使える状態になっています。
出てない方は【ファイル】→【オプション】→【セキュリティーセンター】と進み、ここで設定を変更すれば表示されるようになります。
マクロを組むということは、エクセルにどのような手順で作業をしてほしいかを指定することです。難しく感じるかも知れませんが、エクセルでは人の行動を記録してマクロを作ることも可能です。プログラムなんて書けないっていう方でも、開発からマクロの記録を選択すると、そこからの動作をマクロとして記録してくれます。
これを用いれば、単純な反復作業をボタンぽちっとすればエクセルがやってくれるようになるわけです。
開発タブから【Visual Basic】を押せば、行動記録ではなく、自分でプログラムしてマクロを組むことができる画面になります。ここで紹介するコードは、この画面で作ったものです。
指定列ごとに改行したデータを作成するマクロ
前置きが長くなりましたが、本題に入ります。私が直面したのは、横長のデータを4列ごとで改行して縦長にして整理したい、という状況です。エクセルには、行から列へ、列から行へ変換する機能は元々備わっていますが、4列ごとに行へ変換することは(おそらく)できません。
エクセルの関数だけを用いてやろうとすると、今の場合4列ごとと決まっているので、コピーしたいセルの指定をOFFSET関数やMOD関数などを組み合わせてやればできるかもしれませんが、ちょっと難しくて分かりません。
前述の行動記録マクロを作ろうにも、対象とするセルが毎回変わってしまうので、どうにも上手くいきません。そこで、マクロに挑戦してみました。さっそくコードです。
Sub 複数列コピペ()
Dim ds As Worksheet, ad As Worksheet
Dim MaxRow As String, MaxRow_ad As String, MaxColumn As String
Dim i As Integer, INP As Integer
Set ds = Sheets("元データ")
Set ad = Sheets("整形後データ")
MaxRow = ds.Cells(Rows.Count, 1).End(xlUp).Row
MaxColumn = ds.Cells(1, Columns.Count).End(xlToLeft).Column
For i = 1 To MaxRow
For INP = 1 To MaxColumn Step 4
ds.Range(Cells(i, INP), Cells(i, INP + 3)).Copy
MaxRow_ad = ad.Cells(Rows.Count, 1).End(xlUp).Row
ad.Cells(MaxRow_ad + 1, 1).Insert
Application.CutCopyMode = False
Next INP
Next i
End Sub
プログラミング経験がほぼないので、見る人が見たら鼻で笑われるコードかもしれませんし、不要なことをしているかもしれませんが、求めていた動作はしてくれました。
タイトルでは改行と書いてありますが、その実態は”元データ”シートから4列ずつコピーして”整形後データ”シートに貼り付けるということをしています。つまり、
このようなデータを別のシートに
という形にして貼り付けします。
種々の関数の説明は省略しますが、僭越ながら軽く動作の説明をしたいと思います。
最初に、使う変数の定義をし、そのあとにエクセルのシート名を変数に入れています。
次に、コピーしたいデータの最終行と最終列の情報を次の2文で持ってきています。
MaxRow = ds.Cells(Rows.Count, 1).End(xlUp).Row
MaxColumn = ds.Cells(1, Columns.Count).End(xlToLeft).Column
次に、For文で今持ってきた行数分だけ同じ動作を繰り返します。
その動作が、
・1列目から4列目までをコピー(INP=1のとき)
ds.Range(Cells(i, INP), Cells(i, INP + 3)).Copy
・貼り付け対象シートのデータが入っている最後の行を取得
MaxRow_ad = ad.Cells(Rows.Count, 1).End(xlUp).Row
・その次の行にコピーしたデータを貼り付ける
ad.Cells(MaxRow_ad + 1, 1).Insert
・コピペモードを終了し、次のINPに4を足して次のループへ
という流れになっています。
終わりに
本職エンジニアの方々が難しそうな記事を投稿している中、初心者が簡単なコードを投稿するという恐れ多い記事ですが、お役に立てたら幸いです。マクロをまだまだ理解できていないので、他の方の環境でも動作するのか分かりませんが、ご了承ください。
※2017/06/13 記事をより分かりやすくするため、編集しました。