VBA

【VBA】テーブルの列の並び替えと絞り込みを一発で行う関数

記事内に商品プロモーションを含む場合があります

こんにちは、hokkyokunです。

テーブルの列の並び替えはデフォルトではメソッドが用意されていません。
また、不要な列は削除で消していかなければいけず、
必要な列だけ絞り込みも基本的にはできません。

これらを解消する関数を作成しました。
一部、当サイトで作った別の関数を使いますが、
基本的にはコピペで動きます。

関数

  • 関数名
    arange_tableCol( table , columns )
  • 引数
    ①table : 対象のテーブル(データ型はListObject)
    ②columns : 並び替え順を指定した列名(データ型は配列)
  • 戻り値
    並び替え後のテーブル
Function arange_tableCol(ByRef table As ListObject, ByVal columns As Variant)
    Dim i, j, k As Long
    Dim arrsT As Variant
    Dim orders, order As Variant
    Dim temp, temp2 As Variant
    Dim resultC, resultData, resultDatas As Variant
    Dim tableStyle As String
    Dim tableRange As Range
    Dim ws As Worksheet
    
    '並び替え前のテーブルを配列に格納
    arrsT = table_Input(table)
    
    '並び替え後の列順を並び替え前の列順に当てはめる
    '例えば並び替え後の列名=["名前", "数学", "家庭科"]
    '並び替え前の列名=["家庭科", "英語", "名前", "数学"]とする
    '並び替え後の順番を並び替え前の順番に当てはめると、
    '"名前"は2番目、"数学"は3番目、"家庭科"は0番目となる
    '結果 [ 2 , 3 , 0 ]となる配列を得ることが目標
    For i = 0 To UBound(columns)
        For j = 0 To UBound(arrsT(0))
            If columns(i) = arrsT(0)(j) Then
                Call add_Elm(orders, j)
            End If
        Next
    Next
    
    '並び替えテーブルを格納した配列からordersでとった順番の要素を取って再構築
    For Each order In orders
        Call add_Elm(resultC, arrsT(0)(order))
    Next
    For k = 0 To UBound(arrsT(1))
        temp = Array()
        For Each order In orders
            Call add_Elm(temp, arrsT(1)(k)(order))
        Next
        Call add_Elm(resultDatas, temp)
    Next
    
    '並び替え前のテーブルの書式、位置、テーブルあったシートを記録
    tableStyle = table.tableStyle
    Set tableRange = table.Range(1)
    Set ws = table.Parent
    
    '並び替えテーブルを削除(データだけ消す、じゃないと列や行がくずれる)
    table.tableStyle = ""
    table.Range.ClearContents
    
    '転記
    i = tableRange.Row
    j = tableRange.column
    For Each temp In resultC
        ws.Cells(i, j).Value = temp
        Set tableRange = Union(tableRange, ws.Cells(i, j))
        j = j + 1
    Next
    
    i = tableRange.Row + 1
    For Each temp In resultDatas
        j = tableRange.column
        For Each temp2 In temp
            ws.Cells(i, j).Value = temp2
            Set tableRange = Union(tableRange, ws.Cells(i, j))
            j = j + 1
        Next
        i = i + 1
    Next
    
    'テーブル化
    Set arange_tableCol = ws.ListObjects.Add(xlSrcRange, tableRange, , xlYes, , tableStyle)
End Function

本コードはかなり長く、複雑な処理をしています。
少しでも短く、わかりやすくするため当サイトで作成した関数を使っています。

以下の関数をコピペして使用していただけると幸いです。
(下記をクリックするとそれぞれコードが公開されているページに飛びます)

使い方

下記のような順番がぐちゃぐちゃなテーブルがあったとします。

このテーブルを[ 名前, 国語, 英語, 数学 ]の順番にし、
「体育」と「家庭科」は列を省くとします。

Sub test_arange()
    Dim table As ListObject
    Dim columns As Variant
    
    Set table = ThisWorkbook.Worksheets("Table2").ListObjects(1)
    
    columns = Array("名前", "国語", "英語", "数学")
    
    Set table = arange_tableCol(table, columns)
    
End Sub

実行すると以下のようになります。

図ではわかりずらいですが、
エクセルブックにおいて位置は全く変わっていません

シートもセルの位置も変わっていません
また、隣接して何か記入されていたとしても勝手にテーブル範囲が変わったりもしません。

純粋にテーブルの列名の編集だけ行っています。

また、戻り値として並び替え後のテーブルを取得できるので
続けてプログラムを記述することができます。

まとめ

関数名:arange_tableCol( table , columns )

引数
①table : 対象のテーブル(データ型はListObject)
②columns : 並び替え順を指定した列名(データ型は配列)

戻り値
並び替え後のテーブル

VBAの学習方法をまとめました。

VBA(マクロ)のおすすめの学習方法 こんにちはhokkyokunです。 VBAを学ぶことで確実に業務は効率化し、余裕をもって仕事をすることができるようになります。 ...

VBAを高コスパで、短期間で学ぶにはUdemyがおすすめです。
Udemyは良質の学習プラットフォームですが、動画数が多すぎてどれを見ればよいか迷います。

おすすめの講師をまとめました。

【Udemyは講師で選べ!】UdemyがVBA学習に最適な理由とおすすめのVBA講師 こんにちはhokkyokunです。 巨大学習プラットホームUdemyの中からVBAに関する動画について講師に焦点を当ててまとめま...