Vba 快到几十年了
我有一张图表,上面有一些数据,y轴是线性的,x轴是对数的。问题是关于对数(x-)轴 我希望x轴上的对数刻度与精确的十年(10的幂)对齐,但我不希望轴必须从精确的十年开始;我希望它从我的数据开始的地方开始。例如,轴可以从3开始;但第一个大刻度应该是10。我该怎么做 当前,当我将轴设置为从3开始时,主网格线为3,这是不好的 当我设置以下属性时,网格和刻度都很好,但这是因为我强制轴从十年开始(我不想这样做) 这就是它的外观:很好的网格,但轴没有从正确的位置开始 现在,当我没有具体地把轴的最小值和最大值绕十圈Vba 快到几十年了,vba,excel,charts,Vba,Excel,Charts,我有一张图表,上面有一些数据,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精确生成您要求的图形:
现在,为了实现自动化…不幸的是,我现在没有时间生成执行此操作所需的“清理”版本的代码(当您将上述内容记录为宏时,它会生成通常的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