Vba 快到几十年了

Vba 快到几十年了,vba,excel,charts,Vba,Excel,Charts,我有一张图表,上面有一些数据,y轴是线性的,x轴是对数的。问题是关于对数(x-)轴 我希望x轴上的对数刻度与精确的十年(10的幂)对齐,但我不希望轴必须从精确的十年开始;我希望它从我的数据开始的地方开始。例如,轴可以从3开始;但第一个大刻度应该是10。我该怎么做 当前,当我将轴设置为从3开始时,主网格线为3,这是不好的 当我设置以下属性时,网格和刻度都很好,但这是因为我强制轴从十年开始(我不想这样做) 这就是它的外观:很好的网格,但轴没有从正确的位置开始 现在,当我没有具体地把轴的最小值和最大

我有一张图表,上面有一些数据,y轴是线性的,x轴是对数的。问题是关于对数(x-)轴

我希望x轴上的对数刻度与精确的十年(10的幂)对齐,但我不希望轴必须从精确的十年开始;我希望它从我的数据开始的地方开始。例如,轴可以从3开始;但第一个大刻度应该是10。我该怎么做

当前,当我将轴设置为从3开始时,主网格线为3,这是不好的

当我设置以下属性时,网格和刻度都很好,但这是因为我强制轴从十年开始(我不想这样做)

这就是它的外观:很好的网格,但轴没有从正确的位置开始

现在,当我没有具体地把轴的最小值和最大值绕十圈

' ...
.Chart.Axes(xlCategory).MinimumScale = 0.9 * Cells(DATA_START, 6)
.Chart.Axes(xlCategory).MaximumScale = 1.1 * Cells(DATA_START + n, 6)
看起来是这样的,轴从正确的位置开始,但栅格/刻度看起来很愚蠢:

在本例中,我希望第一个刻度为100,在此之前只有小刻度/网格线

我已经弄明白了,我可以用
.MajorUnit=10
设置两个主刻度之间的乘法因子


我给你一个建议:只需在空工作表上运行此宏。它生成的图表的主要刻度(和网格线)位于
181801800
,但我希望它们位于
1001000

Sub CreateDemoPlot()
    Range("A1:A6") = Application.Transpose(Split("20,40,100,1000,4500,10000", ","))
    Range("B1:B6") = Application.Transpose(Split("-30,-50,-90,-70,-75,-88", ","))
    With ActiveSheet.ChartObjects.Add(Left:=100, Width:=400, Top:=100, Height:=200)
        .Chart.SeriesCollection.NewSeries
        .Chart.ChartType = xlXYScatterLinesNoMarkers
        .Chart.Axes(xlValue).ScaleType = xlLinear
        .Chart.Axes(xlValue).CrossesAt = -1000
        .Chart.Axes(xlCategory).ScaleType = xlScaleLogarithmic
        .Chart.Axes(xlCategory).HasMajorGridlines = True
        .Chart.Axes(xlCategory).HasMinorGridlines = True
        .Chart.Axes(xlCategory).MinimumScale = 0.9 * Cells(1, 1)
        .Chart.Axes(xlCategory).MaximumScale = 1.1 * Cells(6, 1)
        .Chart.Axes(xlCategory).MajorUnit = 10
        .Chart.HasLegend = False

        .Chart.SeriesCollection.NewSeries
        .Chart.SeriesCollection(1).XValues = Range("A1:A6")
        .Chart.SeriesCollection(1).Values = Range("B1:B6")
    End With
End Sub

如果确实要这样做,可以将垂直轴交叉点更改为要开始的值。在这种情况下,我们将从18开始。

我们想去掉左边丑陋的轴,这样你就可以创建一个图表的副本,删除所有内容,删除所有填充颜色,除了下面的图表这样的轴。然后创建一个无边框的白色框,并覆盖原始图表Y轴。请注意,我忘了将线条颜色设置为“否”,并在顶部图表中勾选。

接下来,覆盖透明图表,得到所需内容。要使用VBA自动更新图表,您可以使用
ActiveChart.Axes(xlCategory).CrossesAt=20
,并对叠加图表和基础图表进行所有比例更改

您可能想使用另一个绘图程序,或者只使用您发布的第一个图表,因为它可能不值得您为复杂的图表花费时间。

自动执行此操作的代码:

Sub CreateDemoPlot()
    Dim chart2 As ChartObject
    Dim shape1 As shape

    Range("A1:A6") = Application.Transpose(Split("20,40,100,1000,4500,10000", ","))
    Range("B1:B6") = Application.Transpose(Split("-30,-50,-90,-70,-75,-88", ","))
    Range("D3:K15").Name = "ChartArea" 'Set Chart Area
    With ActiveSheet.ChartObjects.Add(Left:=100, Width:=400, Top:=100, Height:=200)
        .Chart.SeriesCollection.NewSeries
        .Chart.ChartType = xlXYScatterLinesNoMarkers
        .Chart.Axes(xlValue).ScaleType = xlLinear
        .Chart.Axes(xlValue).CrossesAt = -1000
        .Chart.Axes(xlCategory).ScaleType = xlScaleLogarithmic
        .Chart.Axes(xlCategory).HasMajorGridlines = True
        .Chart.Axes(xlCategory).HasMinorGridlines = True
        .Chart.Axes(xlCategory).MinimumScale = 0.9 * Cells(1, 1)
        .Chart.Axes(xlCategory).MaximumScale = 1.1 * Cells(6, 1)
        .Chart.Axes(xlCategory).MajorUnit = 10
        .Chart.HasLegend = False

        .Chart.SeriesCollection.NewSeries
        .Chart.SeriesCollection(1).XValues = Range("A1:A6")
        .Chart.SeriesCollection(1).Values = Range("B1:B6")

        .Chart.Axes(xlCategory).CrossesAt = 18 'Or where ever the actual data starts
        .Chart.Axes(xlCategory).MinimumScale = 10 'Set to 10 instead of the above code

        'position to chart area
        .Top = Range("ChartArea").Top
        .Left = Range("ChartArea").Left
        .Copy

        'create white box
        ActiveSheet.Shapes.AddShape msoShapeRectangle, 50, 50, 45, 200
        Set shape1 = ActiveSheet.Shapes(2)
        shape1.Fill.ForeColor.RGB = RGB(255, 255, 255)
        shape1.Line.ForeColor.RGB = RGB(255, 255, 255)

        'Position whitebox
        shape1.Left = Range("ChartArea").Left
        shape1.Top = Range("ChartArea").Top

        'Paste overlay chart
        ActiveSheet.Paste
        Set chart2 = ActiveSheet.ChartObjects("Chart 3")

        'Position overlay Chart
        chart2.Top = Range("ChartArea").Top
        chart2.Left = Range("ChartArea").Left

        'Clear out overlay chart
        chart2.Chart.Axes(xlValue).Format.Line.Visible = msoFalse
        chart2.Chart.SeriesCollection(1).Format.Line.Visible = msoFalse
        chart2.Chart.PlotArea.Format.Fill.Visible = msoFalse
        chart2.Chart.Axes(xlCategory).Delete
        chart2.Chart.SetElement (msoElementPrimaryValueGridLinesNone)
        chart2.Chart.SetElement (msoElementPrimaryCategoryGridLinesNone)
        chart2.Chart.ChartArea.Format.Fill.Visible = msoFalse

        'Adjust Y axis position from overlay chart
        chart2.Chart.PlotArea.Left = 10
        chart2.Chart.PlotArea.Top = 0
    End With
End Sub

我相信我能够通过以下奇怪的步骤,诱使Excel精确生成您要求的图形:

  • 创建具有所需限制的日志图
  • 关闭垂直轴网线
  • 使用所需网格线的值(例如70、80、90、100、200、300等)创建一个新数组
  • 绘制第二个系列,其中所需网格值为X,图形的负极限为Y(所有网格值相同)
  • 此系列不使用标记,也不使用线条
  • 为Y添加误差条-仅在正方向上,其值等于Y轴的总范围(最大-最小)
  • 向序列添加数据标签,仅表示X值
  • 将标签移到点下方
  • 结果:

    这是一个对数图;标签正确;“网格线”是正确的。很漂亮


    现在,为了实现自动化…不幸的是,我现在没有时间生成执行此操作所需的“清理”版本的代码(当您将上述内容记录为宏时,它会生成通常的Excel混乱…),但是,如果您按照上面的说明手动执行此操作,则确实会得到所示的精确绘图。

    运行SSCCE代码(Excel 2010)时出错。第一个示例中,您明确将轴min和max绕十年,这有什么问题?你为什么不想那样做?这或多或少是我会做的(尽管可以做得更优雅)@AndiMohr:SSCCE在Excel 2010中运行良好。你也试过你自己的建议吗<代码>?Int(-188/10)*10@AndiMohr:当然,但那只是虚拟数据!这在一般情况下是行不通的。你是否希望OP在每次单元格内容改变时都编辑他的代码?@Jean-FrançoisCorbett是的,这基本上就是我目前正在做的。问题是,我不希望轴从精确的十年开始,我只希望那里有刻度和网格。例如,轴可以从
    3
    开始,第一个勾号标签是
    10
    (这也是主网格线的位置)。但是当我将轴设置为从
    3
    开始时,主网格线位于
    3
    …啊哈,明白了。我编辑了你的问题以澄清你的要求。结果正是我想要的。你能提供代码吗?它需要以编程的方式完成(最好是调整我的SSCCE,并在底部的答案中发布代码)。OP在任何非传统的输出设备上渲染时都需要小心,这些设备可能会意外地处理矩形和隐藏文本。虽然我真的不喜欢你的答案的工作方式(只是在旧的轴上画一个新的轴),但这是我得到的最佳答案。不过我不会用它。相反,我将以十年开始x轴,并适当地诅咒Excel不能做这样的事情事实上,我从来没有想过使用Excel/VBA宏做任何事情,更不用说图形了。不幸的是,不能总是选择(特别是如果客户不知道VBA以外的任何东西)。我完全相信我能说服客户VBA可能不是这里的最佳解决方案谢谢你的努力。虽然我喜欢这个想法,但它不会区分次要网格线和主要网格线。而且,我不喜欢把它拼凑在一起,我一直在寻找一条好的出路。与Excel非常不同。您可以创建两个系列(一个在次要网格,一个在主要网格)和se
    Sub CreateDemoPlot()
        Dim chart2 As ChartObject
        Dim shape1 As shape
    
        Range("A1:A6") = Application.Transpose(Split("20,40,100,1000,4500,10000", ","))
        Range("B1:B6") = Application.Transpose(Split("-30,-50,-90,-70,-75,-88", ","))
        Range("D3:K15").Name = "ChartArea" 'Set Chart Area
        With ActiveSheet.ChartObjects.Add(Left:=100, Width:=400, Top:=100, Height:=200)
            .Chart.SeriesCollection.NewSeries
            .Chart.ChartType = xlXYScatterLinesNoMarkers
            .Chart.Axes(xlValue).ScaleType = xlLinear
            .Chart.Axes(xlValue).CrossesAt = -1000
            .Chart.Axes(xlCategory).ScaleType = xlScaleLogarithmic
            .Chart.Axes(xlCategory).HasMajorGridlines = True
            .Chart.Axes(xlCategory).HasMinorGridlines = True
            .Chart.Axes(xlCategory).MinimumScale = 0.9 * Cells(1, 1)
            .Chart.Axes(xlCategory).MaximumScale = 1.1 * Cells(6, 1)
            .Chart.Axes(xlCategory).MajorUnit = 10
            .Chart.HasLegend = False
    
            .Chart.SeriesCollection.NewSeries
            .Chart.SeriesCollection(1).XValues = Range("A1:A6")
            .Chart.SeriesCollection(1).Values = Range("B1:B6")
    
            .Chart.Axes(xlCategory).CrossesAt = 18 'Or where ever the actual data starts
            .Chart.Axes(xlCategory).MinimumScale = 10 'Set to 10 instead of the above code
    
            'position to chart area
            .Top = Range("ChartArea").Top
            .Left = Range("ChartArea").Left
            .Copy
    
            'create white box
            ActiveSheet.Shapes.AddShape msoShapeRectangle, 50, 50, 45, 200
            Set shape1 = ActiveSheet.Shapes(2)
            shape1.Fill.ForeColor.RGB = RGB(255, 255, 255)
            shape1.Line.ForeColor.RGB = RGB(255, 255, 255)
    
            'Position whitebox
            shape1.Left = Range("ChartArea").Left
            shape1.Top = Range("ChartArea").Top
    
            'Paste overlay chart
            ActiveSheet.Paste
            Set chart2 = ActiveSheet.ChartObjects("Chart 3")
    
            'Position overlay Chart
            chart2.Top = Range("ChartArea").Top
            chart2.Left = Range("ChartArea").Left
    
            'Clear out overlay chart
            chart2.Chart.Axes(xlValue).Format.Line.Visible = msoFalse
            chart2.Chart.SeriesCollection(1).Format.Line.Visible = msoFalse
            chart2.Chart.PlotArea.Format.Fill.Visible = msoFalse
            chart2.Chart.Axes(xlCategory).Delete
            chart2.Chart.SetElement (msoElementPrimaryValueGridLinesNone)
            chart2.Chart.SetElement (msoElementPrimaryCategoryGridLinesNone)
            chart2.Chart.ChartArea.Format.Fill.Visible = msoFalse
    
            'Adjust Y axis position from overlay chart
            chart2.Chart.PlotArea.Left = 10
            chart2.Chart.PlotArea.Top = 0
        End With
    End Sub