『データを仕分けたい』(加工職人) 製品の加工表を元請けからもらったcsvをもとに 作ったのですが 今一つ使い勝手が悪いのです。 皆さんのお力で何とかなりませんか?   こんな表を    品番 サイズ  枚数  加工寸法  注文番号    b02  200 1000   10      0   a1011  c05 1000 300 5 0 b3022 a01  100 1200   2   w1=250 b1022 a01 100 1200 1 ※ w1=100 a1023 a01 100 1200 1 ※ w1=250 a1055   a01 100 1200 3    w1=300  a1057 こんな感じにしたいのです 品番 サイズ  枚数  加工寸法  注文番号    b02  200 1000   10      0   a1011  c05 1000 300 5 0 b3022 a01  100 1200   2   w1=250 b1022 a01 100 1200 1 ※ w1=250 a1055 a01 100 1200 1 ※ w1=100 a1023 a01 100 1200 3  w1=300  a1057   この表はまず、     枚数 10枚単位、5枚単位、の順になっていて     次にサイズの大きい順になってます     他の品番の枚数、サイズの順番 及び他の品番との     順番は変えずに     同じ品番の中でのみ加工寸法をまとめたいのです     (出来れば大きい順で)     注文番号は紐づけされていたら十分です。     vbaはそんなに詳しくわかりませんが     何卒宜しくお願いいたします。 < 使用 Excel:Excel2021、使用 OS:Windows11 > ---- このようにならなくていいんですか? |[A] |[B] |[C] |[D] |[E] [1]|品番|サイズ |枚数|加工寸法|注文番号 [2]|b02 |200 1000| 10| 0|a1011 [3]|c05 |1000 300| 5| 0|b3022 [4]|a01 |100 1200| 3|w1=300 |a1057 ←a01の中で加工寸法が最大 [5]|a01 |100 1200| 2|w1=250 |b1022 [6]|a01 |100 1200| 1|w1=250 |a1055 [7]|a01 |100 1200| 1|w1=100 |a1023 もう少し明確な条件・状況を提示されると、多くの回答が寄せられるかもしれません。 以下、推測での回答です。 並べ替え機能を使うかして、提示の元表の順に既に並んでいるということですか? 手間でなければ、品番a01の範囲(上記表ならA4:E7)を選択して、 並べ替え→「先頭行をデータの見出し・・・」のチェック外す→ 最優先されるキー→列D→並べ替えのキー→セルの値→順序→降順→OKボタン とすれば、そのようになります。 上記の条件下限定のVBAを参考出品です。 条件変更には応じかねますのでご了承下さい。 Sub test() Dim i As Long Dim tmp As Range, rng As Range Set rng = Cells(2, "A").Resize(, 5) For i = 3 To Cells(Rows.Count, "A").End(xlUp).Row + 1 Set tmp = Cells(i, "A").Resize(, 5) If Cells(i, "A") <> Cells(i - 1, "A") Then rng.Sort Range("D1"), xlDescending, Header:=xlNo Set rng = tmp Else Set rng = Union(rng, tmp) End If Next End Sub (羊カウント) 2024/04/29(月) 14:20:44 ---- 本当に申し訳ございません わたくしの説明不足です。  (並べ替え機能を使うかして、提示の元表の順に既に並んでいるということですか?)    ➡その通りですが、  しかし表の項目数は都度変わりますので、その都度10枚や5枚の単位の 品番は増えたり減ったりしますし、また、加工しないといけない製品の品番も一種類ではありません、 何種類も増えたり減ったりしますので、その種類ごとに順番にならんでほしいのです しかし、私が提示したデータ数だけでは全くこの表の通りです。 ありがとうございます。 (加工職人) 2024/04/29(月) 14:52:32 ---- >その都度10枚や5枚の単位の品番は増えたり減ったりします この話に単位が10枚とか5枚とかって何か関係あるんですか? 同一品番内の加工サイズ順の並替えの話なら、無関係だろうなぁと思うのですが・・ (半平太) 2024/04/29(月) 16:47:21 ---- またまた、説明不足です、すいません 表の順番として、上から10枚単位、その下に、5枚単位、その下に、1枚とか、2枚とかの 単位をまとめたかったのです 何度も申し訳ございません。 (加工職人) 2024/04/29(月) 17:48:45 ---- フーム、ちょっと分からないです。 こちらが逐一聞く前に、並べ替えルールの全貌を明示してください。 (半平太) 2024/04/29(月) 18:40:29 ---- ルールの全貌、といわれましても うまく言葉にならないので 表の項目を増やしてみます   品番 サイズ  枚数  加工寸法  注文番号    d01 200 1500 10 0 a3311    b02  200 1000   10      0   a1011  c05 1000 300 5 0 b3022 a01  100 1200   2   w1=250 b1022 a01 100 1200 1 w1=100 a1023 a01 100 1200 1 w1=250 a1055   a01 100 1200 3    w1=300  a1057 f03 200 1000 1 w1=150 c0123 f03 200 1000 2 w1=200 c0234 こんな感じにしたいのです 品番 サイズ  枚数  加工寸法  注文番号    d01 200 1500 10 0 a3311 b02  200 1000   10      0   a1011  c05 1000 300 5 0 b3022 a01 100 1200 3  w1=300  a1057← a01  100 1200   2   w1=250 b1022← a01の品番のくくりで a01 100 1200 1 w1=250 a1055←  加工寸法順  a01 100 1200 1 w1=100 a1023← f03 200 1000 2  w1=200  c0234☚ f03の品番のくくりで f03 200 1000 1 w1=150 c0123☚  加工寸法順   いろんな品番の製品があるけど大きいサイズの順番でなおかつ10枚単位の   ものから加工して、次に大きいサイズの順番で並んだ5枚単位、最後に大きい順に   並んだ1枚単位で扱う製品をかこうすんぽうの大きい順に並び替えて加工したいので   すが、ややこしくてすいません。   でもややこしいからこそVBAで何とかならないかと希望を持ってます   何卒宜しくお願い致します。 (加工職人) 2024/04/29(月) 20:19:04 ---- 新しく提示された元表でも、私の拙いコードで希望の結果になると思いますが。 むしろ、その元表の並べ替えキーを教えてもらいたいです。 追記 枚数が降順ですね。 ソートの部分は以下に書き換えてください。 rng.Sort key1:=Range("D1"), order1:=xlDescending, _ key2:=Range("C1"), order2:=xlDescending, Header:=xlNo (羊カウント) 2024/04/29(月) 20:40:59 ---- ありがとうございます 羊カウント様  品番のくくりの中で加工寸法順に並びかえたいのです  現場で作業しているのは、同じような加工で、数が多いものは早く済ませて一枚とか3枚とか  少量のものは加工寸法をまとめて作業をするようなイメージです  ほんとにすいませんうまく伝えれなくて。  元表は3段階で並び替えています  1段階目は(10枚単位、5枚単位、)と(1枚、2枚といった端数)  2段階目は(10枚単位、5枚単位、)を サイズ 200 1500の大きさなら  1500の方の数字の降順、  3段階目は(1枚、2枚といった端数)を2段階目と同じルールで  並び替えています   (加工職人) 2024/04/29(月) 21:54:10 ---- セル番地を書かないから、、、 もうpcから離れてしまったので、とりあえず、 resize(,6) D1→E1 C1→D1 に変更して動作させてみて下さい こちらはあなたの画面を見ることができないので、 多少はそちらで現場合わせして下さい (羊カウント) 2024/04/29(月) 22:04:05 ---- 終始すれ違いだった感じですが、 私としては、元表のソート自体は、そちらで済ましてあることを前提に話をしていました。 新しい元表を提示された時も、すでにソート済だったので。 ところがどうも、加工職人さんとしてはそうではなく、 元表のソートも対応するコードが欲しい、ということだったんでしょうか。 以下のレイアウトの場合のコードです。 一応「こんな感じにしたいのです」の様になります。 <ソート前> |[A] |[B] |[C] |[D] |[E] |[F] [1] |品番|W |H |枚数|加工寸法|注文番号 [2] |c05 |1000| 300| 5| 0|b3022 [3] |a01 | 100|1200| 1|w1=100 |a1023 [4] |b02 | 200|1000| 10| 0|a1011 [5] |f03 | 200|1000| 1|w1=150 |c0123 [6] |a01 | 100|1200| 1|w1=250 |a1055 [7] |a01 | 100|1200| 2|w1=250 |b1022 [8] |d01 | 200|1500| 10| 0|a3311 [9] |f03 | 200|1000| 2|w1=200 |c0234 [10]|a01 | 100|1200| 3|w1=300 |a1057 Sub Macro1() Dim tbl As Range Dim rng(2) As Range, tmp As Range Dim r(2) As Long Set tbl = Cells(1).CurrentRegion tbl.Sort Cells(4), xlDescending, Header:=xlYes Set rng(0) = Columns(4).Find(10, , xlValues, xlWhole, , xlPrevious) Set rng(1) = Columns(4).Find(5, , xlValues, xlWhole, , xlPrevious) Set rng(2) = Columns(4).Cells(tbl.Rows.Count) r(0) = rng(0).Row: r(1) = rng(1).Row: r(2) = rng(2).Row With tbl Set tmp = Range(.Rows(2), .Rows(r(0))) Call test2(tmp) Set tmp = Range(.Rows(r(0) + 1), .Rows(r(1))) Call test2(tmp) Set tmp = Range(.Rows(r(1) + 1), Rows(r(2))) Call test2(tmp) End With Call test End Sub Sub test() Dim i As Long Dim tmp As Range, rng As Range Set rng = Cells(2, "A").Resize(, 6) For i = 3 To Cells(Rows.Count, "A").End(xlUp).Row + 1 Set tmp = Cells(i, "A").Resize(, 6) If Cells(i, "A") <> Cells(i - 1, "A") Then rng.Sort key1:=Range("E1"), order1:=xlDescending, _ key2:=Range("D1"), order2:=xlDescending, Header:=xlNo Set rng = tmp Else Set rng = Union(rng, tmp) End If Next End Sub Sub test2(tmp As Range) tmp.Sort key1:=Cells(3), order1:=xlDescending, _ key2:=Cells(1), order2:=xlAscending, Header:=xlNo End Sub 正確なレイアウトや並べ替えの条件を提示してもらわないと、 お望みの回答は出せませんし、加えて申し上げるなら、 回答者はあなたの勤務先のルールは全くわからないので、 10枚単位、5枚単位というのも、 じゃあ、20枚のグループはあるのかないのか等、 あなたの会社では常識なことも、 説明されなければ分からないのです。 私にとって、質疑応答しながら回答するのは好ましくないので、 今回の件については、私はここまでとさせてください。 (羊カウント) 2024/04/30(火) 23:19:56 ---- # 仕様の確定作業が一番難しいところだと思います。 # 問題解決の大方はそこにあると言ってよいと思います。お疲れさまでした。 こんな考え方ではいかがでしょうか。 G列に 作業列として「枚数2」項目を追加します。(マクロで自動実行) ・5枚以上はそのままとし、 ・5枚未満は同列と見做すため、一律に 1 を設定します。 こうすれば、あとは標準的なソートで対応できそうです。 第1優先キー : G列(枚数2) の降順 第2優先キー : A列(品番) の昇順 第3優先キー : C列(Height) の降順 第4優先キー : E列(加工寸法)の降順 第5優先キー : D列(枚数) の降順 この仕様で良いのか確認してください。 仮にこれでよいとした場合、マクロで対応するなら下記のようになります。 対象シートをアクティブにした状態で、下記のマクロtestを実行して下さい。 Sub test() Dim rng As Range Dim lastRow As Long lastRow = Cells(Rows.Count, "A").End(xlUp).Row 'G列に作業列を追加(5以上は枚数そのまま、5未満は同列とみなし 1とする) [G1] = "枚数2" [G2].Resize(lastRow - 1, 1).Formula = "=IF(D2>=5,D2,1)" Set rng = [A1].CurrentRegion With ActiveSheet.Sort.SortFields .Clear .Add2 Key:=[G2], Order:=xlDescending '枚数2 の降順 .Add2 Key:=[A2], Order:=xlAscending '品番 の昇順 .Add2 Key:=[C2], Order:=xlDescending 'Height の降順 .Add2 Key:=[E2], Order:=xlDescending '加工寸法の降順 .Add2 Key:=[D2], Order:=xlDescending '枚数 の降順 End With With ActiveSheet.Sort .SetRange rng .Header = xlYes .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End With '作業列消去 Columns("G").ClearContents End Sub もし、上記の考え方でまずければ、そちらで修正して下さい。 また、手作業でも問題なく実行できると思います。 (xyz) 2024/05/01(水) 06:02:07 ---- お返事遅くなり申し訳ございません。  羊カウント様 、未熟な私の為に、色々とアドバイスを頂き本当にありがとうございました。  (xyz)様にアドバイス頂いたように仕様の確定作業をもっとわかりやすくするべきでした  (あなたの会社では常識なことも、 説明されなければ分からないのです。)   その通りと思います。   もう一度整理して考えてみます     皆様、本当にありがとうございました。 (加工職人) 2024/05/02(木) 20:42:40