web-dev-qa-db-ja.com

テーブルを破壊せずにクリアなテーブルの内容を選択する方法は?

ここにいる人々の助けを使用して、Excel 2010にvba関数を作成しました。この関数は、テーブル/フォームの内容をコピーしてソートし、適切なテーブルに送信します。

この関数を実行した後、元のテーブルをクリアする必要があります。 ACellがテーブルの最初のセルとして定義されていると仮定すると、次のコードでこれを実現できます。 ACell.ListObject.Range.ClearContentsは正常に動作しますが、唯一の問題はテーブルとデータ値を削除することです。

これを回避する方法はありますか?データを入力するたびにテーブルを設定する必要はありません。

14
SpeedCrazy

どうですか:

ACell.ListObject.DataBodyRange.Rows.Delete

これにより、テーブル構造と見出しは保持されますが、すべてのデータと行は消去されます。

編集:私は私の答えの一部を 前の投稿 から変更するだけです。これにより、1行だけが残ります。

With loSource
   .Range.AutoFilter
   .DataBodyRange.Offset(1).Resize(.DataBodyRange.Rows.Count - 1, .DataBodyRange.Columns.Count).Rows.Delete
   .DataBodyRange.Rows(1).Specialcells(xlCellTypeConstants).ClearContents
End With

すべての行を数式などでそのまま残したい場合は、次のようにします。

With loSource
   .Range.AutoFilter
   .DataBodyRange.Specialcells(xlCellTypeConstants).ClearContents
End With

これは、式をクリアしないことを除いて、@ Readifyが提案したものに近いものです。

31
Doug Glancy

データ(ヘッダーを含むテーブル全体ではなく)をクリアしてみてください:

ACell.ListObject.DataBodyRange.ClearContents
7
Reafidy

行の削除を回避するために、Doug Glancyのソリューションを作り直しました。これにより、式で#Refの問題が発生する可能性があります。

Sub ListReset(lst As ListObject)
'clears a listObject while leaving row 1 empty, with formulae
    With lst
        If .ShowAutoFilter Then .AutoFilter.ShowAllData
        On Error Resume Next
        With .DataBodyRange
            .Offset(1).Rows.Clear
            .Rows(1).SpecialCells(xlCellTypeConstants).ClearContents
        End With
        On Error GoTo 0
        .Resize .Range.Rows("1:2")
    End With
End Sub
3
Patrick Honorez

このコードを使用してデータを削除しますが、一番上の行には式を残します。また、一番上の行を除くすべての行を削除し、ページを一番上までスクロールします。

Sub CleanTheTable()
    Application.ScreenUpdating = False
    Sheets("Data").Select
    ActiveSheet.ListObjects("TestTable").HeaderRowRange.Select
    'Remove the filters if one exists.
    If ActiveSheet.FilterMode Then
    Selection.AutoFilter
    End If
    'Clear all lines but the first one in the table leaving formulas for the next go round.
    With Worksheets("Data").ListObjects("TestTable")
    .Range.AutoFilter
    On Error Resume Next
    .DataBodyRange.Offset(1).Resize(.DataBodyRange.Rows.Count - 1, .DataBodyRange.Columns.Count).Rows.Delete
    .DataBodyRange.Rows(1).SpecialCells(xlCellTypeConstants).ClearContents
    ActiveWindow.SmallScroll Down:=-10000

    End With
Application.ScreenUpdating = True
End Sub
1
Brewer

これらのソリューションのほとんどが対処していないという条件があります。 Patrick Honorezのソリューションを修正して処理しました。元の関数が予期していたより多くのデータを時々クリアするときに髪を引っ張っていたので、これを共有しなければならないと感じました。

この状況は、テーブルに1列しかなく.SpecialCells(xlCellTypeConstants).ClearContentsが一番上の行の内容を消去しようとしたときに発生します。この状況では、1つのセル(列が1つしかないテーブルの一番上の行)のみが選択され、SpecialCellsコマンドは選択範囲ではなくシート全体に適用されます。私に起こっていたのは、テーブルの外にあったシート上の他のセルもクリアされていたということでした。

いくつか掘り下げて、マシューギンドンからのアドバイスを見つけました。 Range SpecialCells ClearContentsはシート全体をクリアします

Range({any single cell})。SpecialCells({whatever})はシート全体で機能するようです。

Range({複数のセル})。SpecialCells({whatever})は、指定されたセルで機能するようです。

リスト/テーブルに1列(行1)しかない場合、このリビジョンはセルに数式があるかどうかを確認し、ない場合はその1つのセルの内容のみをクリアします。

Public Sub ClearList(lst As ListObject)
'Clears a listObject while leaving 1 empty row + formula
' https://stackoverflow.com/a/53856079/1898524
'
'With special help from this post to handle a single column table.
'   Range({any single cell}).SpecialCells({whatever}) seems to work off the entire sheet.
'   Range({more than one cell}).SpecialCells({whatever}) seems to work off the specified cells.
' https://stackoverflow.com/questions/40537537/range-specialcells-clearcontents-clears-whole-sheet-instead

    On Error Resume Next

    With lst
        '.Range.Worksheet.Activate ' Enable this if you are debugging 

        If .ShowAutoFilter Then .AutoFilter.ShowAllData
        If .DataBodyRange.Rows.Count = 1 Then Exit Sub ' Table is already clear
        .DataBodyRange.Offset(1).Rows.Clear

        If .DataBodyRange.Columns.Count > 1 Then ' Check to see if SpecialCells is going to evaluate just one cell.
            .DataBodyRange.Rows(1).SpecialCells(xlCellTypeConstants).ClearContents
        ElseIf Not .Range.HasFormula Then
            ' Only one cell in range and it does not contain a formula.
            .DataBodyRange.Rows(1).ClearContents
        End If

        .Resize .Range.Rows("1:2")

        .HeaderRowRange.Offset(1).Select

        ' Reset used range on the sheet
        Dim X
        X = .Range.Worksheet.UsedRange.Rows.Count 'see J-Walkenbach tip 73

    End With

End Sub

最後に追加した手順は、John Walkenbachに起因するヒントです。これは、J-Walkenbach tip 73最後のセルの自動リセット

1
Ben