Catch event on chart click

前端 未结 4 1219
谎友^
谎友^ 2020-12-18 10:39

I need to catch event in Excel VBA when I click on the chart.

I want to bring the chart to the front, when it is activated, but I can\'t find an appropriate event.

相关标签:
4条回答
  • 2020-12-18 10:55

    Real easy. Put this VBA procedure into a regular code module:

    Sub ClickChart()
      ActiveSheet.ChartObjects(Application.Caller).BringToFront
    End Sub
    

    Assign the macro ClickChart to all charts you want to have this behavior.

    When you click any of the charts, it gets moved in front of all others on the sheet.

    After posting, I see that @timwilliams has suggested this in a comment to another answer.

    0 讨论(0)
  • 2020-12-18 11:05

    If you have a collection of charts to automate, either on particular sheet(s), or the entire workbook then I would suggest that you use a class module to capture rather than tie in code chart by chart

    Jon Peltier (as per normal) has covered this charting code option in great detail, see Chart Events in Microsoft Excel.

    In a class module called CEventChart put:

    Option Explicit
    ' Declare object of type "Chart" with events
    Public WithEvents EvtChart As Chart    
    
    Private Sub EvtChart_Activate()
    EvtChart.ChartObjects msoBringToFront
    End Sub
    

    In a normal module put

    Option Explicit
    
    Dim clsEventChart As New CEventChart
    Dim clsEventCharts() As New CEventChart
    
    Sub Set_All_Charts()
        ' Enable events on sheet if it is a chart sheet
        If TypeName(ActiveSheet) = "Chart" Then
            Set clsEventChart.EvtChart = ActiveSheet
        End If
    
        ' Enable events for all charts embedded on a sheet
        ' Works for embedded charts on a worksheet or chart sheet
        If ActiveSheet.ChartObjects.Count > 0 Then
            ReDim clsEventCharts(1 To ActiveSheet.ChartObjects.Count)
            Dim chtObj As ChartObject
            Dim chtnum As Integer
    
            chtnum = 1
            For Each chtObj In ActiveSheet.ChartObjects
                ' Debug.Print chtObj.Name, chtObj.Parent.Name
                Set clsEventCharts(chtnum).EvtChart = chtObj.Chart
                chtnum = chtnum + 1
            Next ' chtObj
        End If
    End Sub
    
    Sub Reset_All_Charts()
        ' Disable events for all charts previously enabled together
        Dim chtnum As Integer
        On Error Resume Next
        Set clsEventChart.EvtChart = Nothing
        For chtnum = 1 To UBound(clsEventCharts)
            Set clsEventCharts(chtnum).EvtChart = Nothing
        Next ' chtnum
    End Sub
    

    then run Set_All_Charts with the sheet selected where you want your charts to be sent to the front, Jon uses these sheet events to set and disable the chart code on a particular sheet

    Private Sub Worksheet_Activate()
        Set_All_Charts
    End Sub
    
    Private Sub Worksheet_Deactivate()
        Reset_All_Charts
    End Sub
    
    0 讨论(0)
  • 2020-12-18 11:06

    If I understood the question, I faced the same problem. Whenever there are several overlapping charts, their visualization precedence follows the ZOrder.

    In Excel 2003, when one selected a chart, it came to the foreground (at least for visualization, I do not know whether its ZOrder was temporarily changed). When the chart was deselected, its visualization precedence returned to "normal".

    Starting with Excel 2007, charts do not temporarily come to foreground for visualization when selected, so if they are buried behind other charts (or possibly other Shapes), the only option to see them in full is to bring them to front. This has two downsides: 1) more clicks are needed, 2) the (possibly intended) ZOrder is lost.

    Even Jon Peltier, in a post from 5th May 2009, mentioned that there is no workaround for that.

    I have attempted a solution based on:

    1. Detecting the activation of a chart.
    2. Storing its current ZOrder for later use.
    3. Bringing it to front.
    4. After deselecting the chart, restoring its original ZOrder.

    This is the basic idea, and the scheme works fairly well, with a few glitches. I have actually based my code on the page by Jon Peltier quoted here by brettdj. One of the modifications is

    Private Sub EvtChart_Activate()
        Application.EnableEvents = False
        ActivatedChart = EvtChart.name
        If (TypeName(EvtChart.Parent) = "ChartObject") Then
        ' Chart is in a worksheet
          Dim chObj As ChartObject
          Set chObj = EvtChart.Parent
          chObj.BringToFront
        Else
        ' Chart is in its own sheet
        End If
        Application.EnableEvents = True
    End Sub
    

    Use something similar for EvtChart_Deactivate. I hope that the idea is useful.

    0 讨论(0)
  • 2020-12-18 11:12

    Create a handler in the worksheet:

    Public Sub ChartSelected(ByVal Name As String)
      Me.ChartObjects(Name).BringToFront
    End Sub
    

    Right-click the chart and select Assign macro, then type something like

    'Sheet1.ChartSelected "Chart 1"'

    where Chart 1 is the name of the chart.

    To assign this handler programmatically, use

    ChartObject.OnAction = "'Sheet1.ChartSelected ""Chart 1""'"
    
    0 讨论(0)
提交回复
热议问题