Bonjour,
Une proposition VBA "usine à gaz".
Disons que j'ai sorti les grenades pour exterminer 2 termites...
Dans un module standard :
Option Explicit
Public Const NOMPOPUP As String = "MonMenu"
'---- Déterminer les coordonnées en pixels, par rapport à l'écran, du coin supérieur gauche d'une cellule Excel
Private Type position
Left As Integer
Top As Integer
End Type
Private Const GARDEFOU As Byte = 20
Public Function Place_Curseur(Cellule As Range) As position
Dim p As Pane
Set p = QuelPane(Cellule, True)
If Not p Is Nothing Then
Place_Curseur = TopLeftCellule(p, Cellule, False)
End If
Set p = Nothing
End Function
Private Function TopLeftCellule(ByVal LePane As Pane, ByVal Rng As Range, Optional ByVal DansLaCellule As Boolean = True) As position
Dim cel As Range, cc As Byte, cr As Byte, l As Integer, t As Integer, b As Integer, R As Integer, IniL As Integer, INIT As Integer, IniR As Integer, IniB As Integer
With LePane
If Rng.Column = .ScrollColumn Then cc = 0 Else cc = 5
If Rng.Row = .ScrollRow Then cr = 0 Else cr = 5
l = .PointsToScreenPixelsX(Rng.Left) - cc: IniL = l
t = .PointsToScreenPixelsY(Rng.Top) - cr: INIT = t
R = .PointsToScreenPixelsX(Rng.Offset(1, 1).Left) - cc: IniR = R
b = .PointsToScreenPixelsY(Rng.Offset(1, 1).Top) - cr: IniB = b
On Error Resume Next
Set cel = ActiveWindow.RangeFromPoint(l, t)
Do Until cel.Left >= Rng.Left
l = l + 1
If l > IniL + GARDEFOU Then GoTo BoucleInfinie
Set cel = ActiveWindow.RangeFromPoint(l, t)
Loop
Do Until cel.Top >= Rng.Top
t = t + 1
If t > INIT + GARDEFOU Then GoTo BoucleInfinie
Set cel = ActiveWindow.RangeFromPoint(l, t)
Loop
Set cel = Nothing
End With
TopLeftCellule.Left = IIf(DansLaCellule, l, l - 1)
TopLeftCellule.Top = IIf(DansLaCellule, t, t - 1)
Exit Function
BoucleInfinie:
MsgBox "Conditions impossibles pour le positionnement du curseur"
End Function
Private Function QuelPane(ByVal t As Range, Optional ByVal ActivationFeuil As Boolean = False) As Pane
Dim LngNbPanes As Long, LngPane As Long
If ActiveWindow.VisibleRange.Worksheet.Parent.Name = t.Worksheet.Parent.Name Then
If ActiveWindow.ActiveSheet.Name = t.Worksheet.Name Or ActivationFeuil Then
t.Worksheet.Activate
LngNbPanes = ActiveWindow.Panes.Count
For LngPane = 1 To LngNbPanes
With ActiveWindow.Panes(LngPane)
If Not Intersect(t, .VisibleRange) Is Nothing Then
Set QuelPane = ActiveWindow.Panes(LngPane)
Exit Function
End If
End With
Next
End If
End If
Set QuelPane = Nothing
End Function
'---- Déterminer les coordonnées en pixels, par rapport à l'écran, du coin supérieur gauche d'une cellule Excel
'---- Macros MENU et SOUS-MENU
Sub Macro_On_Action(Choix As String)
ActiveCell = Choix
End Sub
Public Sub Cree_Affich_Menu(Target As Range)
Dim p As position
Call Suppr_Menu
Call Creation_Menu
On Error Resume Next
p = Place_Curseur(Target.Offset(1, 1))
Application.CommandBars(NOMPOPUP).ShowPopup p.Left, p.Top
On Error GoTo 0
End Sub
Private Sub Suppr_Menu()
On Error Resume Next
Application.CommandBars(NOMPOPUP).Delete
On Error GoTo 0
End Sub
Private Sub Creation_Menu()
Dim MenuItem As CommandBarPopup
Dim Plage As Range, R As Range
Dim i As Integer, j As Integer
With Application.CommandBars.Add(Name:=NOMPOPUP, position:=msoBarPopup, MenuBar:=False, Temporary:=True)
For i = 2 To 4
Set MenuItem = .Controls.Add(Type:=msoControlPopup)
With MenuItem
.Caption = Worksheets("Listes").Cells(i, 1).Value
Set R = Worksheets("Listes").Rows(1).Cells.Find(.Caption)
Set Plage = R.Resize(Worksheets("Listes").Cells(Rows.Count, R.Column).End(xlUp).Row)
For j = 2 To Plage.Cells.Count
With .Controls.Add(Type:=msoControlButton)
.Caption = Plage.Cells(j).Value
.OnAction = "'" & ThisWorkbook.Name & "'!" & "'Macro_On_Action """ & .Caption & "'"
End With
Next
End With
Next
End With
Set MenuItem = Nothing
Set Plage = Nothing
Set R = Nothing
End Sub
'---- Macros MENU et SOUS-MENU
Dans le module de la feuille concernée :
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Cells.Count = 1 Then
If Target.Column = 2 Then
Cree_Affich_Menu Target
End If
End If
End Sub
Le fichier exemple (honteusement pompé à Jean-Eric salutations]) :