重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

表を時間(C1)の降順にて並び替えたいです
表は、つど、サイズが違います

開始行の項目はA1からH1やI1やK1などに変化します
行の数も、その都度、少なかったり多かったりします

この場合の、表全体を範囲する場合にはどんな方法あがありますか?
教えて下さい

なお、A1の以下、コードでも、ソートされている感じはあります

【条件】
A列とC列と開始行に歯抜けデータはないです

【コード】
Sub test()
Range("A1").Sort Key1:=Range("c1"), order1:=xlDescending, Header:=xlYes

End Sub

A 回答 (5件)

Range("A1").CurrentRegion

    • good
    • 1

コメント拝見しました。


私の読み取り方が勘違いしてたみたいですね。

表の範囲において、
・A列は歯抜けなし
・1行目は項目行で最後列まで歯抜けなし
ということであれば、これでもいいのかな。

Sub SortByOffsetColumnFromA1()
  Dim baseCell As Range    ' 基準セル(A1)
  Dim tblRange As Range    ' 表の範囲(CurrentRegionで取得)
  Dim keyColumn As Range    ' ソートのキーとなる列(C列)
  Dim keyColIndex As Long   ' 表内での列番号(相対)
  
  Set baseCell = Range("A1")       ' A1セルを基準にする
  Set tblRange = baseCell.CurrentRegion ' A1を含む表の範囲を取得

  keyColIndex = 3             ' 表内の3列目(C列)をソートキーに設定
  Set keyColumn = tblRange.Columns(keyColIndex)

  ' ソート実行:降順、ヘッダーあり(1行目は見出しとして扱う)
  tblRange.Sort Key1:=keyColumn, Order1:=xlDescending, Header:=xlYes
End Sub


先の回答ではソート昇順にしてました。すみません。
    • good
    • 1

こういう問題は得意(システム屋だった)なのですが、歳を取って今期が無いのでAIに聞きました。

 以下はGoogleGeminiの回答です。

承知いたしました。表のサイズが変動し、開始行の項目も変わる可能性があるのですね。A列とC列、そして開始行に歯抜けデータがないという条件を考慮して、表全体を自動的に範囲指定し、C列を降順に並べ替える方法をいくつかご提案します。

方法1:CurrentRegionプロパティを利用する
CurrentRegionプロパティは、選択したセルを含む、空白行と空白列で囲まれた領域全体を取得します。このプロパティを利用すると、表のサイズが変動しても自動的に範囲を認識できます。

Sub SortByCTimeDescending()
Dim targetRange As Range

' A1セルを基準にCurrentRegionで表全体を取得
Set targetRange = Range("A1").CurrentRegion

' C列を降順にソート
targetRange.Sort Key1:=targetRange.Columns("C"), Order1:=xlDescending, Header:=xlYes
End Sub

このコードでは、まず Range("A1").CurrentRegion でA1セルを含む表全体を targetRange に設定しています。その後、targetRange.Sort メソッドでソートを実行しています。Key1 には targetRange.Columns("C") を指定することで、表のC列全体を参照し、Header:=xlYes は1行目をヘッダーとして扱います。

方法2:最終行と最終列から範囲を特定する
Cells.SpecialCells(xlLastCell) を利用してシートの最終セルを特定し、そこから表の左上隅であるA1セルを基準に範囲を取得する方法です。

Sub SortByCTimeDescending_LastCell()
Dim lastRow As Long
Dim lastColumn As Long
Dim targetRange As Range

' シートの最終セルを取得
On Error Resume Next ' データがない場合にエラーを回避
lastRow = Cells.SpecialCells(xlLastCell).Row
lastColumn = Cells.SpecialCells(xlLastCell).Column
On Error GoTo 0 ' エラー処理を元に戻す

' A1セルから最終行・最終列までの範囲を設定
Set targetRange = Range(Cells(1, 1), Cells(lastRow, lastColumn))

' C列を降順にソート
targetRange.Sort Key1:=targetRange.Columns("C"), Order1:=xlDescending, Header:=xlYes
End Sub

この方法では、Cells.SpecialCells(xlLastCell) でシートで使用されている最後のセルを取得し、その行番号と列番号を lastRow と lastColumn に格納します。その後、Range(Cells(1, 1), Cells(lastRow, lastColumn)) でA1セルから最終セルまでの範囲を targetRange に設定しています。

方法3:A列の最終行から範囲を特定する
A列には必ずデータが存在するという条件を利用して、A列の最終行を特定し、そこから表の範囲を推測する方法です。

Sub SortByCTimeDescending_LastRowA()
Dim lastRowA As Long
Dim targetRange As Range

' A列の最終行を取得
lastRowA = Cells(Rows.Count, "A").End(xlUp).Row

' A1セルからA列の最終行までの範囲を基準にCurrentRegionを取得
Set targetRange = Range("A1:A" & lastRowA).CurrentRegion

' C列を降順にソート
targetRange.Sort Key1:=targetRange.Columns("C"), Order1:=xlDescending, Header:=xlYes
End Sub

このコードでは、Cells(Rows.Count, "A").End(xlUp).Row でA列の最終行を取得し、lastRowA に格納します。その後、Range("A1:A" & lastRowA).CurrentRegion でA1セルからA列の最終行までの範囲を含む CurrentRegion を取得し、targetRange に設定しています。


どの方法が良いか
・方法1 (CurrentRegion):表が連続したデータで構成されている場合に最も簡潔で有効です。表の周囲に完全に空白の行と列がある場合に適しています。
・方法2 (最終セル):シート全体で使用されている最後のセルを基準とするため、表以外にもデータが存在する場合、意図しない範囲まで選択される可能性があります。
・方法3 (A列の最終行):A列を基準に表の範囲を推測するため、表がA列から始まっており、途中に空白行がない場合に有効です。

通常は 方法1 (CurrentRegion) が最も柔軟で使いやすいかと思います。もし、表の周囲に空白行や空白列がない場合や、他のデータと隣接している場合は、方法3 (A列の最終行) を試してみるのが良いかもしれません。

ご自身のデータ構造に合わせて、いずれかの方法をお試しください。もし、うまくいかない場合や、さらに詳細な条件があれば、お気軽にお知らせください。
    • good
    • 0

> 開始行の項目はA1からH1やI1やK1などに変化します



表の左上にあたるセルがA1だったり、H1になったりするということですか?
『開始"列"が変化する』ということ

そして、ソートの基準となるのは、「開始列+2」の列となるのでしょうか?


とりあえず、のコード。
選択されているセルを基準としてCurrentRegionで表の範囲を取得し、
選択セルから2つ右の列を基準としてソートします。


Sub SortByOffsetColumn()
  Dim baseCell As Range    ' アクティブなセル
  Dim tblRange As Range    ' 表全体の範囲(currentRegionで取得)
  Dim keyColumn As Range    ' ソートの基準となる列
  Dim colOffset As Long    ' アクティブセルからの列オフセット(+2列)

  On Error GoTo ErrorHandler  ' エラーが出たらエラーメッセージを表示

  Set baseCell = activeCell         ' 現在選択中のセルを取得
  Set tblRange = baseCell.CurrentRegion   ' 表の範囲(周囲の空白で囲まれた範囲)を取得

  colOffset = baseCell.Column - tblRange.Columns(1).Column + 3 ' アクティブセルから+2列目の列番号を計算

  ' 指定した列が表の範囲外であれば中止
  If colOffset > tblRange.Columns.Count Then
    MsgBox "右に2列進んだ列が表の範囲にありません。", vbExclamation
    Exit Sub
  End If

  Set keyColumn = tblRange.Columns(colOffset) ' ソートキーとなる列を取得

  ' ソート実行:ヘッダーあり、昇順で行単位に並び替え
  tblRange.Sort Key1:=keyColumn, Order1:=xlAscending, Header:=xlYes

  Exit Sub

ErrorHandler:
  MsgBox "エラーが発生しました:" & vbCrLf & Err.Description, vbCritical
End Sub


コメントはAIに「初心者でもわかるように入れて」と指示して入れてます。
    • good
    • 0
この回答へのお礼

お返事ありがとうございます
すいません。
範囲はA1からH1、A1からI1、AIからK1という意味です
降順の列はC1のみです

> 開始行の項目はA1からH1やI1やK1などに変化します

お礼日時:2025/04/20 17:31

こんにちは



B列にもデータがあるのなら、CurrentRegionで取得するのが簡単かも知れません。(データ範囲の識別条件にもよりますが・・)
 Range("A1").CurrentRegion

データ群の範囲を決める規則が不明ですが、普通に、最終行・最終列を求める方法の応用でも可能でしょう。(こちらの方が正確な場合が多いと思われます)
    • good
    • 1
この回答へのお礼

お返事ありがとうございます

範囲はA1からH1、A1からI1、AIからK1という意味です
降順の列はC1のみです

Range("A1").CurrentRegion ですね。ありがとうございます

お礼日時:2025/04/20 17:31

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A