Excel VBA Chart - установить метки на графике на красный, если они содержат «круглые скобки»? - PullRequest
0 голосов
/ 26 апреля 2019

[обновление]: окончательный код, использованный в конце моего вопроса.

Моя проблема связана с настройкой графиков в Microsoft Excel с использованием VBA.

Я пытаюсь настроить цвета метки моего графика на красный цвет, если метка содержит круглые скобки и , установленные на черный, в противном случае .Найдите график ниже для справки (он имеет 4 метки).graph

Нужный результат будет выглядеть следующим образом:

graph

Код, который я до сих пор достиг, основан на других примерах, но не достигнув моей цели.

Sub Labels_graph_Test()

Dim Qrts As Series

Set ChtObj = ActiveSheet.ChartObjects("Q_Graph")
Set Qrts = ChtObj.Chart.SeriesCollection(1)

For i = 1 To 4

     With Qrts.Points(i).DataLabel

     If InStr(1, currentcell, "(*") Then With Selection.Font.Color = vbRed
     Else: Selection.Font.Color = vbBlack

     End If   

Next i

End Sub

Этот код не работает и выдает "Ошибка компиляции: Завершить без блокировки, если".

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

Большое спасибо заранее

Дайте мне знать, если что-то не понятно

С наилучшими пожеланиями, Мартим Пинто

Финальный код:

(для получения дополнительной информации проверьте ответ Luuklag и FreeMan - оба дали очень полезные идеи и объяснения)

Sub Labels_graph_Test()

Dim Qrts As Series

Set ChtObj = ActiveSheet.ChartObjects("Q_Graph")
Set Qrts = ChtObj.Chart.SeriesCollection(1)

    For i = 1 To 4
        With Qrts.Points(i).DataLabel

            If Left(.Text, 1) = "(" Then
                .Font.Color = vbRed
            Else
                .Font.Color = vbBlack
            End If
        End With
    Next i

End Sub

Ответы [ 2 ]

4 голосов
/ 26 апреля 2019

Ваше форматирование в цикле For делает очень трудным для чтения и, следовательно, очень простым , чтобы испортить.

Если вы исправитеОтступы вот так:

Sub Labels_graph_Test()

  Dim Qrts As Series

  Set ChtObj = ActiveSheet.ChartObjects("Q_Graph")
  Set Qrts = ChtObj.Chart.SeriesCollection(1)

  For i = 1 To 4

    With Qrts.Points(i).DataLabel
      If InStr(1, currentcell, "(*") Then
        With Selection.Font.Color = vbRed
      Else
        Selection.Font.Color = vbBlack
      End If

  Next i

End Sub

Действительно легко увидеть, что у вас есть два блока With, которые не закрыты с End With.

Кроме того, вы не используете With правильно.Я верю (изо всех сил, не цитируйте меня об этом, возможно, вам придется провести дополнительное исследование).что это должно выглядеть примерно так:

    With Qrts.Points(i).DataLabel
      If InStr(1, currentcell, "(*") Then
        .Font.Color = vbRed
      Else
        .Font.Color = vbBlack
      End If
    End With

Обратите внимание, что оператор в операторах If и Else начинается с точки (.).Это говорит компилятору «начать поиск этой сокращенной функции / метода / свойства в конце объекта, который я вызывал в этом операторе With там».то есть он переведет .Font.Color в Qtr.Points(i).DataLabel.Font.Color, что вы хотите установить в vbBlack или vbRed.

Опять же , я не уверен на 100%, что это именно то место, куда можно перейти, чтобы установить цвета - вы должны найти его довольно легко здесь, на SO, вMS Docs, или с помощью макро-рекордера, чтобы установить цвет вручную и позволить ему сказать вам точное свойство для установки.(Macro Recorder отлично как способ поиска этих свойств ленивым человеком. Он отстой при написании красивого, удобочитаемого, эффективного и удобного в обслуживании кода.)

currentcell: мое первоначальное предположение заключалось в том, что это была глобальная переменная для модуля или всего проекта, который содержал текст того, на что вы хотели посмотреть.Кажется, я ошибся (это то, что происходит, когда вы предполагаете) ...

Я считаю, что то, что вы хотите заменить currentcell, будет Qrts.Points(i).DataLabel.Text, так что вы можете посмотреть на фактический ярлык для этой конкретной точки.,Однако у вас есть это With утверждение, так что вы можете сократить его до .Text.Ваше утверждение If будет выглядеть так:

If Left$(.Text, 1) = "(" Then

см. Раздел «Другая мысль» для получения полной информации об остальной части переписывания этого оператора If.

Опять же, я не уверен на 100%, что .Text - это точное свойство, но, веря в голову, я верю, что это так.Если нет, в Immediate Window VBE вы можете ввести ChartObjects.Points(i).DataLabel., и IntelliSense должен предоставить вам список всех возможных опций.Прокрутите список в поисках вероятных кандидатов.Если вы все еще не уверены, сделайте это во время выполнения кода (перейдите к оператору If, затем выполните описанный выше процесс).Если вы продолжите это с ? в «Немедленном окне», оно напечатает значение того, о чем вы просите, чтобы вы могли проверить его.Обратите внимание - это лишь один из множества способов выяснить это (MS Docs, SO, Google и т. Д. И другие варианты).

Еще одна мысль: вместо использования несколько менее читаемой функции InStrчтобы проверить, является ли первый символ строки левосторонним, вы можете просто сделать:

If Left$(currentcell, 1) = "(" Then

Я не уверен в разнице уровней производительности, и это, вероятно, довольно маленькая, ноумственная энергия, необходимая следующему человеку для поддержания этого кода (возможно, будущего вас), будет намного ниже, поэтому более поддерживаемый код.

NB: Left и Left$ почти идентичны.Однако Left возвращает вариант, который должен быть неявно приведен к string для сравнения с "(", в то время как Left$ возвращает string, который не нуждается в неявном приведении.код, который «делает то, что говорит, и говорит, что делает».

2 голосов
/ 26 апреля 2019

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *} * * *}}}}}}}считается однострочным, и для этого не требуется End If.Следовательно, в вашем коде есть End If без соответствующего If.См. Для примера Документы Microsoft

Существует With, для которого нет соответствующего End With.

Ваша текущая ячейка не объявлена ​​и, следовательно, не имеет значения.Вы ищете текст метки данных.Поскольку вы уже находитесь в цикле With для своей Datalabel, вы можете заменить currentcell на .Text для ссылки на текстовое значение текущей Datalabel.

Ваш код должен выглядеть следующим образомчто-то вроде: (не проверено)

For i = 1 To 4

     With Qrts.Points(i).DataLabel

         If InStr(1, currentcell, "(*") Then 
             .Font.Color = vbRed
         Else 
             .Font.Color = vbBlack
         End If   
     End With
Next i
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...