Hallo!
Verbrauch in bestimmten Zeiträumen ermitteln:
Wenn die Ablesungen nicht regelmäßig und hinreichend oft erfolgen,
muss der Verbrauch aus den vorhandenen Daten durch Interpolation
der Zählerstände/Ablesetage ermittelt werden.
Public Class frmConsum
Dim dt As New DataTable
Dim bs As New BindingSource
Dim dgv As New DataGridView With
{.Parent = Me, .Size = New Size(400, 300), .DataSource = bs}
Private Sub frmVerbrauch_Load(sender As Object, _
e As EventArgs) Handles MyBase.Load
'Testdaten
dt.Columns.Add("Datum", GetType(Date))
dt.Columns.Add("Stand", GetType(Double))
With dt.Rows
.Add(New Date(2022, 1, 1), 20)
.Add(New Date(2022, 3, 15), 382)
.Add(New Date(2022, 3, 26), 476)
.Add(New Date(2022, 4, 6), 589)
.Add(New Date(2022, 4, 23), 745)
.Add(New Date(2022, 5, 5), 830)
.Add(New Date(2022, 5, 15), 934)
.Add(New Date(2022, 7, 4), 1011)
.Add(New Date(2022, 12, 31), 2123)
End With
'Datenbindung
bs.datasource = dt
'Beispiel Verbrauch im April 2022
Dim c1 As Double = _
GetConsum(bs, New Date(2022, 4, 1), New Date(2022, 4, 30), _
"Datum", "Stand")
'Beispiel Gesamtverbrauch 2022
Dim c3 As Double = _
GetConsum(bs, New Date(2022, 1, 1), New Date(2022, 12, 31), _
"Datum", "Stand")
'Beispiel für die Ermittlung der interpolierten Verbräuche pro Monat
Dim c(12) As Double, csum As Double
For i As Integer = 1 To 12
If i < 12 Then
c(i) = _
GetConsum(bs, New Date(2022, i, 1), New Date(2022, i + 1, 1), _
"Datum", "Stand")
Else
c(i) = _
GetConsum(bs, New Date(2022, i, 1), New Date(2022, i, 31), _
"Datum", "Stand")
End If
csum += c(i)
Next i
End Sub
Private Function GetConsum(bs As BindingSource,
Start_Date As Date, End_date As Date,
Date_Column As String, Count_Column As String) As _
Double
'ansteigendes Sortieren ist erforderlich
bs.Sort = Date_Column & " ASC"
If (End_date - Start_Date).Days < 1 Then Return -1
Dim start_interpol, end_interpol, first_value, last_value As Double
Dim found_Start As Boolean = False, found_end As Boolean = False
Dim consum As Double = -1
For i As Integer = 0 To bs.Count - 2
'Daten einer Zeilenpaarung in Variablen eintragen
Dim d1 As Date = CDate(bs(i).row(Date_Column)).Date
Dim d2 As Date = CDate(bs(i + 1).row(Date_Column)).Date
Dim c1 As Double = CDbl(bs(i).row(Count_Column))
Dim c2 As Double = CDbl(bs(i + 1).row(Count_Column))
'aktuelles Ableseintervall in Tagen
Dim interval_days As Integer = (d2 - d1).TotalDays
'Mehrere Ablesungen zu einem Datum sind unplausibel
If interval_days < 1 Then Return -1
'Sonderfall: Keine Ablesung ist innerhalb des Intervalls erfolgt
If d1 <= Start_Date And d2 >= End_date Then
Return (c2 - c1) * (End_date - Start_Date).TotalDays / _
interval_days
End If
If d1 = Start_Date Then
'Am ersten Tag des gewünschten Intervalls ist abgelesen worden
start_interpol = 0 : first_value = c1 : found_Start = True
ElseIf d1 < Start_Date And d2 > Start_Date Then
'Stand am ersten Tag des gewünschten Intervalls linear
' interpolieren
start_interpol = (c2 - c1) * (d2 - Start_Date).TotalDays / _
interval_days
first_value = c2 'erster Stand im Intervall
found_Start = True
End If
If d1 = End_date Then
'Am letzten Tag des gewünschten Intervalls ist abgelesen worden
end_interpol = 0 : last_value = c1 : found_end = True
ElseIf d2 = End_date Then
end_interpol = 0 : last_value = c2 : found_end = True
ElseIf d1 < End_date And d2 > End_date Then
'Stand am letzten Tag des gewünschten Intervalls linear
' interpolieren
end_interpol = (c2 - c1) * (End_date - d1).TotalDays / _
interval_days
last_value = c1 'letzter Stand im Intervall
found_end = True
End If
If found_Start And found_end Then
'Verbrauch im Intervall ggf. incl. Interpolation am Anfang und
' Ende
Return start_interpol + end_interpol + (last_value - _
first_value)
End If
Next i
'Keine Daten
Return -1
End Function
End Class |