Reputation: 33
I have an excel workbook with multiple sheets and am trying to limit user ability to insert/delete rows within the first worksheet. I currently have VBA code in place that removes (hides) the 'Insert' and 'Delete' buttons in the Row menu, and inserts to new fake insert/delete buttons which both create pop-up boxes instructing the user in how to properly remove/add rows (I have some key-bound macros which simultaneously delete/add rows across multiple select sheets).
This code works SOMETIMES, but most often returns a "Run-time error '91': Object variable or With block variable not set".
From picking through a multitude of similar questions, I've determined that I'm most likely not initializing the command bar object correctly (or something along those lines), but I haven't been able to figure out how to correctly do it. Can anyone assist in correcting the error?
Here is the code within the sheet object:
Private Sub Worksheet_Activate()
'reset to standard context menu before adding new option
Application.CommandBars("Row").Reset
'removes standard Delete and Insert menu bar items
Application.CommandBars("Row").FindControl(ID:=293).Visible = False
Application.CommandBars("Row").FindControl(ID:=296).Visible = False
'add custom row deletion call
With Application.CommandBars("Row").Controls.Add
.Caption = "Delete Row"
.Style = msoButtonCaption
.OnAction = "DeleteRow"
End With
With Application.CommandBars("Row").Controls.Add
.Caption = "Insert Row"
.Style = msoButtonCaption
.OnAction = "InsertRow"
End With
End Sub
Private Sub Worksheet_Deactivate()
'get rid of the customization when you're done with this sheet
Application.CommandBars("Row").Reset
End Sub
Here is the code within the workbook object:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Source As Range)
'resets menu bars when workbook sheets are changed
Application.CommandBars("Row").Reset
End Sub
Private Sub Workbook_Deactivate()
'Resets menu bars when workbook is deactivated
Application.CommandBars("Row").Reset
End Sub
Here is are the modules for the added buttons -
Module 1:
Public Sub DeleteRow()
MsgBox "Manually deleting rows from this Estimate will disconnect linked sheets. Please use CTRL-Q to delete rows.", vbOKOnly, "WARNING: Delete Rows"
End Sub
Module 2:
Public Sub InsertRow()
MsgBox "Manually inserting rows into this Estimate will disconnect linked sheets. Please use CTRL-A to add rows.", vbOKOnly, "WARNING: Insert Row"
End Sub
Upvotes: 0
Views: 242
Reputation: 4640
Setting these controls visibility to false appears to be modifying the collection, removing the ID you're looking for.
Code to see IDs:
Sub test()
Dim ctl As Object
For Each ctl In Application.CommandBars("Row").Controls
Debug.Print ctl.ID, ctl.Caption, ctl.TooltipText
Next
Debug.Print vbNewLine, vbNewLine
End Sub
If I run this before modifying:
ID | Caption | Tooltip |
---|---|---|
21 | Cu&t | Cu&t |
19 | &Copy | &Copy |
22 | &Paste | &Paste |
21437 | Paste &Special... | Paste &Special... |
3624 | &Paste Table | &Paste Table |
32713 | Data T&ype | |
296 | &Rows | Insert Rows |
293 | &Delete | &Delete |
3125 | Clear Co&ntents | Clear Co&ntents |
855 | &Format Cells... | &Format Cells... |
541 | &Row Height... | &Row Height... |
883 | &Hide | &Hide (Ctrl+9) |
884 | &Unhide | &Unhide (Ctrl+Shift+( ) |
3626 | &Remove Hyperlinks | &Remove Hyperlinks |
Running it as you have it with ID:=293 first:
ID | Caption | Tooltip |
---|---|---|
21 | Cu&t | Cu&t |
19 | &Copy | &Copy |
22 | &Paste | &Paste |
21437 | Paste &Special... | Paste &Special... |
3624 | &Paste Table | &Paste Table |
32713 | Data T&ype | |
3183 | &Insert | Insert Cells |
293 | &Delete | &Delete |
3125 | Clear Co&ntents | Clear Co&ntents |
855 | &Format Cells... | &Format Cells... |
541 | &Row Height... | &Row Height... |
883 | &Hide | &Hide (Ctrl+9) |
884 | &Unhide | &Unhide (Ctrl+Shift+( ) |
3626 | &Remove Hyperlinks | &Remove Hyperlinks |
You can see that ID 296 is gone from the list and 3183 is now present. Testing manually it does the same thing, adds a row.
After swapping the lines and successfully running your script:
ID | Caption | Tooltip |
---|---|---|
21 | Cu&t | Cu&t |
19 | &Copy | &Copy |
22 | &Paste | &Paste |
21437 | Paste &Special... | Paste &Special... |
3624 | &Paste Table | &Paste Table |
32713 | Data T&ype | |
3183 | &Insert | Insert Cells |
293 | &Delete | &Delete |
3125 | Clear Co&ntents | Clear Co&ntents |
855 | &Format Cells... | &Format Cells... |
541 | &Row Height... | &Row Height... |
883 | &Hide | &Hide (Ctrl+9) |
884 | &Unhide | &Unhide (Ctrl+Shift+( ) |
3626 | &Remove Hyperlinks | &Remove Hyperlinks |
1 | Delete Row | Delete Row |
1 | Insert Row | Insert Row |
No matter what 296 seems to be replaced while 293 sticks around. I can't reproduce it now but while testing I saw ID 3181 instead of 3183 so I wouldn't rely on that value.
I have no clue why it would do this.
Upvotes: 2