Excel VBA ListRows.Add Fails

不羁岁月 提交于 2019-12-18 09:43:20

问题


I'm probably missing something simple, but ListRows.Add is giving me grief. Here's the function:

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

In most cases, this works fine. However, whenever the function runs on a certain table in my worksheet, the lines following the call to ListRows.Add are never executed (at least that's what the debugger indicates) and the row does not get added to the table. Any thoughts/ideas?

UPDATE:

Here's what I've learned since the post. If I feed the Sub with stub data it works fine. For example:

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

Note: getTableObject cycles through the worksheets and returns the ListObject with the matching name.

It seems to be an issue dealing with the context in which the code is called. In the case that fails, a formula (Function call) has been placed in various cells of various worksheets. The formula contains references to data in other cells. When the data in the other cells changes, the formula is invoked, which in turn calls the addEmployee Sub that is given above. This is the case that fails.


回答1:


It appears that what I was trying to do is not possible.

When you develop custom functions, it’s important to understand a key distinction between functions that you call from other VBA procedures and functions that you use in worksheet formulas. Function procedures used in worksheet formulas must be passive. For example, code within a Function procedure cannot manipulate ranges or change things on the worksheet. An example can help make this clear.

You might be tempted to write a custom worksheet function that changes a cell’s formatting. For example, it could be useful to have a formula that uses a custom function to change the color of text in a cell based on the cell’s value. Try as you might, however, such a function is impossible to write. No matter what you do, the function won’t change the worksheet. Remember, a function simply returns a value. It cannot perform actions with objects.

That said, I should point out one notable exception. It is possible to change the text in a cell comment by using a custom VBA function.

Walkenbach, J. (2007). Microsoft Office Excel 2007 Power Programming with VBA. John Wiley & Sons, p 280.




回答2:


Sorry for the irrelevance to the question, but this is the only StackOverflow post that comes up on Google when searching for similar crash, due to another cause. The crash on ListRows.Add bugged me extensively for quite a while, so sharing the issue which was causing it for me.

There's a table (say MySourceTable) on a worksheet. In my UserForm, a ComboBox's RowSource is a column from this table (MySourceTable[ColName]). On clicking another button on the same UserForm, I was inserting the new row using ListRows.Add into this table and crashing Excel. If this scenario is similar to yours, read on.

The crash is being caused by the ComboBox, which is still attached to the table, and is unable to process the insertion of rows (please mind that it's still instantiated because I'm still on the UserForm when inserting the new row). After a lot of pain, the following lines above and below the insertion solved it for good:

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

This detaches the ComboBox from the table before inserting the new row and once insertion is done, updates the ComboBox again. Further, the newly inserted row's value (if updated right after insertion) shows up as well in ComboBox.




回答3:


I understand this is a really old question, but it is one that I have come across numerous times while trying to answer for myself. I still do not understand the specifics of why this is happening, but here's my workaround.

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

By adding a new row above the first existing entry, the table automatically adjusts down as intended, then I can start writing my values into the table.

Again, sorry for reviving an old post, but I was unable to find an adequate solution elsewhere, so this is my own workaround I hoped would be helpful to others in the future.




回答4:


In my case table was bound by a listbox

 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 forms applies lisrows.add method to the source table of the listbox. After hours of testing I found that when I don't remove the list source my listrows.add method fails. So I removed rowsource of the listbox before calling UpdateTableFromFrame and restored back once row addtion is done. This solved the problem




回答5:


This also bugged me for a while. For me, it seemed that calling ListRows.Add multiple times in a loop - caused this error to occur, and sometimes crashed Excel. The solution that worked for me: I added DoEvents command after the ListRows.Add command:

tbl.ListRows.Add
DoEvents



回答6:


I know this is an old thread, I don't want to re-post and I beleive I have a solution that might help others.

Quick bit of info about my scripts, I have ListRows.Add in Private Sub BTN_Save_DblClick I removed all my code and left only this module, this to my surprise worked, so I started implementing each sub and function until I got to the one that was causing the problem.

It turns out that (for me) because I had UserForm_Initialize() as a Private Sub instead of a Public Sub, this caused ListRows to fail, crashing excel in the process..

So if you are having this issue, and you have UserForm_Initialize(), make sure it is set to Public instead of private.

Anyway if that doesn't work, then it's a simple process of elimination, remove all your code except the one with ListRows and add each sub/function testing each time, until you find the one that's causing the problem.

Hope this helps.

EDIT So this was a temporary fix, it started crashing again, so I removed the line of code within the userform_initialize and it fixed it again.. this is so strange because all it does is ComboBox1.RowSource=NamedRange.

I never had this sort of issue with Excel VBA before.




回答7:


Another cause for ListObject.ListRows.Add to fail can be worksheet protection. Since I didn't see this mentioned in any of my search results, I'd like to add it here for future reference.

If a worksheet has been protected with

worksheet.Protect 

be sure to

worksheet.Unprotect 

it before applying ListObject.ListRows.Add!




回答8:


In short

tab_.ListRows(1).Range.EntireRow.Insert may(!) work instead of tab_.ListRows.Add.
(Like already suggested in SandPiper's answer)

encapsulating it in a more general function that also returns ListRow:

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

you would use it like this: TabRowAdd(tab_) instead of tab_.ListRows.Add

Possible Cause

If there are other non-table cells underneath (or maybe even beneath) the current table, it wont work, because (I guess) the "shifting-down" of this other content could cause bad side-effects or could be more complicated.

So e.g. imagine the following table layout and how should the insert of a row in table 1 be accomplished straight-forward? (generally bad/stupid layout - I know :) )

| 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       |

=> this is not easy and that's why I guess they may just check, if there is non-table stuff beneath or underneath the to-be-manipulated (insert row/col, delete row/col) table and thus throw some 1004 exception.
(maybe even following "non-A-column-starting" tables would have that problem already - I did not check it)



来源:https://stackoverflow.com/questions/3167893/excel-vba-listrows-add-fails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!