不知怎么的,我无法让我的图表“堆叠”。由于下面解释的原因,我首先在一个名为“ChartsGeneral”的宏中准备了一个标准图表。根据我的“图表”工作表上的一些设置,它会调用特定的第二个宏,例如“图表构建状态”。在第二个宏中,我生成类别和数据系列,并根据需要调整标准图表的设置。
当我尝试通过“createInstance(“com.sun.star.chart.StackableDiagram”)”获取堆叠图表时,没有任何变化。我研究了文档和几个论坛,但我不知道我错过了什么。下面的代码。
配置详情 版本:7.4.3.2 (x64) / LibreOffice 社区
CPU 线程数:12;操作系统:Windows 10.0 Build 19045;语言环境:nl-NL (nl_NL);用户界面:en-US
好的,开始了……请怜悯一个可怜的老非程序员书呆子。
背景 多年来,我为个人财务收集了大量带有 VBA 宏的 Excel 电子表格。今年我决定将它们全部迁移到 LibreOffice,作为我从 Windows 到 Linux 的更广泛迁移的一部分。我不是程序员,所以我决定使用 BASIC,因为它最接近 VBA。
我的一个电子表格跟踪我们的房屋抵押贷款进度。我跟踪所有利息和本金的支付。由于我们通过固定的每月还款额和“滚雪球”(所有储蓄都作为本金的付款返还给本金)支付额外首付,电子表格还计算预期的下一次滚雪球付款,以及对剩余抵押贷款的预测。一切正常。
我的抵押贷款电子表格中的关键工作表是“月份”,我在其中存储过去付款的所有数据,以及“预测”,其中包含“月份”的副本以及未来每个月的预测。
我现在进入最后一个功能块:报告。这主要是一组图表,根据 Months and Prognosis 中的数据显示我的抵押贷款的历史、当前状态和预测。为此,我在我的电子表格中使用了一个名为“图表”的专用工作表。在这里,我可以从下拉列表中选择图表类型,以及一些日期或期间相关的设置(我为此使用命名字段)。请参阅下面的部分屏幕截图。
当我按下图表工作表上的“更新图表”按钮时,会触发一个名为“ChartsGeneral”的宏。在这个宏中:
ChartsGeneral 的代码可以在下面找到
Sub ChartsGeneral()
'Manages the Charts worksheet
'Set Worksheets
wshC = ThisComponent.Sheets.getByName("Charts")
wshM = ThisComponent.Sheets.getByName("Months")
wshP = ThisComponent.Sheets.getByName("Prognosis")
wshS = ThisComponent.Sheets.getByName("Settings")
'Define Colours
cBlack = RGB(0, 0, 0)
cGray01 = RGB(50, 50, 50)
cGray02 = RGB(191, 191, 191)
cWhite = RGB(255, 255, 255)
cDarkRed = RGB(192, 0, 0)
cPinkiDEAL = RGB(204, 0, 102) 'iDeal
cGreenCash = RGB(112, 173, 71) 'Cash Green
cBluePin = RGB(41, 65, 113) 'PIN Blue
cBlueContactless = RGB(58, 125, 193) 'Contactloos Light Blue
cOrangeVisa = RGB(246, 155, 14) 'Visa Orange
'Set Parameters
'Prognosis
ColumnOriginal = 18 'Original Rest Mortgage
ColumnRest = 17 'Actual Rest Mortgae
ColumnPaid = 16 'Reeds afgelost
ColumnPrognosis = 21 'Prognosis Rest Mortgage
ColumnInterestSavedPrognosis = 23 'Bespaarde rente prognose
ColumnInterestSaved = 26 'Bespaarde rente
ColumnExtraTotal = 14 'Column total extra cumulative
ColumnPercent = 24
ColumnPercentPrognosis = 25
'Months
XASColumn = 2
ColumnExtra = 13 'Extra repayment column
ColumnRegular = 12 'Regular repayment column
ColumnInterest = 11 'Interest payment column
ColumnMonthInterest = 3 'Interest payment column
ColumnMonthRegular = 4 'Regular repayment column
ColumnMonthTotal = 9 'Total Monthly repayment column
ColumnSnowball = 7 'Snowball per month column
ColumnWOZ = 17 'WOZ column
ColumnMortgage = 16 'Rest of mortgage column
ColumnVasteLasten = 5 'Regular Interest and Depreciation
ColumnLTV = 21 'LTV Ratio
ColumnPercentageRest = 24 'Percentage Rest Mortgage Paid This Month
ColumnWOZpercentage = 22 'WOZ percentage column
ColumnMortgagePercentage = 26 'Rest of mortgage percentage column
'X-As Values
LastMonthRow = getLastContentIndex("Months", 3)
If wshM.getCellByPosition(1, LastMonthRow).Value = (ThisComponent.NamedRanges.getByName("ChartMonth").getReferredCells.Value + 1) Then
LastMonthRow = LastMonthRow - 1
End If
LastMonth = wshM.getCellByPosition(1, LastMonthRow).Value
LastYear = wshM.getCellByPosition(0, LastMonthRow).Value
xStartRow = 3
xEndRow = LastMonthRow
If ThisComponent.NamedRanges.getByName("ChartPeriod").getReferredCells.String = "1Y" Then
StartYear = LastYear - 1
StartMonth = LastMonth + 1
If StartMonth = 13 Then
StartYear = StartYear + 1
StartMonth = 1
End If
For i = xStartRow To LastMonthRow
If wshM.getCellByPosition(0, i).Value = StartYear And wshM.getCellByPosition(1, i).Value = StartMonth Then
xStartRow = i
Exit For
End If
Next i
End If
If ThisComponent.NamedRanges.getByName("ChartPeriod").getReferredCells.String = "2Y" Then
StartYear = LastYear - 2
StartMonth = LastMonth + 1
If StartMonth = 13 Then
StartYear = StartYear + 1
StartMonth = 1
End If
For i = xStartRow To LastMonthRow
If wshM.getCellByPosition(0, i).Value = StartYear And wshM.getCellByPosition(1, i).Value = StartMonth Then
xStartRow = i
Exit For
End If
Next i
End If
If ThisComponent.NamedRanges.getByName("ChartPeriod").getReferredCells.String = "3Y" Then
StartYear = LastYear - 3
StartMonth = LastMonth + 1
If StartMonth = 13 Then
StartYear = StartYear + 1
StartMonth = 1
End If
For i = xStartRow To LastMonthRow
If wshM.getCellByPosition(0, i).Value = StartYear And wshM.getCellByPosition(1, i).Value = StartMonth Then
xStartRow = i
Exit For
End If
Next i
End If
If ThisComponent.NamedRanges.getByName("ChartPeriod").getReferredCells.String = "5Y" Then
StartYear = LastYear - 5
StartMonth = LastMonth + 1
If StartMonth = 13 Then
StartYear = StartYear + 1
StartMonth = 1
End If
For i = xStartRow To LastMonthRow
If wshM.getCellByPosition(0, i).Value = StartYear And wshM.getCellByPosition(1, i).Value = StartMonth Then
xStartRow = i
Exit For
End If
Next i
End If
If ThisComponent.NamedRanges.getByName("ChartPeriod").getReferredCells.String = "10Y" Then
StartYear = LastYear - 10
StartMonth = LastMonth + 1
If StartMonth = 13 Then
StartYear = StartYear + 1
StartMonth = 1
End If
For i = xStartRow To LastMonthRow
If wshM.getCellByPosition(0, i).Value = StartYear And wshM.getCellByPosition(1, i).Value = StartMonth Then
xStartRow = i
Exit For
End If
Next i
End If
If ThisComponent.NamedRanges.getByName("ChartPeriod").getReferredCells.String = "15Y" Then
StartYear = LastYear - 15
StartMonth = LastMonth + 1
If StartMonth = 13 Then
StartYear = StartYear + 1
StartMonth = 1
End If
For i = xStartRow To LastMonthRow
If wshM.getCellByPosition(0, i).Value = StartYear And wshM.getCellByPosition(1, i).Value = StartMonth Then
xStartRow = i
Exit For
End If
Next i
End If
If ThisComponent.NamedRanges.getByName("ChartPeriod").getReferredCells.String = "20Y" Then
StartYear = LastYear - 20
StartMonth = LastMonth + 1
If StartMonth = 13 Then
StartYear = StartYear + 1
StartMonth = 1
End If
For i = xStartRow To LastMonthRow
If wshM.getCellByPosition(0, i).Value = StartYear And wshM.getCellByPosition(1, i).Value = StartMonth Then
xStartRow = i
Exit For
End If
Next i
End If
'Global Variable for BlogMarkers
ChartStartRow = StartRow
'Generate New Chart
oCharts = wshC.Charts
If oCharts.Count <> 0 then
For i = 0 to oCharts.Count-1
oChart = oCharts.getByIndex(i)
If oChart.name = "AdminChart" then
oCharts.removeByName("AdminChart")
End If
Next i
End If
Dim oRange as Object
Dim oRangeAddress(1) As New com.sun.star.table.CellRangeAddress
Dim oRect As New com.sun.star.awt.Rectangle
Dim cTitle as String
'Define Point and Size in order to change Position and Size of Chart Objects
Dim Pos_Chart As New com.sun.star.awt.Point
Dim Pos_Title As New com.sun.star.awt.Point
Dim Pos_SubTitle As New com.sun.star.awt.Point
Dim Pos_xTitle As New com.sun.star.awt.Point
Dim Pos_yTitle As New com.sun.star.awt.Point
Dim Pos_Legend As New com.sun.star.awt.Point
Dim Size_Chart As New com.sun.star.awt.Size
Dim Size_Title As New com.sun.star.awt.Size
Dim Size_SubTitle As New com.sun.star.awt.Size
Dim Size_xTitle As New com.sun.star.awt.Size
Dim Size_yTitle As New com.sun.star.awt.Size
Dim Size_Legend As New com.sun.star.awt.Size
oRange = thisComponent.getCurrentSelection.getRangeAddress
oRect.Width = 34000
oRect.Height = 19500
oRect.X = 8650
oRect.Y = 20
cTitle = "AdminChart"
oCharts.addNewByName(cTitle,oRect,oRangeAddress(), TRUE, TRUE)
oChart = oCharts.getByName(cTitle).embeddedObject
oChart.Diagram = oChart.createInstance("com.sun.star.chart.LineDiagram") 'LineDiagram
oDiagram = oChart.Diagram
'Change position and size of chart area in rectangle
oChart.RefreshAddInAllowed = True
Pos_Chart.X = 700
Pos_Chart.Y = 1600
Size_Chart.Width = oRect.Width - 1500
Size_Chart.Height = oRect.Height - 2500
oDiagram.setPosition( Pos_Chart )
oDiagram.setSize( Size_Chart )
'Title and Subtitle of Chart
'oChart.SplineType = 0
oChart.HasMainTitle = True
oChart.Title.String = cTitle
oChart.Title.CharColor = cBlack
oChart.Title.CharFontName = "Liberation Sans"
oChart.Title.CharHeight = 16 ' Font Size
oChart.Title.CharWeight = 0 ' Bold in %
oChart.Title.CharPosture = 0 ' Italics = 1
oChart.HasSubTitle = False
'oChart.SubTitle.String = "Testing the waters"
'oChart.SubTitle.CharColor = cBlue
'oChart.SubTitle.CharFontName = "Liberation Sans"
'oChart.SubTitle.CharHeight = 12 ' Font Size
'oChart.SubTitle.CharWeight = 100 ' Bold in %
'oChart.SubTitle.CharPosture = 0 ' Italics
'Chart Area colours
oDiagram.Wall.FillStyle = com.sun.star.drawing.FillStyle.SOLID
oDiagram.Wall.FillColor = cWhite 'Chart Area Colour
oDiagram.Wall.LineStyle = com.sun.star.drawing.FillStyle.SOLID
oDiagram.Wall.LineColor = cBlack 'Chart Area Border Colour
oDiagram.Wall.LineWidth = 20
oChart.Area.FillStyle = com.sun.star.drawing.FillStyle.SOLID
oChart.Area.FillColor = cWhite 'Full Area Colour
'Horizontal Major Grid Lines
oDiagram.HasYAxisGrid = True
oDiagram.YMainGrid.LineStyle = com.sun.star.drawing.FillStyle.SOLID
oDiagram.YMainGrid.LineColor = cGray02
oDiagram.YMainGrid.LineWidth = 20
'Vertical Major Grid Lines
oDiagram.HasXAxisGrid = False
oDiagram.XMainGrid.LineStyle = com.sun.star.drawing.FillStyle.SOLID
oDiagram.XMainGrid.LineColor = cGray02
oDiagram.XMainGrid.LineWidth = 20
'X-Axis
oDiagram.HasXAxis = True
oDiagram.HasXAxisDescription = True
oDiagram.HasXAxisTitle = True
oXaxis = oDiagram.getXAxis()
oXaxis.AxisTitle.String = "X-Values"
oXaxis.AxisTitle.CharFontName = "Liberation Sans"
oXaxis.AxisTitle.CharColor = cBlack
oXaxis.AxisTitle.CharHeight = 11 ' Font Size
oXaxis.AxisTitle.CharWeight = 0 ' Bold in %
oXaxis.AxisTitle.CharPosture = 0 ' Italics = 1
oXaxis.AutoMin = True
oXaxis.AutoMax = True
'oXaxis.Min = 1
'oXaxis.Max = 5
oXaxis.CharColor = cBlack
oXaxis.CharFontName = "Liberation Sans"
oXaxis.CharHeight = 10 ' Font Size
oXaxis.CharWeight = 100 ' Bold in %
oXaxis.CharPosture = 0 ' Italics
oXaxis.LineColor = cBlack
oXaxis.LineWidth = 20
'Primary Y-Axis
oDiagram.HasYAxis = True
oDiagram.HasYAxisDescription = True
oDiagram.HasYAxisTitle = False
oDiagram.HasYAxis = True
oYaxis = oDiagram.getYAxis()
oYaxis.AxisTitle.String = "Y-Values"
oYaxis.AxisTitle.CharFontName = "Liberation Sans"
oYaxis.AxisTitle.CharColor = cBlack
oYaxis.AxisTitle.CharHeight = 11 ' Font Size
oYaxis.AxisTitle.CharWeight = 0 ' Bold in %
oYaxis.AxisTitle.CharPosture = 0 ' Italics = 1
oYaxis.AutoMin = False
oYaxis.AutoMax = False
oYaxis.Min = 0
oYaxis.Max = 2000
oYaxis.StepMain = 250
oYaxis.CharColor = cBlack
oYaxis.CharFontName = "Liberation Sans"
oYaxis.CharHeight = 10 ' Font Size
oYaxis.CharWeight = 0 ' Bold in %
oYaxis.CharPosture = 0 ' Italics
oYaxis.LineColor = cBlack
oYaxis.LineWidth = 20
oYaxis.LinkNumberFormatToSource = False
oYaxis.NumberFormat = "114"
oChart.HasLegend = 1
oLegend = oChart.getLegend()
oLegend.AutomaticPosition = True
oLegend.Alignment = com.sun.star.chart.ChartLegendPosition.BOTTOM
oLegend.CharHeight = 10 ' Font Size
oLegend.CharWeight = 0 ' Bold in %
oLegend.CharFontName = "Liberation Sans"
oLegend.FillColor = cWhite
oLegend.LineColor = cWhite
oLegend.CharColor = cBlack
oLegend.CharPosture = 0 'Italics
oDiagram.Lines = True
oDiagram.LineColor = cDarkRed
oDiagram.LineWidth = 20
'oChart.DataSourceLabelsInFirstColumn = True
'oChart.DataSourceLabelsInFirstRow = False
'Call Chart Procedure
If ThisComponent.NamedRanges.getByName("ChartType").getReferredCells.String = "Opbouw Stand van Zaken" Then
cTitle = "Opbouw Eigen Woning " & ThisComponent.NamedRanges.getByName("ChartPeriod").getReferredCells.String
Call ChartBuildStatus(xStartRow, xEndRow, cTitle)
End If
End Sub
调用宏 ChartBuildStatus 后,该宏包含以下操作:
我尝试了很多方法,包括将堆叠代码移到宏的末尾。但我无法让它正常工作。我一定是忽略了某些东西或做了一些非常愚蠢的事情。因此,经过几天的尝试,我将希望寄托在社区上。任何人都可以对此有所了解吗?
Sub ChartBuildStatus(xStartRow As Long, xEndRow As Long, cTitle As String)
'Define Colours
cBlack = RGB(0, 0, 0)
cGray01 = RGB(50, 50, 50)
cGray02 = RGB(191, 191, 191)
cWhite = RGB(255, 255, 255)
wshC = ThisComponent.Sheets.getByName("Charts")
wshM = ThisComponent.Sheets.getByName("Months")
oCharts = wshC.Charts
oChart = oCharts.getByName("AdminChart").embeddedObject
oChart.Diagram = oChart.createInstance("com.sun.star.chart.AreaDiagram")
'Stackable Diagram
oChart.Diagram = oChart.createInstance("com.sun.star.chart.StackableDiagram")
oDiagram = oChart.getDiagram()
oChart.setDiagram(oDiagram)
oDiagram = oChart.getDiagram()
With oDiagram
.Stacked = True
.Percent = False
.Vertical = False
End With
ChartUnit = 50000
'Specific Chart Adjustments
oXaxis = oDiagram.getXAxis()
oYaxis = oDiagram.getYAxis()
'Ymax And Ymin
oYaxis.AutoMax = True
oYaxis.Min = 0
'Chart details
oChart.Title.String = cTitle
oDiagram.HasXAxisTitle = False
oYaxis.AxisTitle.String = "EUR"
oYaxis.StepMain = ChartUnit
oYaxis.NumberFormat = "115" ' #,##0
'Data Series Generator
oDataProvider = oChart.getDataProvider()
oDiagram = oChart.getFirstDiagram()
oCooSys = oDiagram.getCoordinateSystems()
oCoods = oCooSys(0) ' this chart has only a coordinate system
oChartTypes = oCoods.getChartTypes() ' chart type one by one
oChartType = oChartTypes(0)
'Data Ranges
xEndRow = getLastContentIndex ("Months", 3 )
Xrange = "Months.C" & (xStartRow + 1) & ":C" & (xEndRow + 1) 'yyyymm
Y1range = "Months.S" & (xStartRow + 1) & ":S" & (xEndRow + 1) 'Overwaarde
Y2range = "Months.T" & (xStartRow + 1) & ":T" & (xEndRow + 1) 'Eigen Geld
Y3range = "Months.M" & (xStartRow + 1) & ":M" & (xEndRow + 1) 'Reguliere Aflossing
Y4range = "Months.N" & (xStartRow + 1) & ":N" & (xEndRow + 1) 'Extra Aflossing
Y5range = "Months.Q" & (xStartRow + 1) & ":Q" & (xEndRow + 1) 'Restant Hypotheek
'Prepare for Data Series
oDataProvider = oChart.getDataProvider()
oDiagram = oChart.getFirstDiagram()
oCooSys = oDiagram.getCoordinateSystems()
oCoods = oCooSys(0) ' this chart has only a coordinate system
oChartTypes = oCoods.getChartTypes() ' chart type one by one
oChartType = oChartTypes(0)
'X-Axis Data series
dim categorySequence as object, categoryRange as string
dim coordinateSystem as object, axis as object
dim scaleData as new com.sun.star.chart2.ScaleData
categorySequence = CreateUnoService("com.sun.star.chart2.data.LabeledDataSequence")
categorySequence.setValues(CreateDataSequence(oDataProvider, Xrange, "categories"))
coordinateSystem = oDiagram.getCoordinateSystems()(0)
axis = coordinateSystem.getAxisByDimension(0, 0)
scaleData = axis.getScaleData()
scaleData.Categories = categorySequence
axis.setScaleData(scaleData)
'Y-Axis Data series
oDataSeriesList = oChartType.getDataSeries()
Dim oNewDataSeriesList(4) As Object ' new data series
oSeries1 = CreateDataSeries_Chart(oDataProvider, Xrange, Y1range, "Overwaarde")
oSeries1.Color = RGB(197, 224, 180)
oSeries1.LineWidth = 60
oNewDataSeriesList(0) = oSeries1
oSeries2 = CreateDataSeries_Chart(oDataProvider, Xrange, Y2range, "EigenGeld")
oSeries2.Color = RGB(0, 176, 80)
oSeries2.LineWidth = 60
oNewDataSeriesList(1) = oSeries2
oSeries3 = CreateDataSeries_Chart(oDataProvider, Xrange, Y3range, "Aflossing")
oSeries3.Color = RGB(146, 208, 80)
oSeries3.LineWidth = 60
oNewDataSeriesList(2) = oSeries3
oSeries4 = CreateDataSeries_Chart(oDataProvider, Xrange, Y4range, "AflossingExtra")
oSeries4.Color = RGB(255, 215, 0)
oSeries4.LineWidth = 60
oNewDataSeriesList(3) = oSeries4
oSeries5 = CreateDataSeries_Chart(oDataProvider, Xrange, Y5range, "RestHypotheek")
oSeries5.Color = RGB(192, 0, 0)
oSeries5.LineWidth = 60
oNewDataSeriesList(4) = oSeries5
'Update chart (only the charttype is updated)
oChartType.setDataSeries(oNewDataSeriesList)
End Sub
左边是我的 LibreOffice Calc 电子表格中的图表,右边是我希望它根据我当前的 Excel 工作表看起来的图表。
为了完整起见,请在下面找到附加宏的 CreateDataSequence() 和 CreateDataSeries_Chart()。
创建数据序列()
Function CreateDataSequence( oDataProvider As Object, sRangeRepresentation As String, sRole As String ) As Object
Dim oDataSequence As Object
On Error GoTo Handler
' create .chart2.data.DataSequence from range representation
oDataSequence = oDataProvider.createDataSequenceByRangeRepresentation(sRangeRepresentation)
If NOT IsNull(oDataSequence) Then
oDataSequence.Role = sRole
End If
Handler:
CreateDataSequence = oDataSequence
End Function
CreateDataSeries_Chart()
Function CreateDataSeries_Chart( oDataProvider As Object, sXRangeRepresentation As String, sYRangeRepresentation As String, sLabelRangeRepresentation As String ) As Object
Dim oNewDataSeries As Object
oNewDataSeries = CreateUnoService("com.sun.star.chart2.DataSeries")
Dim oData(1) As Object ' x and y: .chart2.data.XLabeledDataSequence
' Y
oDataY = CreateUnoService("com.sun.star.chart2.data.LabeledDataSequence")
oSequenceY = CreateDataSequence(oDataProvider, sYRangeRepresentation, "values-y")
If NOT IsNull(oSequenceY) Then
oDataY.setValues(oSequenceY)
If NOT ((IsMissing(sLabelRangeRepresentation)) AND (sLabelRangeRepresentation <> "")) Then
oSequenceLabel = CreateDataSequence(oDataProvider, sLabelRangeRepresentation, "label") ' ""
oDataY.setLabel(oSequenceLabel) ' oSequenceLabel label is used as name
End If
End If
' X
oDataX = CreateUnoService("com.sun.star.chart2.data.LabeledDataSequence")
oSequenceX = CreateDataSequence(oDataProvider, sXRangeRepresentation, "values-x")
If NOT IsNull(oSequenceX) Then
oDataX.setValues(oSequenceX)
End If
' set x and y data to series
aData = Array(oDataY, oDataX)
oNewDataSeries.setData(aData)
CreateDataSeries_Chart = oNewDataSeries
End Function
回答我自己的问题......也许可以帮助别人。研究文档后,我意识到我过早地调用了 Stackable 代码。我从 Sub ChartsGeneral 中删除了与可堆叠图相关的所有代码。在代码片段之后:
'Update chart (only the charttype is updated)
oChartType.setDataSeries(oNewDataSeriesList)
我添加了这段代码:
'Make the Chart Stacked...
oChart.Diagram = oChart.createInstance("com.sun.star.chart.StackableDiagram")
oChart.Diagram.Stacked = False
oChart.Diagram.Percent = True
oChart.Diagram.Vertical = False
然后就成功了。