Bi Monthly dates, how? - date

I have the vb net code for first and last day of the Quarter, but I am trying to do this for first and last day of Bi monthly period ( which end on these months Feb, Apr, Jun, Aug, Oct, Dec)
So the bimonthly start and end dates are
Jan 1 to Feb 28 (or 29)
Mar 1 to Apr 30,
May 1 to Jun 30,
etc
Any ideas how to do this? (in Vb thanks)
'To get the first day of the quarter
Public Shared Function xFirstDayOfQuarter(ByVal theDay As DateTime) As DateTime
Dim currQuarter As Integer = (Month(theDay) - 1) \ 3 + 1
Dim FirstDayQuarter As DateTime = DateSerial(Year(theDay), 3 * currQuarter - 2, 1)
Return FirstDayQuarter
End Function
'To get the last day of the quarter
Public Shared Function xLastDayOfQuarter(ByVal theDay As DateTime) As DateTime
Dim currQuarter As Integer = (Month(theDay) - 1) \ 3 + 1
Dim LastDayQuarter As DateTime = DateSerial(Year(theDay), 3 * currQuarter + 1, 0)
Return LastDayQuarter
End Function
This how far I got ..
Private Function DayOfBiMonth(ByVal theDay As DateTime, ByVal FirstOrLast As Integer) As DateTime
Dim res As DateTime = Util.gBASEDATE
Dim Mth As Integer = Month(theDay)
Dim Yr As Integer = Year(theDay)
Dim BiMonth As Integer = -1
Select Case Mth
Case Is = 1, 2
If FirstOrLast = 1 Then
BiMonth = 1
ElseIf FirstOrLast = 2 Then
BiMonth = 2
End If
Case Is = 3, 4
If FirstOrLast = 1 Then
BiMonth = 3
ElseIf FirstOrLast = 2 Then
BiMonth = 4
End If
Case Is = 5, 6
If FirstOrLast = 1 Then
BiMonth = 5
ElseIf FirstOrLast = 2 Then
BiMonth = 6
End If
Case Is = 7, 8
If FirstOrLast = 1 Then
BiMonth = 7
ElseIf FirstOrLast = 2 Then
BiMonth = 8
End If
Case Is = 9, 10
If FirstOrLast = 1 Then
BiMonth = 9
ElseIf FirstOrLast = 2 Then
BiMonth = 10
End If
Case Is = 11, 12
If FirstOrLast = 1 Then
BiMonth = 11
ElseIf FirstOrLast = 2 Then
BiMonth = 12
End If
End Select
If FirstOrLast = 1 Then
res = DateSerial(Yr, BiMonth, 1)
ElseIf FirstOrLast = 2 Then
res = DateSerial(Yr, BiMonth, 20)
res = Util.LastDayOfMonth(res)
End If
Return res
End Function
Private Function LastDayOfMonth(ByVal theDay As DateTime) As DateTime
Dim FirstDayMonth As DateTime = DateSerial(Year(theDay), Month(theDay), 1)
Dim LastDayMonth As DateTime = FirstDayMonth.AddMonths(1).AddDays(-1)
Return LastDayMonth
End Function

This works best
'To get last day of BIMonth 2,4,6,8,12
Public Shared Function LastDayOfBiMonth(ByVal theDay As DateTime) As DateTime
Dim FirstDayBiMonth As DateTime = FirstDayOfBiMonth(theDay)
Dim LastDayBiMonth As DateTime = FirstDayBiMonth.AddMonths(2).AddDays(-1)
Return LastDayBiMonth
End Function
'To get first day of BIMonth 1,3,5,7,9,11
Public Shared Function FirstDayOfBiMonth(ByVal theDay As DateTime) As DateTime
Dim Mnth As Integer = Month(theDay)
If Mnth Mod 2 = 0 Then
Mnth = Mnth - 1
End If
Dim FirstDayBiMonth As DateTime = DateSerial(Year(theDay), Mnth, 1)
Return FirstDayBiMonth
End Function

Related

Cannot get my chart ‘stacked’ using a Calc macro

Somehow I cannot get my chart to ‘stack’. For reasons explained below I first prepare a standard chart in a macro called ‘ChartsGeneral’. Based on some settings on my ‘Charts’ worksheet, it then calls a specific second macro, e.g. ‘ChartBuildStatus’. In this second macro I generate the category and data-series, and adjust the settings of the standard chart as necessary.
When I try to get a stacked chart via ‘createInstance(“com.sun.star.chart.StackableDiagram”)’ nothing changes. I have studied the documentation and several forums, but I have no clue what I am missing. Code below.
Configuration details
Version: 7.4.3.2 (x64) / LibreOffice Community
CPU threads: 12; OS: Windows 10.0 Build 19045; Locale: nl-NL (nl_NL); UI: en-US
OK, here it goes… Please have some mercy on a poor old non-programmer nerd.
Background
Over the years I collected a rather large set of Excel spreadsheets with VBA macros for my personal finances. This year I decided to migrate them all to LibreOffice, as part of my wider migration from Windows to Linux. I am not a programmer, so I decided to use BASIC as it would be closest to VBA.
One of my spreadsheets tracks progress on our home mortgage. I keep track of all payments on interest and principal. As we are paying down extra with a fixed monthly payment and a ‘snowball’ (all savings go back as payments to the principal) the spreadsheet also calculates the expected next snowball payment, as well as a prognosis for the remainder of the mortgage. That all works fine.
The key worksheets in my Mortgage spreadsheet are ‘Months’, where I store all the data of past payments, and ‘Prognosis’, which holds a copy of ‘Months’ but also a prognosis for every month in the future.
I am now down to the last block of functionality: reporting. This is mainly a collection of charts that show the history, current status and prognosis for my mortgage based on the data in Months and Prognosis. For this I use a dedicated worksheet called ‘Charts’ in my spreadsheet. Here I can select a Chart Type from a dropdown-list, as well as some date or period related settings (I use named fields for this). See a partial screenshot below.
Partial Screenshot of Charts worksheet
When I press the ‘Update Chart’ button on my Charts worksheet, a macro called ‘ChartsGeneral’ is triggered. In this macro:
I use the date or period related settings to calculate the starting row and ending row for the data series
I then generate an empty standard linechart called ‘AdminChart’ on the Charts worksheet, with settings for the axes, the formatting, and everything
I call a second macro based on the ChartType value on Charts. In the above example the chart is called ‘Opbouw Stand van Zaken’, so I call a second macro called ChartBuildStatus.
The code for ChartsGeneral can be found below
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
Once the macro ChartBuildStatus is called, that macro contains the following actions:
I change the chart type of AdminChart to AreaDiagram. That shows up correctly on my screen.
I then try to make it a stacked diagram. But it won’t…
After that, I change some formatting characteristics of the chart, like axis titles and number formats
And I generate the category and data series calling on two other macro’s, CreateDataSequence() and CreateDataSeries_Chart(). I don’think they are the problem, they work correctly with other non-stacked line charts and the series
I have tried a number of things, including moving the stacking code to the end of the macro. But I cannot get it to work correctly. I must be overlooking something or doing something very stupid. So after literally days of trying I am pinning my hopes on the community. Anybody who can shed some light on this?
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
On the left the chart as it looks now in my LibreOffice Calc spreadsheet, on the right the chart as I want it to look based on my current Excel sheet.
Left: LibreOffice / Right: Excel (how I want it)
For the sake of completeness, please find the additional macro’s CreateDataSequence() and CreateDataSeries_Chart() below.
CreateDataSequence()
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

LinkedStyle for the Word BuiltinStyles

I am extending the capability of the Word report writing from VSTO to consider different languages. Therefore, instead of using the headings like "Heading 1" etc, I have used wdStyleHeading1 etc. I have built a function to assign the style to the heading. The problem is that the line 1 and line 2 below are overwriting each other. If I call the function first, I loose list number and If I call function second, I loose the format. Can you please explain where I am going wrong?
I have imported the necessary references.
Call HeadingListLevel(wrdApp, 1)
wrdApp.Selection.ParagraphFormat.Style = Word.WdBuiltinStyle.wdStyleHeading1
Below is the sub function
Sub HeadingListLevel(wrdApp As Object, HeadingLvl As Integer)
'Dim wrdHeading As String
Dim wrdHeadingNr As String
Dim i As Integer
Dim ListTemp As Word.ListTemplate
wrdHeadingNr = "%" & 1
ListTemp = wrdApp.ListGalleries(Word.WdListGalleryType.wdOutlineNumberGallery).ListTemplates(1)
For i = 1 To HeadingLvl
If i > 1 Then
wrdHeadingNr = wrdHeadingNr & "." & "%" & i
End If
Next i
'wrdHeading = "Heading " & HeadingLvl
With ListTemp.ListLevels(1)
Select Case HeadingLvl
Case 1
.LinkedStyle = Word.WdBuiltinStyle.wdStyleHeading1
Case 2
.LinkedStyle = Word.WdBuiltinStyle.wdStyleHeading2
Case 3
.LinkedStyle = Word.WdBuiltinStyle.wdStyleHeading3
Case 4
.LinkedStyle = Word.WdBuiltinStyle.wdStyleHeading4
Case 5
.LinkedStyle = Word.WdBuiltinStyle.wdStyleHeading5
Case 6
.LinkedStyle = Word.WdBuiltinStyle.wdStyleHeading6
Case 7
.LinkedStyle = Word.WdBuiltinStyle.wdStyleHeading7
End Select
.NumberFormat = wrdHeadingNr
.NumberStyle = Word.WdListNumberStyle.wdListNumberStyleArabic
End With
wrdApp.Selection.Range.ListFormat.ApplyListTemplate(ListTemplate:=ListTemp)
ListTemp = Nothing
End Sub
I discovered the answer myself. Below is the changes to the sub function. It worked well for me.
Sub HeadingListLevel(wrdApp As Object, HeadingLvl As Integer)
'Dim wrdHeading As String
Dim wrdHeadingNr As String
Dim i As Integer
Dim ListTemp As Word.ListTemplate
wrdHeadingNr = "%" & 1
ListTemp = wrdApp.ListGalleries(Word.WdListGalleryType.wdOutlineNumberGallery).ListTemplates(5)
For i = 1 To HeadingLvl
If i > 1 Then
wrdHeadingNr = wrdHeadingNr & "." & "%" & 1
End If
Next i
'wrdHeading = "Heading " & HeadingLvl
With ListTemp.ListLevels(HeadingLvl)
Select Case HeadingLvl
Case 1
.LinkedStyle = wrdApp.ActiveDocument.Styles(Word.WdBuiltinStyle.wdStyleHeading1).NameLocal
Case 2
.LinkedStyle = wrdApp.ActiveDocument.Styles(Word.WdBuiltinStyle.wdStyleHeading2).NameLocal
Case 3
.LinkedStyle = wrdApp.ActiveDocument.Styles(Word.WdBuiltinStyle.wdStyleHeading3).NameLocal
Case 4
.LinkedStyle = wrdApp.ActiveDocument.Styles(Word.WdBuiltinStyle.wdStyleHeading4).NameLocal
Case 5
.LinkedStyle = wrdApp.ActiveDocument.Styles(Word.WdBuiltinStyle.wdStyleHeading5).NameLocal
Case 6
.LinkedStyle = wrdApp.ActiveDocument.Styles(Word.WdBuiltinStyle.wdStyleHeading6).NameLocal
Case 7
.LinkedStyle = wrdApp.ActiveDocument.Styles(Word.WdBuiltinStyle.wdStyleHeading7).NameLocal
End Select
'.LinkedStyle = wrdHeading
.NumberFormat = wrdHeadingNr
.NumberStyle = Word.WdListNumberStyle.wdListNumberStyleArabic
'.StartAt = 1
'.ResetOnHigher = False
End With
wrdApp.Selection.Range.ListFormat.ApplyListTemplate(ListTemplate:=ListTemp)
ListTemp = Nothing
End Sub

Get today -2 (skipping weekend)

How can I get the Today -2 days (the last 2 working days from now)? but skipping the weekend?
Example #1: Today is February 25, I want February 21
Example #2: Today is February 26, I want February 24
PS: Date format is DD/MM/YYYY
I have this, but the result is going forward, should I use datediff or what?:
<%
Dim d
d = DateAdd("m", 1, Now)
d = "01/" & Month(d) & "/" & Year(d)
d = DateAdd("d", -1, d)
If Weekday(d) = 7 Then
d = DateAdd("d", -1, d)
ElseIf Weekday(d) = 1 Then
d = DateAdd("d", -2, d)
End If
Response.Write "Day: " & d
%>
To get your desired result you need to subtract 3 days on Saturdays, 4 days on Sundays and Mondays, and 2 days on all other days. This can be achieved with something like this:
today = Now
num = Weekday(today, vbWednesday)
d = today - (2 + num\5 + num\6)
response.write "Two working days back: " & d
The Weekday function returns a numeric value for each weekday. By basing the week on Wednesday you can calculate the additional number of days you need to subtract from the current date with integer divisions:
num\5 returns 1 for Saturday, Sunday and Monday, and 0 otherwise.
num\6 returns 1 for Sunday and Monday, and 0 otherwise.
Thus the term 2 + num\5 + num\6 becomes 3 for Saturdays, 4 for Sundays and Mondays, and 2 for all other days.
This might be overkill for what you need but here are two routines I use in my scripts to add or subtract workdays while considering weekends and holidays.
Function AddWorkingDays(dtStart, intDays)
' Start/Default case...
AddWorkingDays = CDate(dtStart)
' If positive days, step forward, otherwise step backward...
Dim intStep, intCount
If intDays > 0 Then intStep = 1 Else intStep = -1
Do While intCount <> intDays
AddWorkingDays = AddWorkingDays + intStep
If IsValidDate(AddWorkingDays) Then intCount = intCount + intStep
Loop
End Function
Function IsValidDate(d)
Dim intWeekday, intMonth, intDay
intWeekday = Weekday(d)
intMonth = Month(d)
intDay = Day(d)
' Weekend dates are not acceptable...
If intWeekday = vbSaturday Or intWeekday = vbSunday Then Exit Function
' Holidays are also not acceptable...
If intMonth = 01 Then If intDay = 01 Then Exit Function ' New Year's Day
If intMonth = 07 Then If intDay = 04 Then Exit Function ' Independence Day
If intMonth = 12 Then If intDay = 25 Then Exit Function ' Christmas Day
' Memorial Day is the last Monday in May...
If intWeekday = vbMonday Then If intMonth = 05 Then If intDay >= 25 Then Exit Function
' ... (Thanksgiving, others) ...
' All tests passed. Date is a valid workday...
IsValidDate = True
End Function

Error 91 in VBA using classes

I'm currently trying to implement a Clark & Wright Savings Heurisitc in VBA, but I'm currently facing some problem. I'm fairly new to VBA, and this error (91) keeps apearing on similar situations, which lead me to believe I'm missing some crucial knowledge. Next I present you the code:
Public Sub CWsavings()
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim aux As Integer
Dim d As Integer
Dim r As Integer
Dim Cu(200) As customer
Dim De(12) As Depot
For i = 1 To 200
Set Cu(i) = New customer
Cu(i).custID = i
Cu(i).longitude = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 2)
Cu(i).latitude = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 3)
Cu(i).lt = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 4)
Cu(i).et = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 5)
Cu(i).weekdemand = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 6)
Cu(i).peakdemand = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 7)
Cu(i).D1 = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 8)
Cu(i).D2 = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 9)
Next i
For j = 1 To 12
Set De(j) = New Depot
De(j).depotID = j
De(j).Dname = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 13)
De(j).latitude = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 14)
De(j).longitude = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 15)
De(j).ncust = ThisWorkbook.Sheets("Results").Cells(j, 7)
De(j).nroute = 0
For k = 1 To De(j).ncust
aux = ThisWorkbook.Sheets("Results").Cells(j + 1, 10 + k)
Call De(j).SetCustomer(Cu(aux), k)
Next k
Next j
For d = 1 To 12
Dim M(30, 30) As Double
Dim maxsav As Double
Dim maxpos(2) As Integer
Dim connorder(676, 2) 'order of connections for routing
Dim it As Integer
it = 0
For i = 1 To De(d).ncust
For j = 1 To De(d).ncust
M(i, j) = CalcSavings(De(d), De(d).customer(i), De(d).customer(j)) ' error here
Next j
Next i
itbegin:
maxsav = 0
maxpos(1) = 0
maxpos(2) = 0
For i = 1 To De(d).ncust
For j = 1 To De(d).ncust
If i <> j Then
If M(i, j) > maxsav Then
maxsav = M(i, j)
maxpos(1) = i
maxpos(j) = j
End If
End If
Next j
Next i
it = it + 1
connorder(it, 1) = maxpos(1)
connorder(it, 2) = maxpos(2)
If it < De(d).ncust * De(d).ncust - ncust Then
M(maxpos(1), maxpos(2)) = 0
GoTo itbegin
End If
Next d
End Sub
Public Function CalcSavings(d As Depot, C1 As customer, C2 As customer)
Dim id As Double
Dim dj As Double
Dim ij As Double
id = DeptDist(C1, d)
dj = DeptDist(C2, d)
ij = CustDist(C1, C2)
CalcSavings = id + dj - ij
End Function
The class Depot:
Public depotID As Integer
Public Dname As String
Public latitude As Double
Public longitude As Double
Private customers(200) As customer
Public ncust As Integer
Private routes(500) As route
Public nroute As Integer
Public Sub addcust(C As customer)
ncust = ncust + 1
Set customers(ncust) = C
End Sub
Public Sub addroute(R As route)
nroute = Me.nroute + 1
Set routes(Me.nroute) = R
End Sub
Public Property Get customer(i As Integer) As customer
customer = customers(i)
End Property
Public Sub SetCustomer(C As customer, i As Integer)
Set customers(i) = C
End Sub
Public Property Get route(i As Integer) As route
route = routes(i)
End Property
Public Sub SetRoute(R As route, i As Integer)
Set routes(i) = R
End Sub
(Class depot Updated)
And the class Customer:
Public custID As Integer
Public latitude As Double
Public longitude As Double
Public lt As Double
Public et As Double
Public weekdemand As Integer
Public peakdemand As Integer
Public D1 As Integer
Public D2 As Integer
I'm sorry for the long post, any help would be appreciated.
Final answer...
VERY ODDLY, (not that odd, when you really look at it, but) you need to use Set even in your Get properties. I guess the reason behind this is because you're returning an object, and even though that object may already exist, you're not going to use that very object. A copy is used instead and Set becomes vital to initialize that copy.
For example, here's what your "get customer" should look like :
Public Property Get customer(i As Integer) As customer
Set customer = customers(i)
End Property
I guess it all makes sense; your array is private, and therefore you wouldn't want to pass the exact object that is contained inside that array, or it'd be counter-logic.
I think I found it... again...!
Try this :
Public Sub SetCustomer(C As customer, i As Integer)
Set customers(i) = C
End Sub
Notice customer(i) was replaced by customers(i)
EDIT : Deleted previous answer, as I was mostly fishing.

how to get the range date in vb6

i have 2 date picker
Dim pday, eitday, otherday, tpenalty, difday, subpenalty As Integer
difday = Val(L1.Caption) - Val(L2.Caption)
pday = 7
eitday = 8
otherday = difday - eitday
tpenalty = 25
If difday <= pday Then
PENALTY.Caption = 0
ElseIf difday = eitday Then
PENALTY.Caption = tpenalty
ElseIf difday > eitday Then
For i = 0 To otherday - 1
subpenalty = subpenalty + 5
Next i
PENALTY.Caption = tpenalty + subpenalty
End If
the problem is when the month is change the calculation is invalid.
I'm guessing based on your code (as many things are unclear), but this should give the number of days between two dates:
difday = DateDiff("d", StartDate, EndDate)
I've used StartDate and EndDate to signify the start and end of the lone period which are used to set L1 and L2, as you shouldn't be converting from strings to dates for calculations.