1

Я пытаюсь заставить макрос работать с диаграммой на листе, используя Диаграмму.Событие BeforeDoubleClick.

Мне удалось использовать событие BeforeDoubleClick (без использования модулей классов) в отдельном графике. Но я бы хотел, чтобы он работал в диаграмме, встроенной как объект в лист. Идея состоит в том, чтобы затем повторить это для нескольких диаграмм в пределах одного рабочего листа.

Следуя совету в этой книге (стр. 172-3), я сделал следующее:

  1. Создана новая рабочая тетрадь. В лист Sheet1 добавлено 2 столбца случайных данных и добавлена диаграмма рассеяния на том же листе рядом с данными.

  2. Вставлен модуль класса с именем "cl_ChartEvents" с кодом:

    Public WithEvents myChartClass As Chart
    
  3. Создан стандартный модуль с кодом:

    Dim myClassModule As New cl_ChartEvents
    Sub InitializeChart()
    Set myClassModule.myChartClass = _ 
    Worksheets("Sheet1").ChartObjects(1).Chart
    End Sub
    
  4. В редакторе VBA дважды щелкните объект «Sheet1 (Sheet1)» и вставьте код:

    Private Sub MyChartClass_BeforeDoubleClick(ByVal ElementID As Long, _
        ByVal Arg1 As Long, ByVal Arg2 As Long, Cancel As Boolean)
    
    Select Case ElementID
        Case xlLegend
            Me.HasLegend = False
            Cancel = True
        Case xlAxis
            Me.HasLegend = True
            Cancel = True
        End Select
    End Sub  
    
  5. Нажмите Run и запустите макрос InitializeChart.

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

Я сделал свою домашнюю работу онлайн, просматривая форумы и т.д., Но не смог найти другого намека на то, как можно реализовать событие BeforeDoubleClick для работы с диаграммой в обычном рабочем листе. Подход в книге, кажется, указывает, что это выполнимо все же.

Любая помощь будет оценена! Заставить это работать помогло бы многим другим с подобными вопросами, которые я видел в сети. Спасибо.

1 ответ1

2

Уверен, ваш код в элементе № 4 списка должен быть в модуле класса для myChartClass а не в коде Sheet1 .

РЕДАКТИРОВАТЬ (для устранения ошибки «элемент не найден»): Изменить код шага 4, чтобы:

Private Sub MyChartClass_BeforeDoubleClick(ByVal ElementID As Long, _
    ByVal Arg1 As Long, ByVal Arg2 As Long, Cancel As Boolean)

    Select Case ElementID
    Case xlLegend
        Me.MyChartClass.HasLegend = False
        Cancel = True
    Case xlAxis
        Me.MyChartClass.HasLegend = True
        Cancel = True
    End Select
End Sub

Единственным изменением является вставка MyChartClass между Me и HasLegend в двух местах, где они происходят.

Почему это работает: Me относится к экземпляру содержащего модуля класса, cl_ChartEvents , который не является тем, что было привязано к интересующей диаграмме. Объект MyChartClass - это то, что связано с Chart . (Лучшее имя для MyChartClass , вероятно, будет MyChartObj , или что-то.) Итак, нужно углубиться в Me.MyChartClass для того, чтобы манипулировать связанной Chart .

РЕДАКТИРОВАТЬ 2 (чтобы предоставить код для применения пользовательской обработки событий к каждой диаграмме в рабочей книге): замените код шага 3 следующим:

Dim ChartColl As New Collection

Sub LinkCharts()
    Dim workCls As cl_ChartEvents
    Dim ws As Worksheet
    Dim ch As Chart, chob As ChartObject

    ' Link all standalone charts
    For Each ch In ActiveWorkbook.Charts
        ' Must create a new instance of the class for each chart
        Set workCls = New cl_ChartEvents
        ' Link each chart to the myChartClass member of the new class instance
        Set workCls.myChartClass = ch
        ' Add the new instance of the class into the Collection object
        ChartColl.Add workCls
    Next ch

    ' Link all charts in objects in sheets
    For Each ws In ActiveWorkbook.Worksheets
        For Each chob In ws.ChartObjects
            Set workCls = New cl_ChartEvents
            Set workCls.myChartClass = chob.Chart
            ChartColl.Add workCls
        Next chob
    Next ws
End Sub

Sub UnlinkCharts()
    ' Removing the cl_ChartEvents instances from the Collection causes 
    '  causes them to be destroyed by garbage collection
    Do Until ChartColl.Count = 0
        ChartColl.Remove 1
    Loop
End Sub

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .