0

我可能遗漏了一些简单的东西,但 ListRows.Add 让我很伤心。这是功能:

Sub addEmployee(employeeName As String, tableToAddTo As ListObject)
   Dim newRow As ListRow

   Set newRow = tableToAddTo.ListRows.Add()
   newRow.Range.Cells(1, 1).Value = employeeName
   tableToAddTo.Sort.Apply
End Sub

在大多数情况下,这可以正常工作。但是,每当该函数在我的工作表中的某个表上运行时,调用 ListRows.Add 之后的行永远不会执行(至少这是调试器所指示的),并且该行不会被添加到表中。有什么想法/想法吗?

更新:

这是我在发帖后学到的东西。如果我为 Sub 提供存根数据,它可以正常工作。例如:

Sub driver() 
    Dim myTable As ListObject 
    Set myTable = getTableObject("myTableName") 
    Call addEmployee("myName", myTable)
End Sub

注意:getTableObject 循环遍历工作表并返回具有匹配名称的 ListObject。

处理调用代码的上下文似乎是一个问题。在失败的情况下,公式(函数调用)已放置在各种工作表的各个单元格中。该公式包含对其他单元格中数据的引用。当其他单元格中的数据发生变化时,将调用公式,然后调用上面给出的 addEmployee Sub。这是失败的情况。

4

8 回答 8

4

很抱歉与这个问题无关,但由于另一个原因,这是谷歌在搜索类似崩溃时出现的唯一 StackOverflow 帖子。崩溃问题ListRows.Add困扰了我很长一段时间,因此分享了导致我崩溃的问题。

工作表上有一个表格(比如 MySourceTable)。在我的 UserForm 中,ComboBox 的 RowSource 是该表(MySourceTable[ColName]) 中的一列。单击同一用户窗体上的另一个按钮时,我将新行插入ListRows.Add到该表中并导致 Excel 崩溃。如果这种情况与您的情况相似,请继续阅读。

崩溃是由仍然附加到表的 ComboBox 引起的,并且无法处理行的插入(请注意,它仍然被实例化,因为插入新行时我仍在用户窗体上)。经过一番痛苦之后,插入上方和下方的以下行解决了它:

    comboSetSelect.RowSource = ""
    Set newRow = myTable.ListRows.Add
    comboSetSelect.RowSource = "MySourceTable[ColName]" 'col set in properties

这会在插入新行之前将 ComboBox 从表中分离出来,一旦插入完成,就会再次更新 ComboBox。此外,新插入的行的值(如果在插入后立即更新)也会显示在 ComboBox 中。

于 2016-11-05T20:28:09.147 回答
3

看来我试图做的事情是不可能的。

开发自定义函数时,了解从其他 VBA 过程调用的函数与在工作表公式中使用的函数之间的主要区别非常重要。工作表公式中使用的函数过程必须是被动的。例如,函数过程中的代码不能操作范围或更改工作表上的内容。一个例子可以帮助说明这一点。

您可能很想编写一个自定义工作表函数来更改单元格的格式。例如,使用自定义函数根据单元格的值更改单元格中文本的颜色的公式可能很有用。尽你所能,然而,这样的函数是不可能写出来的。无论您做什么,该功能都不会改变工作表。请记住,函数只是返回一个值。它不能对对象执行操作。

也就是说,我应该指出一个值得注意的例外。可以使用自定义 VBA 函数更改单元格注释中的文本。

沃肯巴赫,J. (2007)。Microsoft Office Excel 2007 使用 VBA 进行强力编程。约翰威利父子公司,第 280 页。

于 2010-07-02T21:33:24.743 回答
2

我知道这是一个非常古老的问题,但这是我在尝试为自己回答时多次遇到的问题。我仍然不明白为什么会发生这种情况的细节,但这是我的解决方法。

Sub AddRow()
     Dim Tbl as ListObject
     Dim MyColumn as Integer

     Tbl.ListRows(1).Range.EntireRow.Insert
     Tbl.ListColumns(MyColumn).DataBodyRange.Cells(1,1).Value = "My Value"
End Sub

通过在第一个现有条目上方添加新行,表格会按预期自动向下调整,然后我可以开始将我的值写入表格。

再次,很抱歉恢复旧帖子,但我无法在其他地方找到适当的解决方案,所以这是我自己的解决方法,我希望将来对其他人有所帮助。

于 2016-05-23T18:07:48.850 回答
0

在我的情况下,表被一个列表框绑定

 Dim intClientRow As Integer
Dim strLstSource As String
strLstSource = frmHNW.lstB01People_List.RowSource
frmHNW.lstB01People_List.RowSource = ""
intClientRow = UpdateTableFromFrame(frmHNW.fraB01People, "Clients_tblClientDetails", True)
If intClientRow > 0 Then
    UpdateTableFromList frmHNW.lstB01Contact_Method, "ClientPeople_tblClientContactMethod", "=getClientID(" & intClientRow & ")"
    UpdateTableFromList frmHNW.lstB01Pref_Days, "ClientPeople_tblClientPrefDay", "=getClientID(" & intClientRow & ")"
    UpdateTableFromList frmHNW.lstB01Pref_Time, "ClientPeople_tblClientPrefTime", "=getClientID(" & intClientRow & ")"
End If

frmHNW.lstB01People_List.RowSource = strLstSource

UpdateTableFromFrame 表单将 lisrows.add 方法应用于列表框的源表。经过数小时的测试,我发现当我不删除列表源时,我的 listrows.add 方法失​​败了。因此,我在调用 UpdateTableFromFrame 之前删除了列表框的行源,并在行添加完成后恢复。这解决了问题

于 2016-06-11T20:25:07.993 回答
0

这也困扰了我一段时间。对我来说,似乎在循环中多次调用 ListRows.Add - 导致发生此错误,有时还会导致 Excel 崩溃。对我有用的解决方案:我在 ListRows.Add 命令之后添加了 DoEvents 命令:

tbl.ListRows.Add
DoEvents
于 2016-09-05T11:22:34.573 回答
0

我知道这是一个旧线程,我不想重新发布,我相信我有一个可以帮助其他人的解决方案。

关于我的脚本的快速信息,我有ListRows.Add in Private Sub BTN_Save_DblClick 我删除了所有代码,只留下了这个模块,令我惊讶的是,这有效,所以我开始实现每个子和函数,直到我得到那个是导致问题。

事实证明(对我来说)因为我将UserForm_Initialize()作为Private Sub而不是Public Sub,这导致ListRows失败,在此过程中崩溃 excel..

因此,如果您遇到此问题,并且您有UserForm_Initialize(),请确保将其设置为 Public 而不是 private。

无论如何,如果这不起作用,那么这是一个简单的消除过程,删除除ListRows之外的所有代码,并每次添加每个子/功能测试,直到找到导致问题的那个。

希望这可以帮助。

编辑所以这是一个临时修复,它再次开始崩溃,所以我删除了 userform_initialize 中的代码行并再次修复它。这太奇怪了,因为它所做的只是ComboBox1.RowSource=NamedRange

我以前从未遇到过 Excel VBA 的此类问题。

于 2016-09-30T14:04:06.857 回答
0

失败的另一个原因ListObject.ListRows.Add可能是工作表保护。由于我没有在任何搜索结果中看到此内容,因此我想将其添加到此处以供将来参考。

如果工作表受到保护

worksheet.Protect 

务必

worksheet.Unprotect 

申请前ListObject.ListRows.Add

于 2017-08-24T14:18:42.627 回答
0

简而言之

tab_.ListRows(1).Range.EntireRow.Insertmay(!) 代替tab_.ListRows.Add.
(就像SandPiper 的回答中已经建议的那样)

将其封装在一个更通用的函数中,该函数也返回ListRow

Function TabRowAdd(tab_ As ListObject) As ListRow
    tab_.ListRows(1).Range.EntireRow.Insert
    Set TabRowAdd = tab_.ListRows(1)
End Function

你会像这样使用它:TabRowAdd(tab_)而不是tab_.ListRows.Add

可能的原因

如果当前表格下方(或什至下方)还有其他非表格单元格,它将不起作用,因为(我猜)其他内容的“下移”可能会导致不良副作用或可能更复杂。

例如,想象一下下面的表格布局,应该如何直接在表格 1中插入一行?(通常是糟糕/愚蠢的布局 - 我知道 :))

| table 1 header |  | table 2 header |
|         row 1  |  |         row 1  |
|         row 2  |  |         row 2  |         
                    |         row 3  |  | table 5 header |
| table 3 header |  |         row 4  |  |         row 1  |
|         row 1  |                      |         row 2  |
|         row 2  |                      |         row 3  |
                                        |         row 4  |
    | table 4 header      |             |         row 5  |
    |         row 1       |

=> 这并不容易,这就是为什么我猜他们可能只是检查,如果在要操作的(插入行/列,删除行/列)表下方或下方有非表格内容,从而引发一些1004异常。
(甚至可能遵循“非A列起始”表已经存在这个问题 - 我没有检查它)

于 2019-06-24T08:05:25.627 回答