17

我有一个 Excel 表格,用于记录您在特定日期和膳食中摄入的食物。我有一个网格,每条线代表你吃的食物,它有多少糖,等等。

然后我添加了一个保存按钮以将所有数据保存到另一张表中的表格中。

这是我尝试过的

    Public Sub addDataToTable(ByVal strTableName As String, ByRef arrData As Variant)
    Dim lLastRow As Long
    Dim iHeader As Integer
    Dim iCount As Integer

    With Worksheets(4).ListObjects(strTableName)
        'find the last row of the list
        lLastRow = Worksheets(4).ListObjects(strTableName).ListRows.Count

        'shift from an extra row if list has header
        If .Sort.Header = xlYes Then
            iHeader = 1
        Else
            iHeader = 0
        End If
    End With

    'Cycle the array to add each value
    For iCount = LBound(arrData) To UBound(arrData)
        **Worksheets(4).Cells(lLastRow + 1, iCount).Value = arrData(iCount)**
    Next iCount
End Sub

但我在突出显示的行上不断收到相同的错误:

Application-defined or object-defined error

我做错了什么?

提前致谢!

4

8 回答 8

30

你没有说你使用的是哪个版本的 Excel。这是为 2007/2010 编写的(Excel 2003 需要不同的方法)

你也没有说你是如何调用的addDataToTable以及你传递到什么arrData
我猜你正在传递一个0基于数组。如果是这种情况(并且表从 Column 开始A),那么iCount将从开始计数0.Cells(lLastRow + 1, iCount)尝试引用0无效的列。

您也没有利用ListObject. 您的代码假定ListObject1 位于从 row 开始1。如果不是这种情况,您的代码会将数据放在错误的行中。

这是一个利用ListObject

Sub MyAdd(ByVal strTableName As String, ByRef arrData As Variant)
    Dim Tbl As ListObject
    Dim NewRow As ListRow

    ' Based on OP 
    ' Set Tbl = Worksheets(4).ListObjects(strTableName)
    ' Or better, get list on any sheet in workbook
    Set Tbl = Range(strTableName).ListObject
    Set NewRow = Tbl.ListRows.Add(AlwaysInsert:=True)

    ' Handle Arrays and Ranges
    If TypeName(arrData) = "Range" Then
        NewRow.Range = arrData.Value
    Else
        NewRow.Range = arrData
    End If
End Sub

可以通过多种方式调用:

Sub zx()
    ' Pass a variant array copied from a range
    MyAdd "MyTable", [G1:J1].Value
    ' Pass a range
    MyAdd "MyTable", [G1:J1]
    ' Pass an array
    MyAdd "MyTable", Array(1, 2, 3, 4)
End Sub
于 2012-09-06T11:06:19.193 回答
5

Tbl.ListRows.Add对我不起作用,我相信很多其他人都面临同样的问题。我使用以下解决方法:

    'First check if the last row is empty; if not, add a row
    If table.ListRows.count > 0 Then
        Set lastRow = table.ListRows(table.ListRows.count).Range
        For col = 1 To lastRow.Columns.count
            If Trim(CStr(lastRow.Cells(1, col).Value)) <> "" Then
                lastRow.Cells(1, col).EntireRow.Insert
                'Cut last row and paste to second last
                lastRow.Cut Destination:=table.ListRows(table.ListRows.count - 1).Range
                Exit For
            End If
        Next col
    End If

    'Populate last row with the form data
    Set lastRow = table.ListRows(table.ListRows.count).Range
    Range("E7:E10").Copy
    lastRow.PasteSpecial Transpose:=True
    Range("E7").Select
    Application.CutCopyMode = False

希望它可以帮助那里的人。

于 2013-03-25T10:22:17.860 回答
3

我有同样的错误消息,经过大量试验和错误后发现它是由在 ListObject 上设置的高级过滤器引起的。清除高级过滤器 .listrows.add 后再次正常工作。要清除过滤器,我使用它 - 不知道如何仅清除特定列表对象而不是完整工作表的过滤器。

Worksheets("mysheet").ShowAllData
于 2014-12-04T17:18:38.383 回答
1

实际上,我刚刚发现,如果您想在表格中的选择下方添加多行, Selection.ListObject.ListRows.Add AlwaysInsert:=True效果非常好。我只是将代码复制了五次以在我的表中添加五行

于 2015-09-28T20:16:23.963 回答
1

我之前遇到过同样的问题,我通过在新工作表中创建同一个表并删除与该表关联的所有名称范围来修复它,我相信当您使用 listobjects 时,您不允许将名称范围包含在您的表 希望有帮助 谢谢

于 2017-06-25T20:13:59.363 回答
0

今天遇到了这个问题(Excel 在使用添加行时崩溃.ListRows.Add)。在阅读了这篇文章并检查了我的表格后,我意识到行中某些单元格中公式的计算取决于其他单元格中的值。在我的情况下,更高列的单元格甚至是带有公式的单元格!

解决方案是从后到前填充新添加的行,这样计算就不会出错。

Excel 通常可以处理不同单元格中的公式,但似乎在表格中添加一行会按列的顺序(A、B、C 等)重新计算。

希望这有助于解决问题.ListRows.Add

于 2018-09-04T12:35:33.003 回答
-1

只需删除该表并创建一个具有不同名称的新表。也不要删除该表的整行。似乎当包含表行的整行被删除时,它会损坏 DataBodyRange 已损坏

于 2016-06-11T13:19:32.090 回答
-1

由于使用ListRow.Add可能是一个巨大的瓶颈,我们应该只在无法避免的情况下使用它。如果性能对您很重要,请在此处使用此功能来调整表的大小,这比推荐的方式添加行要快得多。

请注意,如果有的话,这将覆盖您的表格下方的数据!

此功能基于 Chris Neilsen接受的答案

Public Sub AddRowToTable(ByRef tableName As String, ByRef data As Variant)
    Dim tableLO As ListObject
    Dim tableRange As Range
    Dim newRow As Range

    Set tableLO = Range(tableName).ListObject
    tableLO.AutoFilter.ShowAllData

    If (tableLO.ListRows.Count = 0) Then
        Set newRow = tableLO.ListRows.Add(AlwaysInsert:=True).Range
    Else
        Set tableRange = tableLO.Range
        tableLO.Resize tableRange.Resize(tableRange.Rows.Count + 1, tableRange.Columns.Count)
        Set newRow = tableLO.ListRows(tableLO.ListRows.Count).Range
    End If

    If TypeName(data) = "Range" Then
        newRow = data.Value
    Else
        newRow = data
    End If
End Sub
于 2017-04-25T23:41:02.583 回答