事前準備
まず、サンプルデータ挿入用の関数などを用意します。
'サンプルデータ挿入用 Private Sub AddTestColumn(ws As IXLWorksheet) ws.Cell("A1").SetValue("B").Style.Fill.SetBackgroundColor(XLColor.LightGreen) ws.Cell("A2").SetValue("A").Style.Fill.SetBackgroundColor(XLColor.DarkTurquoise) ws.Cell("A3").SetValue("a").Style.Fill.SetBackgroundColor(XLColor.BurlyWood) ws.Cell("A4").SetValue("").Style.Fill.SetBackgroundColor(XLColor.DarkGray) ws.Cell("A5").SetValue("").Style.Fill.SetBackgroundColor(XLColor.DarkSalmon) ws.Cell("A6").SetValue("b").Style.Fill.SetBackgroundColor(XLColor.DodgerBlue) ws.Cell("A7").SetValue("B").Style.Fill.SetBackgroundColor(XLColor.IndianRed) ws.Cell("A8").SetValue("c").Style.Fill.SetBackgroundColor(XLColor.DeepPink) End Sub 'サンプルデータ挿入用 Private Sub AddTestTable(ws As IXLWorksheet) ws.Cell("A1").SetValue("B").Style.Fill.SetBackgroundColor(XLColor.LightGreen) ws.Cell("A2").SetValue("A").Style.Fill.SetBackgroundColor(XLColor.DarkTurquoise) ws.Cell("A3").SetValue("a").Style.Fill.SetBackgroundColor(XLColor.BurlyWood) ws.Cell("A4").SetValue("A").Style.Fill.SetBackgroundColor(XLColor.DarkGray) ws.Cell("A5").SetValue("").Style.Fill.SetBackgroundColor(XLColor.DarkSalmon) ws.Cell("A6").SetValue("A").Style.Fill.SetBackgroundColor(XLColor.DodgerBlue) ws.Cell("A7").SetValue("a").Style.Fill.SetBackgroundColor(XLColor.IndianRed) ws.Cell("A8").SetValue("B").Style.Fill.SetBackgroundColor(XLColor.DeepPink) ws.Cell("B1").SetValue("").Style.Fill.SetBackgroundColor(XLColor.LightGreen) ws.Cell("B2").SetValue("a").Style.Fill.SetBackgroundColor(XLColor.DarkTurquoise) ws.Cell("B3").SetValue("B").Style.Fill.SetBackgroundColor(XLColor.BurlyWood) ws.Cell("B4").SetValue("A").Style.Fill.SetBackgroundColor(XLColor.DarkGray) ws.Cell("B5").SetValue("a").Style.Fill.SetBackgroundColor(XLColor.DarkSalmon) ws.Cell("B6").SetValue("A").Style.Fill.SetBackgroundColor(XLColor.DodgerBlue) ws.Cell("B7").SetValue("a").Style.Fill.SetBackgroundColor(XLColor.IndianRed) ws.Cell("B8").SetValue("a").Style.Fill.SetBackgroundColor(XLColor.DeepPink) ws.Cell("C1").SetValue("A").Style.Fill.SetBackgroundColor(XLColor.LightGreen) ws.Cell("C2").SetValue("").Style.Fill.SetBackgroundColor(XLColor.DarkTurquoise) ws.Cell("C3").SetValue("A").Style.Fill.SetBackgroundColor(XLColor.BurlyWood) ws.Cell("C4").SetValue("a").Style.Fill.SetBackgroundColor(XLColor.DarkGray) ws.Cell("C5").SetValue("A").Style.Fill.SetBackgroundColor(XLColor.DarkSalmon) ws.Cell("C6").SetValue("b").Style.Fill.SetBackgroundColor(XLColor.DodgerBlue) ws.Cell("C7").SetValue("A").Style.Fill.SetBackgroundColor(XLColor.IndianRed) ws.Cell("C8").SetValue("").Style.Fill.SetBackgroundColor(XLColor.DeepPink) End Sub '矢印を挿入 Private Sub InsertArrow(range As IXLRange, Optional arrowText As String = "→") range.Merge.SetValue(arrowText).Style.Alignment _ .SetVertical(XLAlignmentVerticalValues.Center).Alignment _ .SetHorizontal(XLAlignmentHorizontalValues.Center) _ .Font.SetFontSize(25).Font.SetBold(True) _ .Font.SetFontColor(XLColor.Red) End Sub
注意
元記事のサンプルデータは、Blank(空白、空欄)を表すためにスペース文字 ” ” を使用しています。
ところが元記事のサンプルデータをそのまま使用すると、ソートしても、元記事と同じソート結果にはなりませんでした。
何度か試してみた結果、ClosedXML の Sort メソッドのオプションである “IgnoreBlanks As Boolean” の “Blanks” はスペース文字のことではなく、空文字または Nothing のことだと思われます。
そのため、この記事でのサンプルデータでは、元記事でスペース文字 ” ” だったところを空文字 “” にしています。
by エレン・イースト(当サイトの管理人)
範囲の単純ソート
範囲をシンプルにソートします。
Dim wb = New XLWorkbook Dim ws = wb.Worksheets.Add("範囲をシンプルにソート") 'サンプルデータを用意 Call AddTestTable(ws) '用意したサンプルデータの右側にデータをコピー Dim rangeSimple = ws.RangeUsed Dim copySimple = rangeSimple.CopyTo(ws.Column(ws.LastColumnUsed.ColumnNumber + 2)) 'コピーしたデータをソート copySimple.Sort '「→」を挿入 Call InsertArrow(ws.Range("D1:D8")) '説明文を挿入 ws.Row(1).InsertRowsAbove(2) ws.Cell(1, 1).SetValue(".Sort = 範囲を上から下へ昇順ソート、英字大小同一視、空白を無視").Style.Font.SetBold 'A1 が選択されてると説明文が読みにくいので別のところを選択 ws.LastCellUsed.CellRight.CellBelow.Select wb.SaveAs("D:\test\SortSimple.xlsx")
1つの列のソート
Dim wb As New XLWorkbook Dim ws = wb.Worksheets.Add("1つの列をソート") 'サンプルデータを用意 Call AddTestColumn(ws) '用意したサンプルデータの右側にデータをコピー Dim rangeSimpleColumn = ws.RangeUsed Dim copySimpleColumn = rangeSimpleColumn.CopyTo(ws.Column(ws.LastColumnUsed.ColumnNumber + 2)) 'コピーしたデータをソート copySimpleColumn.Sort(1, XLSortOrder.Descending, True) '「→」を挿入 Call InsertArrow(ws.Range("B1:B8")) '説明文を挿入 ws.Row(1).InsertRowsAbove(2) ws.Cell(1, 1).SetValue(".Sort(1, XLSortOrder.Descending, True) = 範囲を上から下へ降順ソート、英字大小を区別、空白を無視").Style.Font.SetBold 'A1 が選択されてると説明文が読みにくいので別のところを選択 ws.LastCellUsed.CellRight.CellBelow.Select wb.SaveAs("D:\test\SortSingleColumn.xlsx")
複雑なソート(1)
Dim wb = New XLWorkbook Dim ws = wb.Worksheets.Add("複雑なソート(1)") 'サンプルデータを用意 Call AddTestTable(ws) '用意したサンプルデータの右側にデータをコピー Dim rangeComplex1 = ws.RangeUsed Dim copyComplex1 = rangeComplex1.CopyTo(ws.Column(ws.LastColumnUsed.ColumnNumber + 2)) 'コピーしたデータをソート copyComplex1.Sort(columnsToSortBy:="2, 1 DESC", matchCase:=True) '元記事通り copyComplex1.Sort("2, 1 DESC", True) とすると 'オーバーロードの解決に失敗しエラーとなる。名前付き引数を使えば問題ない。 'by エレン・イースト(当サイトの管理人) '「→」を挿入 Call InsertArrow(ws.Range("D1:D8")) '説明文を挿入 ws.Row(1).InsertRowsAbove(2) ws.Cell(1, 1).SetValue(".Sort = 範囲を上から下へ列2を昇順ソート、列1を降順ソート、英字大小を区別、空白を無視").Style.Font.SetBold 'A1 が選択されてると説明文が読みにくいので別のところを選択 ws.LastCellUsed.CellRight.CellBelow.Select wb.SaveAs("D:\test\SortComplex1.xlsx")
複雑なソート(2)
Dim wb = New XLWorkbook Dim ws = wb.Worksheets.Add("複雑なソート(2)") 'サンプルデータを用意 Call AddTestTable(ws) '用意したサンプルデータの右側にデータをコピー Dim rangeComplex2 = ws.RangeUsed Dim copyComplex2 = rangeComplex2.CopyTo(ws.Column(ws.LastColumnUsed.ColumnNumber + 2)) 'コピーしたデータをソート copyComplex2.SortColumns.Add(1, XLSortOrder.Ascending, False, True) copyComplex2.SortColumns.Add(3, XLSortOrder.Descending) copyComplex2.Sort '.Sort メソッドと .SortColumns メソッドでは matchCase, ignoreBlanks オプションの順番が異なるので注意。 '紛らわしいときは名前付き引数(matchCase:=True など)を使うと良いかも。 'by エレン・イースト(当サイトの管理人) '「→」を挿入 Call InsertArrow(ws.Range("D1:D8")) '説明文を挿入 ws.Row(1).InsertRowsAbove(4) ws.Cell(1, 1).SetValue(".SortColumns.Add(1, XLSortOrder.Ascending, False, True) = 列1を昇順ソート、空白を無視しない、英字大小を区別").Style.Font.SetBold ws.Cell(2, 1).SetValue(".SortColumns.Add(3, XLSortOrder.Descending) = 列3を降順ソート、空白を無視、英字大小を無視").Style.Font.SetBold ws.Cell(3, 1).SetValue(".Sort = SortColumns に設定されたパラメータを使用してソート").Style.Font.SetBold 'A1 が選択されてると説明文が読みにくいので別のところを選択 ws.LastCellUsed.CellRight.CellBelow.Select wb.SaveAs("D:\test\SortComplex2.xlsx")
左から右にソート
Dim wb = New XLWorkbook Dim ws = wb.Worksheets.Add("左から右にソート") 'サンプルデータを用意 Call AddTestTable(ws) 'サンプルデータを回転 ws.RangeUsed().Transpose(XLTransposeOptions.MoveCells) '用意したサンプルデータの下にデータをコピー Dim rangeLeftToRight = ws.RangeUsed Dim copyLeftToRight = rangeLeftToRight.CopyTo(ws.Row(ws.LastRowUsed.RowNumber + 2)) 'コピーしたデータをソート copyLeftToRight.SortLeftToRight '「↓」を挿入 Call InsertArrow(ws.Range("D4:D4"), "↓") '説明文を挿入 ws.Row(1).InsertRowsAbove(2) ws.Cell(1, 1).SetValue(".SortLeftToRight = 範囲を左から右にソート、昇順、空白を無視、英字大小を無視").Style.Font.SetBold 'A1 が選択されてると説明文が読みにくいので別のところを選択 ws.LastCellUsed.CellRight.CellBelow.Select wb.SaveAs("D:\test\SortLeftToRight.xlsx")
テーブルのソート
Dim wb = New XLWorkbook Dim ws = wb.Worksheets.Add("テーブルのソート") 'サンプルデータを用意 Call AddTestTable(ws) 'サンプルデータの上に列タイトルを挿入 Dim header = ws.Row(1).InsertRowsAbove(1).First For co As Int32 = 1 To ws.LastColumnUsed.ColumnNumber header.Cell(co).Value = "列" & co.ToString Next '用意したサンプルデータの右側にデータをコピー Dim rangeTable = ws.RangeUsed Dim table = rangeTable.CopyTo(ws.Column(ws.LastColumnUsed.ColumnNumber + 2)) _ .CreateTable 'そしてテーブルを作成 'テーブルをソート table.Sort("列2, 列3 Desc, 列1 ASC") '「→」を挿入 Call InsertArrow(ws.Range("D2:D9")) '説明文を挿入 ws.Row(1).InsertRowsAbove(2) ws.Cell(1, 1).SetValue(".Sort(""列2, 列3 Desc, 列1 ASC"") = テーブルを上から下へソート、列2 昇順、列3 降順、列1 昇順、空白を無視、英字大小を無視").Style.Font.SetBold 'A1 が選択されてると説明文が読みにくいので別のところを選択 ws.LastCellUsed.CellRight.CellBelow.Select wb.SaveAs("D:\test\SortTable.xlsx")