今回は自作マクロの紹介です。
販売システムなどからエクスポートしたCSVデータ、列多くないですか?
多すぎて分かりにくいことってよくあると思うんですね。
で、必要な列だけを別のシートにコピーするためのマクロを作ってみました。
ちなみにパワークエリでもできますが、、、
「パワークエリだとどうしても処理に時間がかかるし今回だけだしなぁ、サクッと必要な列だけ抜き出したいなぁ」って場面を想定しています。
Contents
マクロ作成に使った機能など
まず今回使った機能とかを整理しておくと、まずは列を選択してコピー&ペースト、これができないと話になりません。
そして複数列を選択するので、繰り返し処理の代表格であるForの使い方。
これには二重にForを使うにはどうすればいいかも含まれます。
あとはユーザーフォームのリストを使ってコピーしたい列を参照する方法、最後にこれらをどのようにまとめていくか、です。
これをまとめるとこんな感じです。
- 範囲指定とコピー&ペースト
- 列項目の取得方法
For文その1~Forの基本的な使い方~ - 任意の列のコピー
For文その2~Forの二重ループと条件分岐IF~ - ユーザーフォームの使い方
- リストボックスの操作(項目の追加など)
- マクロの作り方
で、この記事では今回のマクロの根幹となる「範囲指定とコピー&ペースト」を書いていこうと思います。
マクロでコピー&ペーストあれやこれや
まずはこちらをどうぞ。
Option Explicit
Sub 列のコピー1()
Range("A1:A6").Copy Range("C1:C6")
End Sub
Sub 列のコピー2()
Range("A1:A6").Copy Range("C1")
End Sub
Sub 列のコピー3()
Range("A1:A6").Copy Cells(1, 3)
End Sub
Sub 列のコピー4()
Range(Cells(1, 1), Cells(6, 1)).Copy Cells(1, 3)
End Sub
Sub 列のコピー5()
Range(Cells(1, 1), Cells(6, 1)).Copy _
Cells(1, 3)
End Sub
Sub 列のコピー6()
Range(ActiveWorkbook.ActiveSheet.Cells(1, 1), ActiveWorkbook.ActiveSheet.Cells(6, 1)).Copy _
ActiveWorkbook.ActiveSheet.Cells(1, 3)
End Sub
Sub 列のコピー7()
Range(Sheets("Sheet1").Cells(1, 1), Sheets("Sheet1").Cells(6, 1)).Copy _
Sheets("Sheet2").Cells(1, 1)
End Sub
Sub 列のコピー8()
With Sheets("Sheet1")
Range(.Cells(1, 1), .Cells(6, 1)).Copy _
Sheets("Sheet2").Cells(1, 1)
End With
End Sub
Sub 列のコピー9()
With Sheets(1)
Range(.Cells(1, 1), .Cells(6, 1)).Copy _
Sheets(2).Cells(1, 1)
End With
End Sub
Sub 列のコピー10()
ThisWorkbook.Sheets(1).Range("A1:A6").Copy _
Workbooks("Book1.xlsx").Sheets(1).Range("A1")
End Sub
Sub 列のコピー11()
ThisWorkbook.Sheets(1).Range("A1:A6").Copy _
ActiveWorkbook.Sheets(2).Range("A1")
End Sub
Sub 列のコピー12()
Selection.Copy Range("C1")
End Sub
Sub 列のコピー13()
Selection.Copy Cells(ActiveCell.Row, 3)
End Sub
Sub 列のコピー14()
Range(Cells(1, 1), Cells(1, 1).End(xlDown)).Copy Cells(1, 3)
End Sub
Sub 列のコピー15()
Range(Cells(1, 1), Cells(Rows.Count, 1).End(xlUp)).Copy _
Cells(1, 3)
End Sub
Sub 列のコピー16()
Range(Cells(1, 1), Cells(1, 1).End(xlToRight)).Copy _
Cells(3, 1)
End Sub
Sub 列のコピー17()
Range(Cells(1, 1), Cells(1, Columns.Count).End(xlToLeft)).Copy _
Cells(3, 1)
End Sub
(やりすぎた・・・。
今回使う、マクロでコピペするにはでどんな書き方があるのか、範囲選択方法を中心に、思いつく限り書いてみました。
なお、「Sub ~ End Sub」がひとつのブロックです。
ちなみに事前に開発タブを使えるようする方法はこちらをどうぞ。
では早速ひとつづつ見ていきましょう。
コピー&ペーストの基本形
Sub 列のコピー1()
Range("A1:A6").Copy Range("C1:C6")
End Sub
コピー&ペーストの基本はこうです。
{コピー元}.Copy {コピー先}
これはA1~A6を選択して「Ctrl+C」、C1~C6を選択して「Ctrl+V」した状態と同じです。
結果はこの図のようになります。
もちろん値貼り付けの方法などもあるのですが、今回そういった機能は使いませんので、その辺の説明は省略しています。
この記事ではコピー範囲の指定方法に絞ってお届けしています。
では次。
コピー先の指定
Sub 列のコピー2()
Range("A1:A6").Copy Range("C1")
End Sub
コピー先の範囲指定は開始セルを指定するだけでOKです。
Ctrl+Vで貼り付ける時もそうしますよね。
それと同じです。
セルをインデックスで指定
Sub 列のコピー3()
Range("A1:A6").Copy Cells(1, 3)
End Sub
コピー先に注目してください。
セルを”C3”と指定せず、行と列のインデックスから指定するにはCellsを使います。
インデックスで指定した方がいいメリットとしては、インデックスを変数に指定してタテにヨコにと動かしやすいためです。
「C3」みたいに指定するとタテにヨコに動かしにくいですよね。
Cells(行インデックス , 列インデックス)
範囲をCellsで指定
Sub 列のコピー4()
Range(Cells(1, 1), Cells(6, 1)).Copy Cells(1, 3)
End Sub
じゃあコピー元も行と列のインデックスで指定しようとするとこうなります。
Range(開始セル,終了セル)なので、開始セルと終了セルそれぞれをCells関数で指定します。
改行
Sub 列のコピー5()
Range(Cells(1, 1), Cells(6, 1)).Copy _
Cells(1, 3)
End Sub
通常「○○.Copy ××」は1行で書かないといけないのですが、セルの指定方法によっては長くなりますよね。
そこでこれを2行で表示して見やすくするのがこの書き方です。
そのまま改行しては成立しなくなりますので、文中に区切り記号を入れて改行することができるのです。
_(アンダーバー)は改行する合図
Rangeの裏にあるものは・・・?
Sub 列のコピー6()
Range(ActiveWorkbook.ActiveSheet.Cells(1, 1), _
ActiveWorkbook.ActiveSheet.Cells(6, 1)).Copy _
ActiveWorkbook.ActiveSheet.Cells(1, 3)
End Sub
ここまで書くことはないですが、通常セルを指定するためにはどのシートかを指定しないといけません。
そしてシートを指定するためにはどのブックかを指定しないといけません。
通常は、作業中のブック作業中のシートを対象にしていますので、
Range(○○).Copy Cells(x,x)
と書いた場合、作業中のブックを示すActiveWorkbook・作業中のシートを示すActiveSheetが省略されています。
シートを指定
Sub 列のコピー7()
Range(Sheets("Sheet1").Cells(1, 1), Sheets("Sheet1").Cells(6, 1)).Copy _
Sheets("Sheet2").Cells(1, 1)
End Sub
じゃあシートを指定するにはどうすれば?
その答えがこうです。
Sheets(“シート名”)でシートを指定することができます。
ちなみに、Range(“A1:A6”)とする場合にはSheets(“A1:A6”)と書けばいいのですが、Cells関数を使う場合はそのセル自体がどのシート化を指定するため、いちいちCellsの前にSheets関数でシートを指定する必要があります。
それが面倒ならこんな書き方もあります。
Sub 列のコピー7_2()
Sheets("Sheet1").Activate
Range(Cells(1, 1), Cells(6, 1)).Copy _
Sheets("Sheet2").Cells(1, 1)
End Sub
これはいったんSheet1を作業中状態にしたうえでCells関数でセルを指定します。
シートを指定せずにCells関数を使うと作業中のシートが選択されていること利用した書き方ですね。
With~End With で記載省略
Sub 列のコピー8()
With Sheets("Sheet1")
Range(.Cells(1, 1), .Cells(6, 1)).Copy _
Sheets("Sheet2").Cells(1, 1)
End With
End Sub
何度も出てくる句はWith~End Withで省略することができます。
With 省略したい語句 とし、省略するときはピリオドから開始して書きます。
そして省略扱い終了の宣言としてEnd Withで閉めます。
With ○○ / (○○省略).×× ~~ / End With
シートをインデックスで指定
Sub 列のコピー9()
With Sheets(1)
Range(.Cells(1, 1), .Cells(6, 1)).Copy _
Sheets(2).Cells(1, 1)
End With
End Sub
セルをインデックスで指定するならシートもインデックスで指定したい!
そんなときの書き方が、Sheets(インデックス)です。
ちなみにインデックスの付番はどうなってるかというと、ブックでの並び順になっています。
具体的にはこんな感じです。
Sheets(“Sheet1”).xxx.Copy Sheets(“Sheet2”).xxxとした場合
このように3番目に並んでるSheet2にコピーされました。
Sheets(1).xxx.Copy Sheets(2).xxxとした場合
この場合は2番目に並んでいるSheet3にコピーされました。
Sheets(インデックス)で指定、並び順に注意!
ThisWorkbookとWorkbooks
Sub 列のコピー10()
ThisWorkbook.Sheets(1).Range("A1:A6").Copy _
Workbooks("Book1.xlsx").Sheets(1).Range("A1")
End Sub
マクロの登録されたブック(=ThisWorkbook)から、「Book1.xlsx」(=WorkBooks(“ブック名.xlsx”) )にコピーするという意です。
ThisWorkbookとActiveWorkbook
Sub 列のコピー11()
ThisWorkbook.Sheets(1).Range("A1:A6").Copy _
ActiveWorkbook.Sheets(2).Range("A1")
End Sub
これはマクロの登録されたブックから、作業中のブック(=ActiveWorkbook)にコピーするという意です。
ただし、このブック間を渡って何かをするには、両方のブックを開いておかないといけないなど、エラーが生じやすいところでもあるので、ブック間でのやり取りは極力使わないようにしたいところです。
選択範囲を指定のセルにコピー
Sub 列のコピー12()
Selection.Copy Range("C1")
End Sub
自分で選択した範囲をコピーする、こんな時もありますよね。
そんなときの書き方がこちらです。
自分で選択した範囲:Selection
選択範囲の真横にコピー
Sub 列のコピー13()
Selection.Copy Cells(ActiveCell.Row, 3)
End Sub
Cells(ActiveCell.Row,3)の説明が必要ですね。
ActiveCellとSelectionの違いはこの通りです。
選択範囲の中でも編集可能な状態になっているセルがActiveCellということです。
そして「Row」でActiveセルの行番号を取得しています。
Shift+Ctrl+↓をVBAで
Sub 列のコピー14()
Range(Cells(1, 1), Cells(1, 1).End(xlDown)).Copy Cells(1, 3)
End Sub
範囲選択の時にShift+Ctrl+↓で選択すると思います。
それをVBAで書くとこうなります。
[セル].End(XlDown) これで[セル]から下へジャンプします。
下へジャンプ:End(XlDown)
上へジャンプ:End(XlUp)
左へジャンプ:End(XlToLeft)
右へジャンプ:End(XlToRight)
空白を含む範囲の選択
Sub 列のコピー15()
Range(Cells(1, 1), Cells(Rows.Count, 1).End(xlUp)).Copy Cells(1, 3)
End Sub
End(XlDown)では空白を含む範囲には対応できません。
で、どうするかというと、開始セルを工夫して最終行にジャンプするように書けばOKです。
それがこの句「Cells(Rows.Count, 1).End(xlUp)」です。
Rows.Countでこのシートの最終行のインデックスを取得し、そのセルを開始位置として上にジャンプ。
これでデータ最終行に一回でたどり着くわけです。
定型文として暗記をお勧めします。
Cells(Rows.Count, 1).End(xlUp)
ちなみに今回紹介するマクロで使用する書き方はこれです。
左右にジャンプ
Sub 列のコピー16()
Range(Cells(1, 1), Cells(1, 1).End(xlToRight)).Copy Cells(3, 1)
End Sub
Sub 列のコピー17()
Range(Cells(1, 1), Cells(1, Columns.Count).End(xlToLeft)).Copy Cells(3, 1)
End Sub
上下にジャンプの左右バージョンです。
こちらも空白を含む場合End(XlToRight)では対応できないので、最終列から左にジャンプでデータ最終列のインデックスを取得します。
これも定型文として暗記をお勧めします。
Cells(1, Columns.Count).End(xlToLeft)
ふう。。。
まとめ
たくさん書きましたが、これだけ覚えておいて下さい。
コピー&ペースト:コピー元.Copy コピー先
列の範囲指定:Cells(Rows.Count, 1).End(xlUp)
今回はこの辺で、次回「列項目の取得方法 For文その1~Forの基本的な使い方~」に続きます。
最後まで読めた方、ありがとうございます。
ほんっっっとうに、ありがとうございましたっ!!