I need some guidance on StringBuilder module. This function seems to be as simple as possible, but ...
The goal is to export data from internal structure 'PowerStrucX' to an external file in a CSV format to be able to import the data into MS Excel.
To get an appropriate Excel format I transform for each row each column with several operations (e.g. constant float point length, change decimal point to comma) into string variables (c1 to c17). This is all fine and works as expected. Because the data could be large I combine the each row and column with StringBuilder to one variable 'sb'. When 'sb' length exceeds a defined bufferlength, the variable is exported by appending to an existing file. The export itself works as expected (file management etc.) but the content is very strange.
The log file looks like this ...
Depending on the selected string buffer length (i played around with this buffer) the file content shows all rows or only some.
However, two things are strange:
1. Each row starts with the content of the last string c17 ('17,9761'). It should start with a time stamp 'T20250909....'. When I delete c17 (use only c1 to c16) the string starts with the content of c16 ('0,6014')
2. The content of the file is incomplete (some times), which has nothing to do with the file operations but with the string buffer. I can skip the export but #1 is still wrong.
It seems that my implementation and usage of the StringBuilder variable 'sb' is wrong but I don't see the reason why.
It is nearly impossible to create a simple program to simulate the issue. I tried this (same sub, but some simulated data structure) and what happens: it worked!!
Any hint to overcome this issue is appreciated.
Wosl
The goal is to export data from internal structure 'PowerStrucX' to an external file in a CSV format to be able to import the data into MS Excel.
To get an appropriate Excel format I transform for each row each column with several operations (e.g. constant float point length, change decimal point to comma) into string variables (c1 to c17). This is all fine and works as expected. Because the data could be large I combine the each row and column with StringBuilder to one variable 'sb'. When 'sb' length exceeds a defined bufferlength, the variable is exported by appending to an existing file. The export itself works as expected (file management etc.) but the content is very strange.
StringBuilder:
Sub OutputCSVPower (cFileDir As String, cFileCSV As String, cExt As String, _
cDataType As String, PowerStrucX As PowerStruc) As ResumableSub
Private nValues As Long, iFraction As Int, cReturn As String
Private lTotalLength As Long, lLength As Long
Private sb As StringBuilder, iJunk As Int
Private c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17 As String
'---------------------------------------------------------------
' Generate CSV Header and fraction of floating point numbers
'---------------------------------------------------------------
sb.Initialize
If iPowerUnitIndicator = 0 Then
iFraction = 1
Else If iPowerUnitIndicator = 1 Then
iFraction = 4
Else If iPowerUnitIndicator = 2 Then
iFraction = 7
End If
For i = 1 To nPowerTableName
If i = 1 Then
sb.Append(PowerTableName(i-1) & cExt)
Else
sb.Append(";" & PowerTableName(i-1) & cExt)
End If
Next
sb.Append(CRLF)
lTotalLength = sb.Length
lLength = lTotalLength
'---------------------------------------------------------------
' Output header to new CSV file
'---------------------------------------------------------------
Wait For (OpenOutputExternalStorage (cPVDataStorageFolder, cFileCSV, sb, False)) complete (oRes As Object)
'---------------------------------------------------------------
' Loop through data rows
'---------------------------------------------------------------
nValues = PowerStrucX.TimestampList.Size
If nValues < 1 Then
Return "3"
End If
sb.Initialize
iJunk = 0
For i = 1 To nValues
' Setup row of data
c1 = PowerStrucX.TimestampList.Get(i-1)
c2 = PowerStrucX.DatumList.Get(i-1)
c3 = ((RFormat(PowerStrucX.UhrzeitList.Get(i-1), 6, 14, True)).Trim).Replace(".",",")
c4 = PowerStrucX.UhrzeitListText.Get(i-1)
c5 = ((RFormat(PowerStrucX.UhrzeitListX.Get(i-1), 6, 14, True)).Trim).Replace(".",",")
c6 = RFormat(PowerStrucX.ProduktionList.Get(i-1), iFraction, 8, True).Replace(".",",")
c7 = RFormat(PowerStrucX.VerbrauchList.Get(i-1), iFraction, 8, True).Replace(".",",")
c8 = RFormat(PowerStrucX.DirektverbrauchList.Get(i-1), iFraction, 8, True).Replace(".",",")
c9 = RFormat(PowerStrucX.BatterieentladungList.Get(i-1), iFraction, 8, True).Replace(".",",")
c10 = RFormat(PowerStrucX.NetzbezugList.Get(i-1), iFraction, 8, True).Replace(".",",")
c11 = RFormat(PowerStrucX.NetzeinspeisungList.Get(i-1), iFraction, 8, True).Replace(".",",")
c12 = RFormat(PowerStrucX.BatterieladungList.Get(i-1), iFraction, 8, True).Replace(".",",")
c13 = RFormat(PowerStrucX.SpeicherladungList.Get(i-1), iFraction, 8, True).Replace(".",",")
c14 = RFormat(PowerStrucX.WorkTodayList.Get(i-1), iFraction, 8, True).Replace(".",",")
c15 = RFormat(PowerStrucX.WorkMonthList.Get(i-1), iFraction, 8, True).Replace(".",",")
c16 = RFormat(PowerStrucX.WorkYearList.Get(i-1), iFraction, 8, True).Replace(".",",")
c17 = RFormat(PowerStrucX.WorkTotalList.Get(i-1), iFraction, 8, True).Replace(".",",")
sb.Append(c1).Append(";").Append(c2).Append(";").Append(c3).Append(";").Append(c4).Append(";").Append(c5).Append(";"). _
Append(c6).Append(";").Append(c7).Append(";").Append(c8).Append(";").Append(c9).Append(";").Append(c10).Append(";"). _
Append(c11).Append(";").Append(c12).Append(";").Append(c13).Append(";").Append(c14).Append(";").Append(c15).Append(";"). _
Append(c16).Append(";").Append(c17).Append(";").Append(CRLF)
'WOSL###########################
Log ("Länge: " & sb.Length & " sb: " & sb.ToString)
'WOSL###########################
' Append to external file
lTotalLength = lTotalLength + sb.Length
lLength = lLength + sb.Length
If lLength > nStringBuffer Then
AppendExternalStorage (sb.ToString)
iJunk = iJunk + 1
sb.Initialize
lLength = 0
End If
Next
' Clear string buffer
If lLength > 0 Then
AppendExternalStorage (sb.ToString)
iJunk = iJunk + 1
End If
sb.Initialize
Log ("CSV File '" & cFileCSV & "' with power data (" & cDataType & ") successfully written to '" & _
cFileDir & "' with " & lTotalLength & " Bytes in " & iJunk & " junks.")
cReturn = "0"
Return cReturn
End Sub
The log file looks like this ...
Log:
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create (first time) **
Can use persistant uri!
** Activity (main) Resume **
Get PV power data from SQLite DB on NAS, calculate work data and plot results
Generate 'Day' Chart (daily power flow chart in main activity)
TimestampFromToday, TimestampToToday, DateTime: T20250909000000, T20250909235959 (09.09.2025 00:00:00, 09.09.2025 23:59:59)
------------------------------------------------------------------
Get power data from webserver
Selected timeframe: T20250909000000 to T20250909235959
*** Receiver (httputils2service) Receive (first time) ***
Number of rows processed: 941
Länge: 171 sb: 17.9761T20250909000027;09.09.2025;0,007500;00:00:27;0,007500; 0,0000; 0,3138; 0,0000; 0,0000; 0,3138; 0,0000; 0,0000; 0,0000; 0,0000; 0,2542; 0,6014; 17,9761;
Länge: 171 sb: 17.9761T20250909000129;09.09.2025;0,024722;00:01:29;0,024722; 0,0000; 0,3120; 0,0000; 0,0000; 0,3120; 0,0000; 0,0000; 0,0000; 0,0000; 0,2542; 0,6014; 17,9761;
Länge: 171 sb: 17.9761T20250909000231;09.09.2025;0,041944;00:02:31;0,041944; 0,0000; 0,3106; 0,0000; 0,0000; 0,3106; 0,0000; 0,0000; 0,0000; 0,0000; 0,2542; 0,6014; 17,9761;
Länge: 171 sb: 17.9761T20250909000333;09.09.2025;0,059167;00:03:33;0,059167; 0,0000; 0,3408; 0,0000; 0,0000; 0,3408; 0,0000; 0,0000; 0,0000; 0,0000; 0,2542; 0,6014; 17,9761;
Länge: 171 sb: 17.9761T20250909000435;09.09.2025;0,076389;00:04:35;0,076389; 0,0000; 0,3111; 0,0000; 0,0000; 0,3111; 0,0000; 0,0000; 0,0000; 0,0000; 0,2542; 0,6014; 17,9761;
Länge: 171 sb: 17.9761T20250909000537;09.09.2025;0,093611;00:05:37;0,093611; 0,0000; 0,3394; 0,0000; 0,0000; 0,3394; 0,0000; 0,0000; 0,0000; 0,0000; 0,2542; 0,6014; 17,9761;
....
Depending on the selected string buffer length (i played around with this buffer) the file content shows all rows or only some.
However, two things are strange:
1. Each row starts with the content of the last string c17 ('17,9761'). It should start with a time stamp 'T20250909....'. When I delete c17 (use only c1 to c16) the string starts with the content of c16 ('0,6014')
2. The content of the file is incomplete (some times), which has nothing to do with the file operations but with the string buffer. I can skip the export but #1 is still wrong.
It seems that my implementation and usage of the StringBuilder variable 'sb' is wrong but I don't see the reason why.
It is nearly impossible to create a simple program to simulate the issue. I tried this (same sub, but some simulated data structure) and what happens: it worked!!
Any hint to overcome this issue is appreciated.
Wosl