Поймать событие на графике клика - PullRequest
4 голосов
/ 15 сентября 2011

Мне нужно перехватить событие в Excel VBA, когда я нажимаю на график.

Я хочу вывести график на передний план, когда он активирован, но я не могу найти подходящее событие.

Для диаграммы, отсутствующей на листе (отдельная, полноэкранная диаграмма), существует событие Chart_Activate().

Как можно вызвать одно и то же событие, когда диаграмма находится на определенном листе?

Ответы [ 4 ]

3 голосов
/ 16 сентября 2011

Если у вас есть набор диаграмм для автоматизации, либо на отдельных листах, либо во всей книге, я бы предложил использовать модуль классов для записи, а не для привязки кодовой диаграммы к диаграмме

Джон Пельтье (как обычно) подробно рассмотрел этот код кода, см. События диаграммы в Microsoft Excel .

В модуле класса CEventChart поместите:

Option Explicit
' Declare object of type "Chart" with events
Public WithEvents EvtChart As Chart    

Private Sub EvtChart_Activate()
EvtChart.ChartObjects msoBringToFront
End Sub

В обычном модуле поместите

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

, затем запустите Set_All_Charts с выбранным листом, на который вы хотите, чтобы ваши диаграммы отправлялись вперед, Джон использует эти события листа, чтобы установить и отключить код диаграммы наконкретный лист

Private Sub Worksheet_Activate()
    Set_All_Charts
End Sub

Private Sub Worksheet_Deactivate()
    Reset_All_Charts
End Sub
1 голос
/ 23 августа 2013

Если я понял вопрос, я столкнулся с той же проблемой.Когда есть несколько перекрывающихся диаграмм, их приоритет визуализации следует за ZOrder.

В Excel 2003, когда кто-то выбирал диаграмму, он выходил на передний план (по крайней мере, для визуализации я не знаю, является ли ее ZOrder был временно изменен).Когда диаграмма была отменена, ее приоритет визуализации вернулся к «обычному».

Начиная с Excel 2007, диаграммы временно не выходят на передний план для визуализации при выборе, поэтому, если они скрыты за другими диаграммами (или, возможно, другимиShape s), единственная возможность увидеть их полностью - вывести их на передний план.Это имеет два недостатка: 1) нужно больше кликов, 2) (возможно, намеревается) ZOrder потеряно.

Четный Джон Пельтье , в сообщение от 5 мая 2009 , в котором упоминается, что для этого нет обходного пути.

Я пытался найти решение, основанное на:

  1. Обнаружении активации диаграммы.
  2. Сохранение его текущего ZOrder для последующего использования.
  3. Вывод его на передний план.
  4. После отмены выбора диаграммы, восстановление ее исходного ZOrder.

Это основная идея, и схема работает довольно хорошо , с несколькими глюками.Я фактически основал свой код на странице Джона Пельтье , цитируемой здесь brettdj.Одна из модификаций:

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

Используйте нечто подобное для EvtChart_Deactivate.Я надеюсь, что идея полезна.

0 голосов
/ 18 июля 2015

очень легко.Поместите эту процедуру VBA в обычный модуль кода:

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

Назначьте макрос ClickChart для всех диаграмм, для которых вы хотите иметь такое поведение.

Когда вы нажимаете на любую из диаграмм, онаперемещается перед всеми остальными на листе.

После публикации я вижу, что @timwilliams предложил это в комментарии к другому ответу.

0 голосов
/ 15 сентября 2011

Создайте обработчик на листе:

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

Щелкните правой кнопкой мыши диаграмму и выберите Назначить макрос, затем введите что-то вроде

'Sheet1.ChartSelected "Chart 1"'

где Chart 1 - имя диаграммы.

Чтобы назначить этот обработчик программно, используйте

ChartObject.OnAction = "'Sheet1.ChartSelected ""Chart 1""'"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...