web-dev-qa-db-ger.com

Wie kann man klare Tabelleninhalte auswählen, ohne die Tabelle zu zerstören?

Ich habe eine VBA-Funktion in Excel 2010, die ich mit Hilfe von Personen hier erstellt habe. Diese Funktion kopiert den Inhalt einer Tabelle/eines Formulars, sortiert sie und sendet sie an die entsprechenden Tabellen.

Nachdem Sie diese Funktion ausgeführt haben, möchte ich, dass die ursprüngliche Tabelle gelöscht wird. Ich kann dies mit dem folgenden Code erreichen, vorausgesetzt, ACell wurde als erste Zelle in der Tabelle definiertACell.ListObject.Range.ClearContents funktioniert einwandfrei. Das einzige Problem ist, dass die Tabelle sowie die Datenwerte gelöscht werden.

Gibt es einen Weg, um das zu umgehen? Ich möchte die Tabelle lieber nicht jedes Mal einrichten, wenn ich Daten eingebe.

9
SpeedCrazy

Wie wäre es mit:

ACell.ListObject.DataBodyRange.Rows.Delete

Dadurch bleiben Ihre Tabellenstruktur und Überschriften erhalten, aber alle Daten und Zeilen werden gelöscht.

BEARBEITEN: Ich werde nur einen Teil meiner Antwort aus Ihrem vorherigen Beitrag ändern, da er meistens das tut, was Sie wollen. So bleibt nur eine Reihe übrig:

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

Wenn Sie alle Zeilen mit ihren Formeln und so weiter beibehalten möchten, tun Sie einfach Folgendes:

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

Das ist nahe an dem, was @Readify vorgeschlagen hat, außer dass Formeln nicht gelöscht werden.

28
Doug Glancy

Löschen Sie einfach die Daten (nicht die gesamte Tabelle einschließlich Kopfzeilen):

ACell.ListObject.DataBodyRange.ClearContents
7
Reafidy

Ich verwende diesen Code, um meine Daten zu entfernen, aber die Formeln in der obersten Zeile belassen. Außerdem werden alle Zeilen außer der obersten Zeile entfernt und die Seite nach oben verschoben. 

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

Es gibt eine Bedingung, die die meisten dieser Lösungen nicht berücksichtigen. Ich habe Patrick Honorez 'Lösung überarbeitet, um damit umzugehen. Ich hatte das Gefühl, ich musste dies teilen, weil ich mir die Haare aus dem Kopf zog, als die ursprüngliche Funktion gelegentlich mehr Daten löschte, als ich erwartet hatte.

Die Situation tritt auf, wenn die Tabelle nur eine Spalte enthält und die Funktion .SpecialCells(xlCellTypeConstants).ClearContents versucht, den Inhalt der obersten Zeile zu löschen. In diesem Fall wird nur eine Zelle ausgewählt (die oberste Zeile der Tabelle, die nur eine Spalte enthält), und der Befehl SpecialCells gilt für das gesamte Blatt anstelle des ausgewählten Bereichs. Was mit mir geschah, waren andere Zellen auf dem Blatt, die sich außerhalb meines Tisches befanden, wurden ebenfalls gelöscht.

Ich habe ein bisschen gegraben und fand diesen Rat von Mathieu Guindon: Range SpecialCells ClearContents löscht das ganze Blatt

Range ({jede einzelne Zelle}). SpecialCells ({whatever}) scheint auf dem gesamten Blatt zu funktionieren.

Range ({mehr als eine Zelle}). SpecialCells ({whatever}) scheint von den angegebenen Zellen abzuarbeiten.

Wenn die Liste/Tabelle nur eine Spalte enthält (in Zeile 1), prüft diese Revision, ob die Zelle eine Formel enthält, und wenn nicht, wird nur der Inhalt dieser einen Zelle gelöscht.

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

Ein letzter Schritt, den ich eingeschlossen habe, ist ein Tipp, der John Walkenbach zugeschrieben wird, der manchmal als J-Walkenbach tip 73Automatische Zurücksetzung der letzten Zelle

1
Ben

Ich habe die Lösung von Doug Glancy überarbeitet, um das Löschen von Zeilen zu vermeiden, was zu Problemen mit #Ref in Formeln führen kann. 

Sub ClearList(lst As ListObject)
'clears a listObject while leaving 1 empty row + formulae
    With lst
        If .ShowAutoFilter Then .AutoFilter.ShowAllData
        If .DataBodyRange.Rows.Count = 1 Then Exit Sub
        .DataBodyRange.Offset(1).Rows.Clear
        .DataBodyRange.Rows(1).SpecialCells(xlCellTypeConstants).ClearContents
        .Resize .Range.Rows("1:2")
    End With

End Sub
1
Patrick Honorez