7/07/2021

Excel。VBA。元データから必要な列だけを好きな順番でコピーしたい。【Copy of columns】

Excel。VBA。元データから必要な列だけを好きな順番でコピーしたい。

<Excel VBA>

パターン化しているような、簡単な処理になればなるほど、面倒に感じてしまいます。


例えば、次のような作業。

このような売上表があります。


これを、必要な列を任意の順番で別シートにコピーしたいという作業です。


元データは、販売日の列は一番右側にありますが、NOの次に表示させています。


範囲選択をしてコピーして貼り付ける作業ですが、コピーする列の順番を確認しながら作業するのは、面倒ですし、ミスを起こす可能性もあります。


そこで、Excel VBAでどうにかならないかと考えたわけです。


実は、Excel VBAで作るプログラム文は、たったの一行で、この希望をかなえることができます。


最初に準備が必要です。

コピー先に並べたい順で見出しを作っておく必要があります。


そして、次のようなプログラム文をつくります。

Sub 抽出コピー()

    Worksheets("MASTER").Range("a1").CurrentRegion.AdvancedFilter Action:=xlFilterCopy, copytorange:=Worksheets("COPY").Range("a1:d1")

End Sub


たった、これだけです。

説明は後回しにして、実行してみましょう。


用意した見出しの順番に、データがコピーされていることが確認できますね。


ただ、B列の販売日。

列幅が狭いので、「####」と表示されてしまっています。

日付関係では、悩まされる現象の一つですね。


このあと、列幅の自動調整をしてもいいのですが、プログラム文に含んでしまったほうが、さらに楽になりますので、次のように、プログラム文を修正します。


Sub 抽出コピー()

    Dim i As Long

    Dim lastrow As Long

    Worksheets("MASTER").Range("a1").CurrentRegion.AdvancedFilter Action:=xlFilterCopy, copytorange:=Worksheets("COPY").Range("a1:d1")

    

    Worksheets("COPY").Range("b1").Select

    

    lastrow = Cells(Rows.Count, "b").End(xlUp).Row

    

    For i = 2 To lastrow

        If Left(Cells(i, "b").Text, 1) = "#" Then

            Cells(i, "b").EntireColumn.AutoFit

        End If

    Next

End Sub


では、改めて、実行してみましょう。


B列の販売日が列幅を調整されて、綺麗に表示されていることが確認できます。


では、プログラム文を確認していきましょう。


お馴染みの変数の宣言文からですね。

Dim i As Long

Dim lastrow As Long


販売日の「#」対策で、「i」「lastrow」を用意しました。


Worksheets("MASTER").Range("a1").CurrentRegion.AdvancedFilter Action:=xlFilterCopy, copytorange:=Worksheets("COPY").Range("a1:d1")


ここが、今回のメインのプログラム文です。

Worksheets("MASTER").Range("a1").CurrentRegion は、A1を起点とした連続したセル(表)を範囲選択するという意味です。


AdvancedFilter Action:=xlFilterCopy は、フィルターオプション設定を行っています。


Excelのフィルターにある「詳細設定」をクリックしたのと同じものです。


xlFilterCopyは、フィルター処理したデータを新しい場所にコピーすることができます。


copytorange:=Worksheets("COPY").Range("a1:d1") は、抽出された行のコピー先のセル範囲を指定させています。


Worksheets("COPY").Range("b1").Select は、コピー先のシートに移動しただけです。


lastrow = Cells(Rows.Count, "b").End(xlUp).Row は、データの最終行の行番号を代入させています。

このあとのFor To Nextで使用します。


For i = 2 To lastrow

    If Left(Cells(i, "b").Text, 1) = "#" Then

        Cells(i, "b").EntireColumn.AutoFit

    End If

Next


If Left(Cells(i, "b").Text, 1) = "#" Then は、B2のセルの左から1文字目が「#」かどうかを確認させています。

もし、「#」ならば、

Cells(i, "b").EntireColumn.AutoFit 列幅を自動調整させています。


これで、任意の列の順番でデータをコピーすることができます。


Excel VBAには、様々な手法がありますので、少しずつ、使用しているファイルに組み込んで、作業効率を改善できるといいですね。