Excel VBA图表-如果包含“括号”,则将图形标签设置为红色?

Excel VBA图表-如果包含“括号”,则将图形标签设置为红色?,excel,vba,Excel,Vba,[更新]:问题末尾使用的最终代码 我的问题涉及使用VBA在Microsoft Excel中自定义图形 如果标签包含括号,我试图将图表的标签颜色自定义为红色,否则设置为黑色。 找到下面的图表作为参考,它有4个标签。 预期结果如下所示: Sub Labels_graph_Test() Dim Qrts As Series Set ChtObj = ActiveSheet.ChartObjects("Q_Graph") Set Qrts = ChtObj.Chart.SeriesCo

[更新]:问题末尾使用的最终代码

我的问题涉及使用VBA在Microsoft Excel中自定义图形

如果标签包含括号,我试图将图表的标签颜色自定义为红色,否则设置为黑色。 找到下面的图表作为参考,它有4个标签。

预期结果如下所示:

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 Qrts.Points(i).DataLabel
      If InStr(1, currentcell, "(*") Then
        .Font.Color = vbRed
      Else
        .Font.Color = vbBlack
      End If
    End With
If Left$(.Text, 1) = "(" Then
到目前为止,我所获得的代码是基于其他示例的,但没有达到我的目标

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
此代码不起作用,并给出编译错误:End if WITH block if

请不要告诉我使用条件格式,因为在这种情况下,标签来自单元格,因此条件格式不起作用

非常感谢你

如果有什么不清楚,请告诉我

致以最良好的祝愿, 马蒂姆平托

最终代码:

要了解更多信息,请查看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
有两个三个问题:根据评论

因为在同一行上有文本,所以If语句被视为一行,而不需要End If。因此,代码中有一个结束If,而没有相应的If。有关示例,请参见

有一个With没有相应的End With

您的currentcell未声明,因此不包含任何值。您正在查找datalabel的文本。由于您已经在Datalabel的With循环中,您可以将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

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 Qrts.Points(i).DataLabel
      If InStr(1, currentcell, "(*") Then
        .Font.Color = vbRed
      Else
        .Font.Color = vbBlack
      End If
    End With
If Left$(.Text, 1) = "(" Then
很容易看出,你有两个带块的块,它们的末端不是带块的

另外,您没有正确使用With。我相信我的想法,不要引用我的话,你可能需要做一些额外的研究。它应该是这样的:

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 Qrts.Points(i).DataLabel
      If InStr(1, currentcell, "(*") Then
        .Font.Color = vbRed
      Else
        .Font.Color = vbBlack
      End If
    End With
If Left$(.Text, 1) = "(" Then
请注意,If和Else语句中的语句以句点开头。。这告诉编译器开始在我在With语句中调用的对象的末尾查找这个缩短的函数/方法/属性。i、 e.它将.Font.Color转换为Qtr.Pointsi.DataLabel.Font.Color,这是您要设置为vbBlack或vbRed的

同样,我不能100%确定设置颜色的确切位置-您应该可以很容易地在MS文档中找到该位置,或者使用宏记录器手动设置颜色,并让它告诉您要设置的确切属性。宏记录器作为懒人查找这些属性的方法非常优秀。它不擅长编写漂亮、可读、高效、可维护的代码

currentcell:我最初的假设是,这是模块或整个项目的全局变量,包含您想要查看的任何内容的文本。看来我错了当你假设

我相信您想要用Qrts.Pointsi.DataLabel.Text替换currentcell,这样您就可以查看此特定点的实际标签。但是,这里有一个With语句,所以可以将其缩短为.Text。您的If语句如下所示:

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 Qrts.Points(i).DataLabel
      If InStr(1, currentcell, "(*") Then
        .Font.Color = vbRed
      Else
        .Font.Color = vbBlack
      End If
    End With
If Left$(.Text, 1) = "(" Then
有关重写此If语句的其余部分的详细信息,请参阅另一个思想部分

再一次,我不是100%确定。文本是确切的属性,但是,在我的脑海里,我相信这就是它。如果没有,则可以在VBE的即时窗口中键入ChartObjects.Pointsi.DataLabel。智能感知应该给你所有可能的选项列表。滚动列表,寻找可能的候选人。如果仍然不确定,请在代码运行时执行该操作,直到If语句,然后执行上述过程。如果你继续这样做?在即时窗口中,它将打印您要求的任何内容的值,以便您可以检查它。注意-这只是众多解决方法中的一种,微软文档,谷歌等都是其他选择

另一个想法是:不使用可读性稍差的InStr函数检查字符串的第一个字符是否为左括号,您可以简单地执行以下操作:

If Left$(currentcell, 1) = "(" Then
我不确定性能级别的差异,这可能是非常微小的,但是下一个人在维护代码时所需的精神能量可能会大大降低,从而使代码更易于维护

注意:Left和Left$几乎相同。但是,Left返回需要隐式转换为字符串的变量,以便与进行比较,而Left$返回不需要隐式转换的字符串。它朝着实现它所说和所做的代码走了很长的路


这是我说的,但要简洁得多正如弗里曼所提到的,这是非常简洁明了的。谢谢你的回答。我现在对代码有一个问题,因为标签是对象,我使用的是currentcell,我想它导致的问题是找不到括号。你的观点是什么?只是想澄清一下@Freeman第三点。用文本替换currentcell解决了我面临的问题。谢谢。这是一个多么美妙的解释和建议啊,我把你和Luuklag的答案混合在一起,得到了一个更清晰易懂的代码。然而,我在上面的回答中写到了我面临的问题:所有的标签都被涂上了黑色,因为它找不到括号。我认为需要使用比currentcell更智能的东西。有什么想法吗?@MartimOnFire currentcell。。。我可能错误地认为这是一个全局变量,它包含了您正在查看的任何单元格的内容。我猜不是这样的。。。给我一对,我会的update@MartimOnFire您可以将currentcell替换为。text@MartimOnFire我可以推荐一个名为。这是一个非常活跃的VBE开源外接程序,可以帮助处理缩进等简单的事情,以及Left vs Left$等微妙的事情。在过去的几年里,它真的帮助我提高了编码水平。免责声明:我是一个热情的用户和粉丝,已经提交了足够多的bug报告,偶尔被任命为QA:和功能请求的负责人,甚至还做了一个小的图形调整。@FreeMan很好的推荐,我不知道,我一定会使用它,因为我已经看到使用它会让我受益,避免新手犯错误。关于Left和Left$,这两个建议都有效,另外两个建议在对象方面也不起作用。我非常感谢你的时间和帮助