Search code examples
excelvba

Excel right click add menu item issue


The following code works nicely and produces the required outcome when I right click in any cell in the range (B3:B5000). However, if I then right click on another cell the menu item is of the first cell I right clicked. If I right click on another cell in a different column and then right click in the range (B3:B5000) it will then be correct.

Any support fixing this "bug" would be greatly appreciated.

Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
    Dim cmdBtn As CommandBarButton, param, forename, surname As String
  
    Set cmdBtn = Application.CommandBars("Cell").FindControl(, , "testBt")
    If Intersect(Target, Range("B3:B5000")) Is Nothing Then
        If Not cmdBtn Is Nothing Then cmdBtn.Delete
        Exit Sub
    End If
    
    forename = ActiveCell.Offset(0, 2).Value
    surname = ActiveCell.Offset(0, 1).Value
    
    If Not cmdBtn Is Nothing Then Exit Sub

    Set cmdBtn = Application.CommandBars("Cell").Controls.Add(Temporary:=True)
    param = ActiveCell.Offset(0, 0).Value 'parameter to be sent. It can be any kind...
    With cmdBtn
        .Tag = "testBt"
        .Caption = forename & " " & surname & " Breakdown"
        .Style = msoButtonCaption
        .OnAction = "'TestMacro """ & param & """'"
    End With
End Sub

For anyone interested the macro it calls simply does this:

Sub TestMacro(str As String)
   MsgBox "It works... (" & str & ")"
End Sub

Solution

  • You should set a break on the first line of code so you can step through it after right clicking on a different cell in the target range. This will allow you to check the execution flow in each scenario and understand what the code is actually doing.

    If you right click in the target range a 2nd time, then cmdBtn will already exist, so the code will stop at this point:

    If Not cmdBtn Is Nothing Then Exit Sub
    

    You probably need to replace that line with this:

    If Not cmdBtn Is Nothing Then cmdBtn.Delete
    

    To remove the old button with the old caption, before adding a new button with a new caption.