如何检索Excel图表对象中的最大/最小值和位置

时间:2012-10-17 01:45:30

标签: excel-2007

如何检索Excel图表系列集合的最大值和最小值以及图表上的位置?我想计算系列中每个点的标签位置并相应地移动它。

我这样做是为了让它们看起来很好看,万一你的疑惑。如果我只是盲目地移动标签,数字往往会搞砸。我确信我可以在图表的底部有这个数字,但这不是我想要做的。 Chart对象很难用于对象列表事务-a-ma-jig(当你在对象名称之后命中一段时间​​时弹出的那个问题)。< / p>

编辑:我想要实现的是检索特定系列excel图表的最高(最高)和最低(最低)值。我也想在图表上找到自己的位置(从顶部或左侧)。我知道要查看哪种方式,但是如果你给代码检查哪种方法可以获得奖励。见下图。

   -------------------Left------------------------------------- >
  |        ________________________________________
  |       |                                        |
  |   225 |----------------------------------------|max (highest)
  |   200 |                                        |
  |   175 |                                        |
  |   150 |            -----                       |
|Top| 125 |           /     \                      |
  |   100 |          /       \                     |
  |    75 |   -------         \                    |
  |    50 |  /                 --------------\     |
  |    25 | /                                 \    |
 \|/    0 |----------------------------------------|min (lowest)
  V       |________________________________________|

3 个答案:

答案 0 :(得分:2)

你根本不需要任何VBA ..我知道你想要什么,我已经创造了它。我会解释你是如何为最大位置做的,因为你做了最小的类似。首先,我们需要找到最大的Y轴标签然后变得容易。

让我们分解为五个步骤:

  1. 公式中的A:确定比例。
  2. 公式中的
  3. B:按比例进行比较。
  4. 公式中的
  5. C:测量间隔。
  6. 公式中的
  7. D:将其缩小。
  8. 公式中的
  9. E:计算最大轴标签。
  10. 好的,这是每个步骤的公式:

    1. = ROUNDDOWN(LOG(MAX(数据)); 1)其中数据代表包含您的值的单元格。
    2. = MAX(数据)/ 10 ^ A)* 1.05
    3. = 0.2 +(B→2)* 0.3 +(B→5)* 0.5
    4. = ROUNDDOWN(B; C)
    5. =(C + d)* 10 ^ A
    6. 我自己使用荷兰语公式,所以我可能会略微翻译错误。除此之外,我向你保证这是有效的。原因是,我已经弄清楚Excel如何“思考”图表。我将尝试解释这是如何工作的。

      基本上,Excel使用三个基本范围:从1到2,从2到5以及从5到10 ..当一个数字高于10时,10将再次被视为1并且你会回到第一个范围。这就是我们首先使用LOG公式确定比例的原因。如果你是新手,请在wiki中查找。

      因此,当我们得到比例时,我们确定它所属的范围。对于这三个范围中的每一个,y轴标签间隔是不同的。因此,我们在第三步计算它们,并在第四步中使用它来向下舍入数字B.第五步简单地将其乘以原始比例。

      然后你去:找到最大的Y轴标签。看图表,应该是一样的。如果你明白了,你也会找到最小的Y轴标签。现在很酷的事情是,您可以非常轻松地计算标签应该去哪里,因为您现在知道网格的大小。

      祝你好运,如果你还有疑问,请告诉我。

      帕特里克

答案 1 :(得分:0)

目前尚不清楚您想要实现的目标,但这是一个访问图表的SeriesPointsLabels的演示。

Sub MoveLabels()
    Dim sh As Worksheet
    Dim oCh As Chart
    Dim oSers As SeriesCollection
    Dim oSer As Series
    Dim oPts As Points
    Dim oPt As Point
    Dim oLbls As DataLabels
    Dim oLbl As DataLabel
    Dim i As Long, pt As Long


    Set sh = ActiveSheet
    Set oCh = sh.ChartObjects("Chart 8").Chart

    ' Series Collection of a chart
    Set oSers = ch.SeriesCollection
    For Each oSer In oSers
        'Labels collection of a series
        Set oLbls = oSer.DataLabels
        For Each oLbl In oLbls
            ' Label Object

        Next

        'Points collection of a series
        Set oPts = oSers.Points
        For Each oPt In oPts
            ' Label Object
            Set oLbl = oPt.DataLabel
        Next
    Next
End Sub

答案 2 :(得分:0)

好吧,经过一些更多的实验(这是VBA的一件事)我得到了它。我的具体案例有两个相互叠加的条形系列。代码相当长,但速度很快。我想我学到了一些关于如何加速vba的过程!

Sub AdjustReportChart()
    'main report chart
    Dim mrc As Chart
    Dim sercol As SeriesCollection
    Dim axe As Axis, ser As series
    Dim poi1 As Point, poi2 As Point
    Dim i As Integer, j As Integer
    'select the chart
    If hwb Is Nothing Then Call SetGlobals
    Set mrc = mws.ChartObjects("Chart 1").Chart
    'delave all the needed vars
    Dim poi1pos As Double, poi1val As Double
    Dim min1 As Integer, max1 As Integer
    Dim poi2pos As Double, poi2val As Double
    Dim min2 As Integer, max2 As Integer
    'get the chart width params
    Dim width As Integer
    width = Int(mrc.PlotArea.InsideWidth)
    Set sercol = mrc.SeriesCollection
    Set axe = mrc.Axes(2, sercol(1).AxisGroup)
    min1 = axe.MinimumScale
    max1 = axe.MaximumScale
    Set axe = mrc.Axes(2, sercol(2).AxisGroup)
    min2 = axe.MinimumScale
    max2 = axe.MaximumScale
    'start adjusting. 
    For j = 1 To sercol(1).points.Count
        Set poi1 = sercol(1).points(j)
        Set poi2 = sercol(2).points(j)
        poi1pos = poi1.DataLabel.Left
        poi2pos = poi2.DataLabel.Left
        poi1val = poi1.DataLabel.Text
        poi2val = poi2.DataLabel.Text
        poi1pos = (poi1val / (max1 - min1) * width - 6) + 142
        poi2pos = (poi2val / (max2 - min2) * width - 6) + 142
        If poi2pos < poi1pos + (Len(Str(poi1val)) * 6) And _
            poi1pos < poi2pos + (Len(Str(poi2val)) * 6) Then
            poi2pos = poi1pos + (Len(Str(poi1val)) * 6)
        End If
        poi1.DataLabel.Left = poi1pos
        poi2.DataLabel.Left = poi2pos
    Next j
End Sub