• ベストアンサー

VBAでグループごとソートする方法がわかりません。

下記のようなソートをVBAで行いたいのですがわかりません。 3行2列ずつ入れ替え、その結果を別シートに作成したいのです。 A    B    C    D    E    F    G    H    I    J    K    L 5    佐藤  6    鈴木 3    高橋  8    磐田 5   中根  5    後藤 da8       da4       da6       da1       da1      da5  ↓(2行目の数を基準に3行2列ごと入れ替え) E    F    A    B    I    J    K    L    C    D    G    H 3    高橋  5    佐藤 5   中根  5    後藤  6    鈴木  8    磐田 da6       da8       da1      da5        da4      da1  ↓(最初の条件を満たしたまま、3行目のdaに続く数を基準に3行2列ごと入れ替え) E    F    I    J    K    L    A    B    C    D    G    H 3    高橋  5    中根 5   後藤  5    佐藤  6    鈴木  8    磐田 da6       da1       da5      da8        da4      da1 最近VBAを勉強し始め、「かんたんプログラミング EXCEL VBA」という書籍を読んだ知識レベルのため、なかなか苦戦しております。お時間ありましたら、考え方のヒントもしくは教えていただけないでしょうか? 以下を貼り付けてカット&ペーストしていただいたらデータを作成しやすいです。 ABCDEFGHIJKL 5佐藤6鈴木3高橋8磐田5中根5後藤 da8da4da6da1da1da5

質問者が選んだベストアンサー

  • ベストアンサー
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.4

こんばんは。 読みきりました。これは、基本的な表の作り方が間違ってしまっているから、これは、マクロ以前の問題だと思います。別に表がきちんと作れていれば、マクロは必要ないと思います。以下は、途中で、並べ替えのできる表が出てきますので、途中で止めてみてもよいと思います。 Sub TestSort()   Dim r As Range   Dim ar1 As Variant   Dim ar2 As Variant   Dim ar3 As Variant   Dim ar4 As Variant   Dim i As Integer   Dim j As Integer   Dim k As Integer   Dim CopyCell As Range 'コピー先      Set r = Range("A1").CurrentRegion   If r.Rows.Count > 3 Then MsgBox "今回のマクロでは完了できません": Exit Sub      '配列のIndexの上限   k = Int(r.Columns.Count / 2) - 1      ReDim ar1(0 To k)   ReDim ar2(0 To k)   ReDim ar3(0 To k)   ReDim ar4(0 To k)      Set CopyCell = r.Cells(6, 1) 'コピー先 A6 から      'データ取得   For i = 1 To r.Columns.Count Step 2     ar1(j) = r.Cells(1, i).Value & "," & r.Cells(1, i + 1).Value     j = j + 1   Next i   j = 0   For i = 1 To r.Columns.Count Step 2     ar2(j) = r.Cells(2, i).Value     j = j + 1   Next i   j = 0   For i = 1 To r.Columns.Count Step 2     ar3(j) = r.Cells(3, i).Value     j = j + 1   Next i   j = 0   For i = 1 To r.Columns.Count Step 2     ar4(j) = r.Cells(2, i + 1).Value     j = j + 1   Next i      '作業セル空間にコピー   With Range("A100").Resize(, k + 1)     .Value = ar1     .Offset(1).Value = ar2     .Offset(2).Value = ar3     .Offset(3).Value = ar4   End With      '並べ替え   Range("A100").CurrentRegion.Sort _   Key1:=Range("A101"), Order1:=xlAscending, _   Key2:=Range("A102"), Order2:=xlAscending, _   Header:=xlGuess, _   OrderCustom:=1, _   MatchCase:=False, _   Orientation:=xlLeftToRight      Set r2 = Range("A100").CurrentRegion '作業セル空間の確保   j = 1   'CopyCellを中心にしてコピーする   For i = 1 To r2.Columns.Count     CopyCell.Cells(1, j).Value = Split(r2.Cells(1, i).Value, ",")(0)     CopyCell.Cells(1, j + 1).Value = Split(r2.Cells(1, i).Value, ",")(1)     j = j + 2   Next i   For i = 1 To r2.Columns.Count     CopyCell.Cells(2, (i - 1) * 2 + 1).Value = r2.Cells(2, (i - 1) + 1).Value   Next i   For i = 1 To r2.Columns.Count     CopyCell.Cells(3, (i - 1) * 2 + 1).Value = r2.Cells(3, (i - 1) + 1).Value   Next i   For i = 1 To r2.Columns.Count     CopyCell.Cells(2, i * 2).Value = r2.Cells(4, (i - 1) + 1).Value   Next i      '作業空間の削除   Range("A100").CurrentRegion.ClearComments   Set CopyCell = Nothing: Set r = Nothing: Set r2 = Nothing End Sub

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (3)

  • Dxak
  • ベストアンサー率34% (510/1465)
回答No.3

Excelのソートを使用しない場合で・・・ > 考え方のヒントもしくは教えていただけないでしょうか? で、自分の手で並べなおす時、1段階2段階と分けて並べなおすでしょうか? 多分しない、条件として、含ませて並べ替えを行ってます。 ・<の場合:無条件で並べ替え ・=の場合:次の条件のda?のところを比較して並べ替え 通常のソートであれば、「<の場合」だけを使用しますが、複合した場合、単純に複合した条件を追記してます 参考VBAは、バブルソートですので、データ数が多い場合、違うソートで組みなおしたほうが良いかもしれません (コードがおかしいかもしれませんが・・・ご自身で見直してみてください^^;) Sub SampleSort() Dim I, J As Long Dim n01, n02, n03, n04, n05 As Variant Const StCol = 1 Const StRow = 10 Const NumCn = 6 With ActiveSheet I = NumCn - 1 Do While I >= 2 J = StCol Do While J <= I n01 = .Cells(StRow, J * 2 - 1).Value n02 = .Cells(StRow, J * 2).Value n03 = .Cells(StRow + 1, J * 2 - 1).Value n04 = .Cells(StRow + 1, J * 2).Value n05 = .Cells(StRow + 2, J * 2 - 1).Value If n03 > .Cells(StRow + 1, (J + 1) * 2 - 1).Value Or _ (n03 = .Cells(StRow + 1, (J + 1) * 2 - 1).Value And _ n05 > .Cells(StRow + 2, (J + 1) * 2 - 1).Value) Then .Cells(StRow, J * 2 - 1).Value = _ .Cells(StRow, (J + 1) * 2 - 1).Value .Cells(StRow, J * 2).Value = _ .Cells(StRow, (J + 1) * 2).Value .Cells(StRow + 1, J * 2 - 1).Value = _ .Cells(StRow + 1, (J + 1) * 2 - 1).Value .Cells(StRow + 1, J * 2).Value = _ .Cells(StRow + 1, (J + 1) * 2).Value .Cells(StRow + 2, J * 2 - 1).Value = _ .Cells(StRow + 2, (J + 1) * 2 - 1).Value .Cells(StRow, (J + 1) * 2 - 1).Value = n01 .Cells(StRow, (J + 1) * 2).Value = n02 .Cells(StRow + 1, (J + 1) * 2 - 1).Value = n03 .Cells(StRow + 1, (J + 1) * 2).Value = n04 .Cells(StRow + 2, (J + 1) * 2 - 1).Value = n05 End If J = J + 1 Loop I = I - 1 Loop End With End Sub

全文を見る
すると、全ての回答が全文表示されます。
  • zap35
  • ベストアンサー率44% (1383/3079)
回答No.2

全くもってEXCEL向きではない表ですね(^^; 並べ替えた結果はどのようにしても良いのですが、元のデータは A列  B列  C列  5  佐藤  da8 のように表を作成するべきです。そうすれば並べ替えも簡単にできます。並べ替えた結果をマクロで追加シートに展開するのは比較的簡単でしょう。(そうでないと配列定数を使用する必要があるのでマクロも難しくなります) マクロの勉強中だそうですからマクロにしますが、以下は追加シートに一旦、上記作業用の表を作成し、値を展開し直すものです。 Sub Macro3() Dim idx As Integer Dim ShtNM As String  ShtNM = ActiveSheet.Name  Worksheets.Add  With Sheets(ShtNM) '一旦作業表を作成する   For idx = 1 To .Range("IV1").End(xlToLeft).Column Step 2    If .Cells(1, idx) = "" Then     Exit For    Else     ActiveSheet.Cells(4 + Int(idx / 2), "A").Value = .Cells(1, idx)     ActiveSheet.Cells(4 + Int(idx / 2), "B").Value = .Cells(1, idx).Offset(0, 1).Value     ActiveSheet.Cells(4 + Int(idx / 2), "C").Value = .Cells(1, idx).Offset(1, 0).Value    End If   Next idx  End With  With ActiveSheet '作業表を並べ替えてから表示形式に展開   .Cells(4, "A").CurrentRegion.Sort Key1:=Range("A4"), Order1:=xlAscending    For idx = 4 To .Range("A65536").End(xlUp).Row    .Cells(1, (idx - 4) * 2 + 1) = .Cells(idx, "A").Value    .Cells(1, (idx - 4) * 2 + 1).Offset(0, 1) = .Cells(idx, "B").Value    .Cells(1, (idx - 4) * 2 + 1).Offset(1, 0) = .Cells(idx, "C").Value   Next idx   .Cells(4, "A").CurrentRegion.ClearContents   .Cells(1, "A").Select  End With End Sub

全文を見る
すると、全ての回答が全文表示されます。
  • driverII
  • ベストアンサー率27% (248/913)
回答No.1

こういう場合は、 1.3行2列毎にブロック番号を仮につけます。 1 2 3 4 5 6 2.そして2行目の数・daに続く数でソートします。 3 5 6 1 2 4 3.別の場所に、ブロックのデータをコピーして、最後に元の位置に貼り付けます。 ソートの方法については、お好きなものをネットで検索してください。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • EXCEL2000VBAの記述について

    e列~j列の5行目に 下記の項目が入っています。   e列 f列 g列 h列 i列 j列 5行目 4月 5月 6月 7月 8月 9月 別シートのE列の5行目に入っているデータと、上記の列(e列~j列)の5行目に入っているデータが 同じの場合は、別シートのE列の6行目から38行目に入っているデータをコピーして、上記の 同じ項目の場所の6行目から38行目にデータを貼り付けたい場合 VBAで記述の仕方を教えてください。

  • excelデータの切り貼りマクロ

    excelマクロの初心者です。 データの切り貼りをするマクロについて教えてください。 以下のような担当者と会社名の入った縦に大きなデータを 担当 社名 佐藤 A社 佐藤 B社 佐藤 C社 田中 D社 田中 E社 田中 F社 鈴木 G社 鈴木 H社 鈴木 I社 高橋 J社 高橋 K社 高橋 L社 最終的に 佐藤 田中 鈴木 高橋 A社 D社 G社 J社 B社 E社 H社 K社 C社 F社 I社 L社 このように一番上に担当者、下に該当する社名を羅列されるように切り貼りをしたいと思っています。 ファイルがいくつもあり、また行数はファイルごとに異なり一定ではありません。 マクロでどのように書いたらよいかご教授頂けないでしょうか。 よろしくお願いいたします<(_ _)>

  • VBA

    1 a;b;c;d; 2 e;f;g;h; 3 i;j;k;l; をVBAで   1 a;   2 e;   3 i;   1 b;   2 f;    3 j;   1 c;   2 g;   3 k;   1 d;   2 h;   3 l; としたいのですが、どうしたらいいですか?

  • エクセルVBA/抽出・貼付け

    下記を行いたいのですが、どのようなコードになるのでしょうか? シート001(入力用) (1)A1~A50、B1~B50、C1~C50、D1~D50  に数値、E1~E50に文字列 (2)F1~F50、G1~G50、H1~H50、I1~I50  に数値、J1~J50に文字列 ※空白行混在 シート002(計算用) シート001に作ったコマンドボタン:クリックにより、 シート002を表示させ、A1~E100に、 シート(1)のA1~E50とF1~J50の空白行以外を連続して 反映させたい。並べ替え用など別シートを用いずに、 VBAコード内で処理したい。

  • VBAで範囲を有するセルの記載位置を入れ替える

    お世話になります。 あるデータを扱うため、sheet_1に以下のような表を作成し管理を行っております。 sheetは複数存在するので、敢えてsheet_1とします。 (sheet_1)      B列ーC列ーD列ーF列ーG列ーH列ーI列ーJ列ーK列ーL列・・・  3行  A   A   A   A   B   B   B   B   C   C  4行  A   A   A   A   B   B   B   B   C   C  5行  A   A   A   A   B   B   B   B   C   C  6行  A   A   A   A   B   B   B   B   C   C  7行  F   F   F   F   G   G   G   G   H   H  8行  F   F   F   F   G   G   G   G   H   H  9行  F   F   F   F   G   G   G   G   H   H 10行  F   F   F   F   G   G   G   G   H   H 11行  K   K   K   K   L    L   L   L   M   M 12行 以下、上記のように続く 4列毎×4行毎の16セル分の範囲を1情報として扱っているのですが、VBAを利用して記入された横方向の情報を下部行(例えば150行目)で縦に置き換える方法をご教授いただきたく投稿致しました。 変換元の対象範囲はB3:BM126です。 (sheet_1)       B列ーC列ーD列ーF列ーG列ーH列ーI列ーJ列ーK列ーL列・・・ 150行  A   A   A   A   F   F   F   F   K   K 151行  A   A   A   A   F   F   F   F   K   K 152行  A   A   A   A   F   F   F   F   K   K 153行  A   A   A   A   F   F   F   F   K   K 154行  B   B   B   B   G   G   G   G   L   L 155行  B   B   B   B   G   G   G   G   L   L 156行  B   B   B   B   G   G   G   G   L   L 157行  B   B   B   B   G   G   G   G   L   L 158行  C   C   C   C   H   H   H   H   M   M 159行 以下、上記のように続く 同一sheet内ではなく、新たにsheetを作成して同じ結果を求める方法でも構いませんので、恐れ入りますがご教授宜しくお願い致します。

  • VBAのマクロで、複数行を1行に集計

    お世話になります。VBA初心者です。 下記のような表があった場合、請求書番号が同じものをVBAで1行に集計するにはどうしたらよろしいのでしょうか? 請求書No.|顧客名|摘要|金額 111111  |鈴木 | A |100 111111 |鈴木 | S |160 222222 |佐藤 | F |500 555555 |山田 | A |150 555555 |山田 | D |200 888888 |鈴木 | S |160  ↓下記のように集計 請求書No.|顧客名|摘要|金額 111111 |鈴木 | A |260 222222 |佐藤 | F |500 555555 |山田 | A |350 888888 |鈴木 | S |160 摘要は各請求書番号の最初の行を使います。重複は2行とは限りません。また、最終的に何枚の請求書があるのかも計算させたいのです。ただしこれはどこかに関数"=counta()"を使えばVBAでなくても出来るのですが。 よろしくお願いいたします。

  • VBAのプログラムでうまく動かなくて困っています。

    VBA初心者です。 エクセルのVBAのプログラムでうまく動かなくて困っています。教えていただける方がいらしたら、ぜひ教えて下さい!よろしくお願いします。エクセルの内容は以下のとおりです。 (内容) セル    E H J L N P R・・・ 8行目100 200 50 40 30 80 9行目130 350 10 50 60 120 110 ・ ・ (1)列Hの値が列Eの値より大きい場合その下に行を追加します。 (2)セルJ+セルL+セルN+・・をしてセルEの値を超えたセル以降の値を追加した行のセルJ列から順にコピペする処理です。 上のセルの1行目の内容でいいますと、 (1)列Hの値「200」が列Eの値「100」より大きいのでその下に行追加 (2)セルJ、L、N「50」+「40」+「30」でセルEの値「100」より大きいので、追加した行のセルJ列にセルN、Pの値をコピペするです。 以下が私が書いたプログラムです。 Sub test() Dim x As Integer Dim s As Integer Dim t As Integer x = Range("B8").End(xlDown).Row r = Range("J8").End(xlToRight).Column '8行目から最終行までループ For i = x To 9 Step -1 If Cells(i, 5) < Cells(i, 8) Then ☆【For r = y To 11 Step -2 Cells(s, t).Value = Cells(i, r) + Cells(i, r + 2) If Cells(i, 5).Value < Cells(s, t).Value            Then Exit For Next】 Rows(i + 1).Insert Shift:=xlDown '超えたセルをコピーして、1行下の"J列以降"に代入 ★ x = x + 1 End If Next i End Sub 上記プログラムで★の部分がうまく書けません。☆の部分も間違っているような気がします。よろしくお願いします。

  • VBAの記述方法について

    初めまして、VBAについて質問をさせてください。 「テスト資料」と「Sheet1」がそれぞれ別ブックで氏名と施設名の情報をもっています。 「テスト資料」では、氏名及び施設名が行ごとに並んでおり、氏名はC列、施設名はL列から最終列(そのときによって変動)にあります。「Sheet1」では、氏名はG列、施設名はE列にあります。 「テスト資料」の氏名及び施設名がSheet1の氏名及び施設名に一致する行を 探しだし、値がどちらも同じなら、「テスト資料」の該当する行のA列からD列と、 一致した施設名のセルを22番の色で塗りつぶす (上のVBAでは記述方法が分からなかったため、ひとまずA列からD列を指定しています) という処理がしたいのですが、下記を実行しても何も起こりません。 どのようにすれば処理ができるのか、どなたかご助力お願いいたします。 Dim i As Integer, j As Integer For i = 3 To Sheets("PQ_Proc_H_EUC_E009_選考会資料").Cells(Rows.Count, 1).End(xlUp).Row For j = 12 To Sheets("PQ_Proc_H_EUC_E009_選考会資料").Cells(Columns.Count, 1).End(xlToLeft).Column If Sheets("PQ_Proc_H_EUC_E009_選考会資料").Cells("i,C").Value = Sheets("Sheet1").Range("G:G").Value And Sheets("PQ_Proc_H_EUC_E009_選考会資料").Cells("i,j").Value = Sheets("Sheet1").Range("E:E").Value Then Sheets("PQ_Proc_H_EUC_E009_選考会資料").Range("A:D").Interior.ColorIndex = 22 End If Next j Next i

  • EXCEL VBA 条件による空白挿入

    EXCEL2003を使っています。 以下のように列FGHが空白の行については列ABCを空白を挿入したいのですが数万行あり処理をVBAで自動化したいです。どなたかお力をお貸し下さい。お願いします。 A B C D E F G H 1 1 2 3 4 5 6 7 8 2 1 2 3 4 5 _ _ _ 3 1 2 3 4 5 6 7 8 4 1 2 3 4 5 _ _ _ 5 1 2 3 4 5 6 7 8 ↓ A B C D E F G H 1 1 2 3 4 5 6 7 8 2 _ _ _ 1 2 3 4 5 3 1 2 3 4 5 6 7 8 4 _ _ _ 1 2 3 4 5 5 1 2 3 4 5 6 7 8

  • VBAの文字検索、コピーについて質問です。

    VBAの文字検索、コピーについて質問です。 いつもお世話になっています。 VBAにて別のブックのある一つの文字を検索し、貼り付けをする作業を行いたいのですがなにか良い方法はないでしょうか? 注意点 1)ブック1が入力シート、ブック2が貼り付けシートとします。 2)ブック1はブック2に情報を張り付け終えたらその列を削除します。 3)検索値は数字です。ブック1のB1が必ず検索したい番号になります。 4)ブック2の1行目からブック1のB1の数字を探し出して張り付けたいです。 5)貼り付け時、値のみの貼り付けを行いたいです。 例: ブック1  A    B  C   D   E  F   G   H  I  J  K 1    21  22  23  24  25  26  27  28  29 30 2山田  1 3田中  3 4佐藤  5 5鈴木  1 ブック2  A  ・・・ T   U   V  W  X   Y   Z   AA  AB 1  ・・・・19  20  21  22  23  24   25  26  27 ・・・・・ 2山田    2  1 3田中    3  2 4佐藤     5  5 5鈴木    1  0 削除以降の作業は自分で考えられたのですが、この作業のコードはうまく出来ません。 コードすらどうしたらいいか考えています。 どうか宜しくお願い致します。

専門家に質問してみよう