将新行添加到excel表格(VBA)

将新行添加到excel表格(VBA),vba,excel,Vba,Excel,我有一个excel,用来记录你在特定的一天和一顿饭中摄入的食物。我有一个网格,每一行代表你吃的食物,它有多少糖,等等 然后我添加了一个保存按钮,将所有数据保存到另一个工作表中的表中 这就是我尝试过的 Public Sub addDataToTable(ByVal strTableName As String, ByRef arrData As Variant) Dim lLastRow As Long Dim iHeader As Integer Dim iCou

我有一个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
我做错了什么


提前谢谢

您没有说您正在使用哪个版本的Excel。这是为2007/2010年编写的(Excel 2003需要另一种方法)

您也不会说如何调用
addDataToTable
以及将什么传递到
arrData

我猜您正在传递一个基于
0
的数组。如果是这种情况(表从列
A
开始),则
iCount
将从
0
开始计数。单元格(lLastRow+1,iCount)
将尝试引用列
0
,该列无效

您也没有利用
列表对象
。您的代码假定
ListObject
1位于第
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

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
”首先检查最后一行是否为空;如果没有,请添加一行
如果table.ListRows.count>0,则
Set lastRow=table.ListRows(table.ListRows.count).Range
对于col=1到lastRow.Columns.count
如果Trim(CStr(lastRow.Cells(1,col.Value))“”则
lastRow.Cells(1,列).EntireRow.Insert
'剪切最后一行并粘贴到倒数第二行
lastRow.Cut目标:=表.ListRows(表.ListRows.count-1).范围
退出
如果结束
下一列
如果结束
'用表单数据填充最后一行
Set lastRow=table.ListRows(table.ListRows.count).Range
范围(“E7:E10”)。副本
lastRow.PasteSpecial转置:=真
范围(“E7”)。选择
Application.CutCopyMode=False

希望它能帮助其他人。

我收到了相同的错误消息,经过多次尝试和错误后,我发现这是由ListObject上设置的高级过滤器引起的。 清除高级过滤器后,listrows.add再次正常工作。 要清除过滤器,我使用这个-不知道如何只清除特定listobject而不是完整工作表的过滤器

Worksheets("mysheet").ShowAllData

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

只需删除该表并创建一个具有不同名称的新表。也不要删除该表的整行。似乎当包含表行的整行被删除时,它会损坏数据源范围,就像使用
ListRow一样。Add
可能是一个巨大的瓶颈,我们只能在无法避免的情况下使用它。 如果性能对您很重要,请在此处使用此函数调整表的大小,这比按建议的方式添加行要快得多

请注意,如果有数据,这将覆盖表下的数据

此函数基于Chris Neilsen的公认答案


我以前也遇到过同样的问题,我通过在新的工作表中创建同一个表并删除与该表关联的所有名称范围来解决了这个问题。我相信,当您使用listobjects时,您不可能在表中包含名称范围。希望对您有所帮助,谢谢(Excel在使用
.ListRows.Add
添加行时崩溃)。 在阅读了这篇文章并检查了我的表格后,我意识到行中一些单元格中公式的计算依赖于其他单元格中的值。 在我的例子中,单元格位于更高的列中,甚至是带有公式的单元格

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

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


希望这有助于解决
.ListRows.Add的问题。我忘了。这是Office 2010版的。但这解决了我的问题,谢谢:)如果在myAdd中设置了tbl,引用特定工作表可能会有一定的限制。或者,行:Set Tbl=range(strTableName)。可以改用ListObject,这样无论表格在哪里它都可以工作。@RowanC代码基于OP的原始代码,但您的建议更好。██  慢██  使用ListRows.Add非常慢!在复杂的工作表中,以这种方式添加100行需要35秒!(我确实关闭了事件和屏幕更新)。“一定有更好的解决办法了。”Jonas_Hess我刚刚在一张简单的纸上做了一个测试,添加100行的时间<0.5秒。所以慢的不是
AddRows
,而是你的“复杂”工作表。代码运行时是否尝试将计算设置为手动?有趣的是,表中的行越多,运行速度越慢。这里有一点,
ListRows.Add
非常感谢您,在我的案例中帮助了我:)
工作表(“mysheet”).ListObjects(“tableName”).AutoFilter.ShowAllData
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