Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 10 Pro : Microsoft 365)
F列、G列の項目を使ってデータの並べ替えを行いたい
投稿日時: 24/05/29 16:23:46
投稿者: takatada72

お疲れさまです。
下記のコードは、CSVシートに、A列から、DZまでデータがあり、不必要な項目だけ削除します。
残った列は、A列からI列が残り、その後、F列:(発売年月:2024年05月)・G列(週:1-5の文字だけ)を並べ替えの条件にして、A-Iを並べ替えを実施したいのです。
 
Copilotに聞きながら、試してみたのですが、発売年月、週の並べ替えがされていませんでした。
どこをどのように修正すれば、正しく並べ替えできますでしょうか
 
お忙しいとは思いますが宜しくお願い致します。
 
 
 
 
   Dim ws As Worksheet
    Dim targetRange As Range
    Dim cell As Range
     
    ' アクティブなシートを取得
    Set ws = ActiveSheet
         
    ws.Range("C:D").Delete
    ws.Range("E:F").Delete
    ws.Range("H:CI").Delete
    ws.Range("I:AD").Delete
    ws.Range("J:X").Delete
     
     
    ' 表示されている列の幅を調整
    Columns(1).ColumnWidth = 10 'A列
    Columns(2).ColumnWidth = 12 'B列
    Columns(3).ColumnWidth = 50 'C列
    Columns(4).ColumnWidth = 40 'D列
    Columns("E:I").AutoFit
 
' F、G列を基準に昇順で並べ替え
    ' 最初のシートを取得
    Dim ws2 As Worksheet
    Set ws2 = ThisWorkbook.Sheets(1)
     
    ' 最終行を取得
    Dim lastRow As Long
    lastRow = ws2.Cells(ws2.Rows.Count, "A").End(xlUp).Row
     
    ' F列とG列の範囲を指定
    Dim sortRange As Range
    Set sortRange = ws2.Range("F2:G" & lastRow)
     
    ' F列を昇順で並び替え
    sortRange.Sort Key1:=sortRange.Columns(1), Order1:=xlAscending, Header:=xlYes
     
    ' G列を昇順で並び替え
    sortRange.Sort Key1:=sortRange.Columns(2), Order1:=xlAscending, Header:=xlYes
     
End

回答
投稿日時: 24/05/29 17:57:59
投稿者: WinArrow

掲示したコードが
  
Copilot
が作成したコードですか?
  
多分、質問の仕方に問題があるのではないでしょうか?
  
もう一度、やりたいことを整理して、トライしてみては?
 
最後まで、Copilotに面倒見てもらったら・・・・

回答
投稿日時: 24/05/29 22:15:04
投稿者: WinArrow

ヒント
 
ソートメソッドでは、一度にキーを複数指定できます。
英字のコード記述は、Excel2003までの仕様です。キーは3つまで指定できます。

投稿日時: 24/05/30 09:50:32
投稿者: takatada72

WinArrowさん
 
お疲れさまです。
 
質問の仕方しだいと感じておりますが、VBA事態が完全に理解していないのと、
質問の言葉が乏しいので、何かヒントをもらえないかと思っての投稿です。
 
今回、キーは、2つなので、
ソートメソッドをお使って、第一キーは、F列:(発売年月)第二キーをG列(週)して
A列からI列を並べ替えるVBAコードを教えて下さいでいいですかね
 
引き続き、VBAなどが理解していない私でも、COPILOTから、正しいコードが出せる
ヒントを教えて頂けると幸いです。
 
お忙しいとは思いますが宜しくお願い致します。[/b]

投稿日時: 24/05/30 10:22:48
投稿者: takatada72

何度、COPILOTに問い合わせしても、同じコードでの回答してもらえません。
 
他の追加ヒントは、ないでしょうか
お忙しいとは思いますが宜しくお願い致します。
 
マクロ作成で作ったコードで実行すると正しく、並べ替えされましたが、コードが
美しくないので、COPILOTに聞くと、同じコードが出力され、並べ替えが正しくなく
なってしまうのです。
 
宜しくお願い致します。
    ActiveWorkbook.Worksheets(1).Sort.SortFields.Clear
    ActiveWorkbook.Worksheets(1).Sort.SortFields.Add2 _
        Key:=Range("F2:F6176"), SortOn:=xlSortOnValues, Order:=xlAscending, _
        DataOption:=xlSortNormal
    ActiveWorkbook.Worksheets(1).Sort.SortFields.Add2 _
        Key:=Range("G2:G6176"), SortOn:=xlSortOnValues, Order:=xlAscending, _
        DataOption:=xlSortNormal
    With ActiveWorkbook.Worksheets(1).Sort
        .SetRange Range("A1:I10000")
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
 
COPILOTに上のコードを集約して下さいと言うと、下記のようになってしまい、実行しても
正しい並び替えにならないのです。
    ' F列を昇順で並び替え
    sortRange.Sort Key1:=sortRange.Columns(1), Order1:=xlAscending, Header:=xlYes
      
    ' G列を昇順で並び替え
    sortRange.Sort Key1:=sortRange.Columns(2), Order1:=xlAscending, Header:=xlYes

回答
投稿日時: 24/05/30 10:56:29
投稿者: sk

引用:
F列:(発売年月:2024年05月)・G列(週:1-5の文字だけ)を
並べ替えの条件にして、A-Iを並べ替えを実施

(標準モジュール)
------------------------------------------------------------
Sub SortByAutoFilter()
     
    Dim wsTarget As Worksheet
    Dim rngTarget As Range
    Dim lngFirstRow As Long
    Dim lngLastRow As Long
     
    Set wsTarget = ActiveSheet
     
    With wsTarget
 
        If .AutoFilterMode = True Then
            .ShowAllData
            .AutoFilterMode = False
        End If
         
        lngFirstRow = 1
        lngLastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
         
        If lngFirstRow >= lngLastRow Then
            Set wsTarget = Nothing
            Exit Sub
        End If
         
        Set rngTarget = .Range(.Cells(lngFirstRow, 1), _
                               .Cells(lngLastRow, 9))
         
        rngTarget.AutoFilter
             
    End With
     
    With wsTarget.AutoFilter.Sort
        .SortFields.Clear
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .SortFields.Add2 Key:=rngTarget.Columns(6), _
                         SortOn:=xlSortOnValues, _
                         Order:=xlAscending, _
                         DataOption:=xlSortNormal
        .SortFields.Add2 Key:=rngTarget.Columns(7), _
                         SortOn:=xlSortOnValues, _
                         Order:=xlAscending, _
                         DataOption:=xlSortNormal
        .Apply
    End With
     
    wsTarget.AutoFilterMode = False
     
    Set rngTarget = Nothing
    Set wsTarget = Nothing
 
End Sub
------------------------------------------------------------
 
以上のような処理を実行できればよい、ということでしょうか。

回答
投稿日時: 24/05/30 16:34:17
投稿者: WinArrow

時: 24/05/29 16:23:46投稿者: takatada72
掲示のコードで、基本的な間違いは、2ヶ所
 
1ヶ所目
ソート範囲:
「A-Iを並べ替えを実施したい」と書いているのに
>Set sortRange = ws2.Range("F2:G" & lastRow)
というコードになっています。
※マクロの記録で作成したコードでは、クリアしています。
※この問題は気が付いていないのかな?
 
2ヶ所目
ソートキーの個数ではなく、ソートメソッド実行は1回でよい
のに、2回実行するコードになっている
※今回、この点に焦点を当たっている。
 
マクロの記録で作成したコードがきれいでない・・・ではなく、
機能するコードでなくては意味がありません。
今後、仕様の変更が生じた場合、全部あなたが対応することになるから、
コードをキチンと理解する(Copilotで得られたコードを含む)力をつけることをお勧めします。
Copilotは、ヒントをもらえるもの(マクロの記録と同じかそれ以下か)という割り切りで使うとよいでしょう、仕様変更に対応するメンテナンスに、使えるか分かりません。
 
 
 
 
 

回答
投稿日時: 24/05/31 07:26:48
投稿者: simple

既に皆さんから指摘いただいているとおりです。
参考情報をいくつか追加しておきます。
 
SortオブジェクトはExcel2007で導入されたもので、
従来のRangeのSortメソッドとは別ものです。
・従来の方法がソートキーが最大3個であったのに対して、
・Sortオブジェクト利用ではその制限はありません。
・また、速度もSortオブジェクトのほうが速いとされています。
しかし一方で、
・簡単なソートなら、Sortメソッドのほうが簡単に書けることも事実です。
二つの方法をきちんと分けて理解する必要があります。
 
【参照サイト】
Sortオブジェクト
https://learn.microsoft.com/ja-jp/office/vba/api/excel.sort
RangeのSortメソッド
https://learn.microsoft.com/ja-jp/office/vba/api/excel.range.sort
なお、MS社以外のサイトなら、
"ソート site:http://officetanaka.net" などと検索すれば、有益な記事がいくつも出てきます。
 

> ソートキーの個数ではなく、ソートメソッド実行は1回でよい
> のに、2回実行するコードになっている
> ※今回、この点に焦点を当たっている。

ご指摘のとおりです。
 
追記すると、Sortメソッドを2回実行するなら、

最初に 優先度の低いキー(G列)でソートし、
次に   優先度の高いキー(F列)でソートすれば望む結果が得られます。
(ソート対象範囲をきちんと指定することは当然です。質問以前です)
こうして考えると、Sortメソッドで指定できるキーは3つが限度ですが、
優先順位の低いものから実施すれば、実質、その制限はないとも言えます。
 

COPILOTとかChatGPTといった生成系AIの利用にあたっては、それは間違っている可能性が
かなりある、という前提で受け止めるべきです。
 
「COPILOTに上のコードを集約して下さい」と質問されたそうですが、適切でなかったのかもしれません。
以下のように見やすくすることはできますが、Sortオブジェクトを使う限り、
幾分コード量は増えることを甘受しなければなりません。
 
Sub test()
    With Worksheets(1).Sort
        With .SortFields
            .Clear
            .Add2 Key:=Range("F2"), SortOn:=xlSortOnValues, _
                  Order:=xlAscending, DataOption:=xlSortNormal
            .Add2 Key:=Range("G2"), SortOn:=xlSortOnValues, _
                  Order:=xlAscending, DataOption:=xlSortNormal
        End With
        .SetRange Range("A1:I10000")
        .Header = xlYes
        .MatchCase = False              
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
End Sub

投稿日時: 24/05/31 08:53:45
投稿者: takatada72

skさん、修正して頂いたので大変助かりました。skさんのコードをそのまま
導入したら、並べ替えがうまく行きました。
ありがとうございました。
 
WinArrowさん、解説して頂きましてありがとうございました。少しづづ、内容
を理解させて頂きたいと思います。還暦をすぎると、理解力が落ちてきているので、
理解するまでに時間がかかってしまうので恐縮です。
 
simpleさん、Sortメソッドについてのご説明をありがとうございました。
根品の部分を説明して頂けると、なんとなく、理解も少し、早くなったような気が
致します。
 
 
みなさま、ありがとうございました。
解決とさせて頂きたいと思います。