Code zur Anzeige von Daten aus DataSet optimieren (Ausführung dauert zu lange)

  • VB.NET
  • .NET 4.5

Es gibt 98 Antworten in diesem Thema. Der letzte Beitrag () ist von DerSmurf.

    Huhu.
    Ja ein bisschen schwer habe ich mich bei der Befüllung des "13. Monats" getan.
    Aber ich glaube das Ergebniss ist ok (hab ich ja gepostet).
    Der Rest war relativ einfach, wenn auch ein wenig zeitaufwendig.
    Hat etwas gedauert, herauszufinden welche Schleifen ich mir in den anderen Subs sparen kann. Aber klappt ja alles :)

    Ich mach mich jetzt die Tage an den Monatsvergleich und melde mich, wenn es fertig, ist oder ich zwischendrin noch Fragen habe. Könnte aber ein paar Tage dauern.

    Bishirhin erstmal nochmal vielen, vielen Dank für deine Hilfe.
    Hmm, sorry aber ich habe doch noch eine (Anfänger)Frage.
    Es geht nochmal um die Übergabe der Variablen an die einzelnen Subs. z.B.

    VB.NET-Quellcode

    1. Private Sub GetDataSummaries(year As Integer, incomePerMonthAndProductGroup(,) As Double, customersPerMonth() As Integer, incomePerProductGroup() As Double)


    Diese habe ich (in der alten Version des Codes) alle ByRef übergeben (also quasi als Verweis auf die Variablen, welche von der Aufrufsub übergeben werden), damit sie geändert wieder aus der Sub GetDataSummaries rauskommen.

    Wenn ich diese ByVal (was ja der Standart - also in obiger GetDataSummaries Deklaration der Fall - ist), dann arbeitet die Sub GetDataSummaries doch nur mit den Werten der übergebenen Variablen, kann die übergebenen Variablen aber nicht ändern.

    Warum kommen die Teile aus deiner Sub verändert wieder raus?
    Ah, das heißt im obigen Beispiel würde, wenn year vor der Übergabe 2009 ist und in der Sub GetDataSummaries auf 2010 geändert wird, nach der Ausführung von GetDataSummaries immernoch 2009 sein, weil sie als ByVal eben nicht verändert wird. Diese müsste dann ByRef sein.
    Gleiches ist es mit dem Array - das ist nach der Ausführung von GetDataSummaries immernoch das gleiche, beinhaltet aber andere Werte.
    Also quasi übergebe ich ein Array immer (so wie) ByRef.

    DerSmurf schrieb:

    Ah, das heißt im obigen Beispiel würde, wenn year vor der Übergabe 2009 ist und in der Sub GetDataSummaries auf 2010 geändert wird, nach der Ausführung von GetDataSummaries immernoch 2009 sein, weil sie als ByVal eben nicht verändert wird.
    Genau.

    DerSmurf schrieb:

    Diese müsste dann ByRef sein.
    Ähm - bitte nicht!
    Die Idee von GetDataSummaries() ist, dass der Aufrufer das Jahr angibt, und GetDataSummaries() holt dann die Summaries für dieses Jahr zusammen. Das wäre doch Bockmist, wenn GetDataSummaries() eigenmächtig die Jahres-Vorgabe ändern täte (oder es auch nur könnte).

    DerSmurf schrieb:

    ...Array - das ist nach der Ausführung von GetDataSummaries immernoch das gleiche, beinhaltet aber andere Werte.
    Also quasi übergebe ich ein Array immer (so wie) ByRef.
    hmm - naja so ungefähr. Bzw. wie du bislang ByRef verstanden hattest.
    Mir wäre lieber, du könntest es so nehmen wie's ist: Array ist ein Referenz-Typ.
    Wenn Eigenschaften eines Referenz-Typen in einer Sub geändert, so sind sie auch beim Aufrufer geändert. Das betrifft nicht nur Auflistungen, sondern die allermeisten komplexen Typen - auch ein Form, oder Button, eine DataTable, DataRow, ... alles Referenz-Typen.

    (gugge auch: ByVal und ByRef - was macht jetzt genau was )
    OK, so werde ich es nehmen! und danke für den Link!

    Das Beispiel mit der Änderung der Variablen year, war nur ein Beispiel.
    Natürlich sinnbefreit, das Jahr byref zu übergeben und zu ändern - aber die Sub diente ja gerade als Beispiel.
    Huhu
    Ich brauche leider bereits früher deine Hilfe als angenommen.
    Ich habe versucht, nach der gleichen Logik wie in deiner "JahresumsatzSub", meine Tagesumsätze auszulesen.
    Das Auslesen an sich klappt. Aber ich habe ja bei den Monatseinnahmen das Problem, dass ich jede Einnahme einem Datum zuordnen muss, bzw. wissen muss, an welchem Datum es keine Einnahme gab.
    Ich habe mal die Solution angehangen. Hier habe ich jeweils einzelne Dateien erzeugt. "Year" beinhaltet den Code für die Jahresuaswertung - welche hier irrelevant ist.
    MonthOld und MonthNew beinhalten entsprechend den alten Code (funktioniert, aber langsam) für die Monatsauswertung. In "New" schreibe ich gerade den neuen Code.

    Falls du die Solution nicht brauchst, hier der Code:

    VB.NET-Quellcode

    1. 'Daten für den ersten Monat sammeln
    2. Dim ArrDates(0 To 30) As Date 'Array zum speichern der Daten mit Umsätzen
    3. Dim ArrIncome(0 To 30, 0 To groupcount) As Double 'Habe einfach 31 Zeilen im Array veranschlagt - wird schon reichen...
    4. 'alternativ: Tage des Monats auslesen (Numberofdays = Integer.Parse(DateTime.DaysInMonth(year, Month).ToString))
    5. 'und Arraygröße dynamisch bestimmen
    6. Dim ArrCustomers(0 To 30) As Integer 'hier das gleiche
    7. GetDataSummariesMonth(Startdate, ArrDates, ArrIncome, ArrCustomers)


    VB.NET-Quellcode

    1. Private Sub GetDataSummariesMonth(Startdate As Date, Arrdate() As Date, Arrincome(,) As Double, Arrcustomers() As Integer)
    2. Dim dt1 = Startdate.AddMonths(1) ' Zeit-Bereich
    3. Dim productGroups = DtsSettings.ProductGroup.ToArray
    4. Dim groupcount = productGroups.Length
    5. Dim distributionTables = From distTbl In productGroups.SelectMany(Function(x) x.GetDistribution_TableRows)
    6. Let dt = distTbl.DailyIncomeRow._Date
    7. Where dt >= Startdate AndAlso dt < dt1 Select distTbl
    8. For Each rwDistrTbl In distributionTables
    9. Dim DateOfIncome = rwDistrTbl.DailyIncomeRow._Date ' Datum der Einnahme speichern
    10. Dim rwPG = rwDistrTbl.ProductGroupRow
    11. Dim day = rwDistrTbl.DailyIncomeRow._Date.Day
    12. Dim iProdGroup = Array.IndexOf(productGroups, rwPG)
    13. Arrdate(day - 1) = DateOfIncome
    14. Arrincome(day - 1, iProdGroup) += CDbl(rwDistrTbl.ProductGroupIncome / 100)
    15. Arrincome(30, iProdGroup) += CDbl(rwDistrTbl.ProductGroupIncome / 100)
    16. Next
    17. 'IncomeRows auswerten
    18. For Each rwIncome In DtsSettings.DailyIncome.Where(Function(x) x._Date >= Startdate AndAlso x._Date < dt1)
    19. Arrcustomers(rwIncome._Date.Day - 1) += rwIncome.CustomerCount 'tägliche Kunden aufsummieren
    20. Next
    21. For day = 0 To 29 ' Gesamt Monatsumsatz
    22. 'hier habe ich mich vertan (auch in der angehängten Solution - muss natürlich 0 to 30 heißen, um auch den Gesamtumsatz zu errechnen.
    23. For iProdGroup = 0 To groupcount - 1
    24. Arrincome(day, groupcount) += Arrincome(day, iProdGroup) 'tägliches Income je ProductGroup in die letzte Spalte("gesamt") aufsummieren
    25. Next
    26. Next
    27. End Sub


    Das Problem ist (wie du ja vielleicht siehst), dass es Werte im Array ArrIncome gibt die "0" sind.Also an einem Tag an dem es keine Einnahme gab - ists 0.Das könnte ich ja notfalls beim schreiben ins DGV auswerten, dann in der letzten Spalte ist der Gesamtumsatz. Wenn der 0 ist überspringe ich die Zeile.(Aber evtl. geht das ja eleganter)

    Und das Datum (arrdate) stellt noch ein Problem dar. Denn wenn das Datum in der entsprechenden DailyIncomeRow nicht gefunden wurde (also Sonntag der 03.06.2012 z.B.), so wird mir der 01.01.0001 in mein Datumsarray - Arrdate - geschrieben. Auch das müsste ich beim rausschreiben ja auswerten. Was ja ebenfalls geht (weiß nicht ob 01.01.0001 nothing entspricht) - aber notfalls kann ich ja beim Schreiben der Datumswerte in die erste Spalte des DGV ebenfalls den Inhalt prüfen:

    VB.NET-Quellcode

    1. For i = 0 to ArrDates.GetLength -1
    2. If arrdates(i)<> 01.01.0001 then 'oder eben not is nothing
    3. DGVEvaluation.Rows.Add(ArrDates(i).ToString("ddd dd.MM"))
    4. next


    Allerdings frage ich mich wie gesagt, ob es so richtig ist diese beiden Punkte ("0 Einnahmen" und "leere Daten") beim schreiben ins DGV auszuwerten, oder ob es eine Möglichkeit gibt, diese Daten garnicht erst ins Array zu schreiben.
    Dateien

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „DerSmurf“ ()

    ich hab den Unterschied "0 Einnahme", "leere Daten" nicht wirklich kapiert.
    Ich hab in MonatAlt gesehen, dass die Sonntage weggelassen sind - vielleicht meinst du ja das damit.

    Ich hab jetzt was gebastelt, was die Sonntage nicht weglässt, aber Zellen mit 0 leer lässt.
    Finde ich übersichtlicher, weil das strukturiert die Monats-Ansicht in Wochen.



    Übrigens

    DerSmurf schrieb:

    weiß nicht ob 01.01.0001 nothing entspricht
    stimmt genau.
    Das hängt mit dem Unterschied von ReferenzTyp und ValueTyp zusammen. Date ist ein ValueTyp, und kann deswegen nicht Nothing werden - es nimmt stattdessen einen Standard-Wert an.
    Dateien
    Huhu.
    Das haut so leider nicht hin.

    ErfinderDesRades schrieb:

    ich hab den Unterschied "0 Einnahme", "leere Daten" nicht wirklich kapiert.

    Ich meine damit, dass Daten (Datumswerte), welche keine Tageseinnahme haben, nicht im DGV auftauchen sollen.
    Also am Beispiel Juni 2012 - der 03.06.2012 (Sonntag) hat keine Einnahme, das Datum 03.06.12 soll damit auch nicht im DGV auftauchen.
    Allerdings liegt dies NICHT daran, dass es ein Sonntag ist, sondern, dass es eben keine Einnahme gibt.
    Es gibt ja zum Beispiel noch Feiertage - also reguläre Wochentage ohne Einnahme, welche folglich auch nicht im DGV auftauchen sollen.
    Weiterhin gibt es verkaufsoffene Sonntage - also Sonntage mit Einnahme - diese sollten natürlich ins DGV.

    Deswegen habe ich den Ansatz gewählt, die Tagesdaten aus meinem Array ins DGV zu schreiben, weil ich ja nur über mein DataSet herausfinde, welche Tagesdaten es gibt.

    Nur habe ich hier eben das Problem bei der Befüllung.
    Ich schreibe mir ja in mein Datumsarray für jeden Tag ohne Einnahme ein Nothing.
    Auch mein ArrIncome enthält Zeilen in denen alle Werte 0 sind.

    Dies stellt ja erstmal kein Problem dar - denn ich kann ja (wie oben gezeigt), beim Schreiben der Daten ins DGV auf "0" und auf nothing Dates prüfen und das Schreiben der Zeile entsprechend überspringen. (muss ich ja eh - aufgrund der unbekannten Arraygröße)
    Aber da Frage ich mich halt, ob es so in Ordnung geht "sinnlos" Daten ins Array zu schmeißen und diese später auszusortieren, oder obs da nicht hübscher ist, die Daten garnicht erst im Array zu haben.

    Hierzu könnte ich ja z.B. prüfen ob DailyIncome nothing ist:

    VB.NET-Quellcode

    1. For Each rwDistrTbl In distributionTables
    2. 'prüfen ob DailyIncome nothing ist
    3. If rwDistrTbl.DailyIncomeRow.IsDailyIncomeNull Then
    4. 'Schleifendurchlauf überspringen
    5. End If


    Ich Frage mich halt nur, ob das Not tut, oder ob ich diese Leerdaten nicht einfach im Array lassen soll.
    Denn so kann ich ja z.B. nicht mit "day" arbeiten - sondern muss noch einen extra Counter einbauen z.B.
    Denn wie gesagt, beim schreiben muss ich ja eh prüfen ob es eine Einnahme gibt, weil ich ja nicht weiß, wie viele Zeilen im Array beschrieben sind.
    Ich hab mir das ganze jetzt mal intensiv angeschaut.
    Aber tut mir leid, Tage ohne Einnahme da als Leerzeile geht garnicht.
    Da komm ich nicht drrauf klar.

    Edit: spricht denn etwas dagegen, den Schleifendurchlauf, beim zusammensammeln der Daten zu überspringen, wenn es an einem Datum keine Einnahme gibt (so wie in Post #49)?
    Dann verwende ich nicht mehr ​Dim day = rwDistrTbl.DailyIncomeRow._Date.Day, sondern anstelle dessen eine Zählvariable, die sich bei jedem Durchlauf (sofern Datum gefunden), um 1 erhöht und (sollte) ein Array bekommen, welches nur die relevanten Daten enthält.
    In Zeile31 enthält das Array dann die Gesamtumsätze und der Rest dazwischen ist leer.
    Das kann ich ja beim schreiben ins DGV abfangen (oder das Array in der Sub ​GetDataSummariesMonth gescheit runderdimensionieren.
    (Was ja aber bei 2D Arrays irgendwie doof ist)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „DerSmurf“ ()

    So, bin fertig.
    Läuft alles, die Ausführungszeit liegt bei 0,3 Sekunden, also top!

    Es wäre nett, wenn du mal rüber schaust, ob das so alles passt.

    und dann nerve ich mit dem nächsten, wenns ok ist. - Die Rekorde brauchen (weil nach der gleichen "Kack"Logik, wie meine ersten beiden Subs geschireben) ebenfalls ewig zum laden.
    Dateien
    naja - bischen was umgestellt, umbenannt, CustCol eliminiert habich - aber im wesentlichen so gelassen:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub FillMonthNew()
    2. 'Zeit speichern - um Sub Ausführungszeit wiederzugeben
    3. Dim Starttime = System.DateTime.Now
    4. 'Prüfen ob Eingaben in ComboBoxen numerisch sind
    5. Dim year = Integer.Parse(CBYear.Text)
    6. Dim yearcomp = Integer.Parse(CBCompare.Text)
    7. Dim month = CBMonth.SelectedIndex + 1
    8. Dim Numberofdays = Integer.Parse(DateTime.DaysInMonth(year, month).ToString)
    9. Dim Startdate = New Date(year, month, 1)
    10. Dim StartdateComp = New Date(yearcomp, month, 1)
    11. Dim groupcount = DtsSettings.ProductGroup.Count
    12. Dim NumberofdaysComp = Integer.Parse(DateTime.DaysInMonth(yearcomp, month).ToString)
    13. ClearDGV()
    14. ''das Hauptjahr
    15. Dim dailyIncomes(31, groupcount) As Double 'Zeilen/Spalten: (31 Tage + "gesamt"-Zeile / groupcount ProductGroups + "gesamt"-Spalte)
    16. Dim dailyCustomers(31) As Integer
    17. GetDataSummariesMonth(Startdate, dailyIncomes, dailyCustomers)
    18. '' das Vergleichsjahr
    19. Dim dailyIncomesComp(31, groupcount) As Double 'Zeilen/Spalten: (31 Tage + "gesamt"-Zeile / groupcount ProductGroups + "gesamt"-Spalte)
    20. Dim dailyCustomersComp(31) As Integer
    21. GetDataSummariesMonth(StartdateComp, dailyIncomesComp, dailyCustomersComp)
    22. 'schreiben der Daten ins DGV
    23. CreateDgvColumns(dailyIncomes)
    24. FormatDGV()
    25. FillDgvMonth(Startdate, dailyIncomes, dailyCustomers)
    26. DGVEvaluation.Rows.Add("%")
    27. Const SumRow = 31
    28. CompareMonth(dailyIncomes, dailyCustomers, dailyIncomesComp, dailyCustomersComp, groupcount, yearcomp, SumRow)
    29. 'Pro Kopf Umsatz Hauptjahr
    30. PCS(dailyIncomes(SumRow, groupcount), dailyCustomers(SumRow), 0)
    31. 'Kundenschnitt Hauptjahr
    32. CustAVG(NumberofdaysComp, dailyCustomers(SumRow), 1)
    33. 'Pro Kopf Umsatz Vergleichsjahr
    34. PCS(dailyIncomesComp(SumRow, groupcount), dailyCustomersComp(SumRow), DGVEvaluation.Rows.Count - 2)
    35. 'Kundenschnitt Vergleichsjahr
    36. CustAVG(NumberofdaysComp, dailyCustomersComp(SumRow), DGVEvaluation.Rows.Count - 1)
    37. DGVEvaluation.Rows.Add()
    38. ChangeSizes(DGVEvaluation.ColumnCount)
    39. 'MessageBox.Show("Ausführungszeit: " & (System.DateTime.Now - Starttime).ToString)
    40. End Sub
    41. Private Sub CustAVG(Numberofdays As Integer, monthlyCustomers As Integer, writingrow As Integer)
    42. Dim CustAvgComp As Double = 0
    43. If Numberofdays > 0 Then CustAvgComp = monthlyCustomers / Numberofdays
    44. CaptionedWriting(writingrow, "Kundenschnitt", CustAvgComp)
    45. End Sub
    46. Private Sub PCS(monthlyIncomes As Double, monthlyCustomers As Integer, writingrow As Integer)
    47. Dim PCS = 0.00
    48. If monthlyCustomers > 0 Then PCS = monthlyIncomes / monthlyCustomers
    49. CaptionedWriting(writingrow, "pro Kopf", PCS)
    50. End Sub
    51. Private Sub CaptionedWriting(row As Integer, caption As String, value As Double)
    52. Dim col = DGVEvaluation.Columns.Count - 2
    53. Dim writeCells = DGVEvaluation.Rows(row).Cells
    54. writeCells(col).Value = caption
    55. writeCells(col + 1).Value = value.ToString("0.00")
    56. End Sub
    57. Private Sub CompareMonth(dailyIncomes(,) As Double, dailyCustomers() As Integer, dailyIncomesComp(,) As Double, dailyCustomersComp() As Integer,
    58. groupcount As Integer, yearcomp As Integer, sumrow As Integer)
    59. Dim col = DGVEvaluation.Columns.Count - 3
    60. Dim WritingRow = DGVEvaluation.Rows.Count - 1
    61. '% für jede Warengruppe und Gesamtumsatz eintragen
    62. For i = 0 To groupcount
    63. DGVEvaluation.Rows(WritingRow).Cells(i + 1).Value = Math.Round(((dailyIncomes(sumrow, i) - dailyIncomesComp(sumrow, i)) / dailyIncomesComp(sumrow, i)) * 100, 2).ToString("0.00") & " %"
    64. Next
    65. '% für Kunden eintragen
    66. Dim Customercompare As Double = Math.Round(((dailyCustomers(sumrow) - dailyCustomersComp(sumrow)) / dailyCustomersComp(sumrow)) * 100, 2)
    67. DGVEvaluation.Rows(WritingRow).Cells(col).Value = Customercompare.ToString("0.00") & " %"
    68. 'Kunden % blau färben, wenn > 100
    69. If Customercompare > 0 Then
    70. With DGVEvaluation
    71. .Rows(WritingRow).Cells(col).Style.ForeColor = Color.Blue
    72. .Rows(WritingRow).Cells(col).Style.Font = New Font("Microsoft Sans Serif", 12, FontStyle.Bold)
    73. .Rows(WritingRow - 1).Cells(col).Style.ForeColor = Color.Blue
    74. .Rows(WritingRow - 1).Cells(col).Style.Font = New Font("Microsoft Sans Serif", 12, FontStyle.Bold)
    75. End With
    76. End If
    77. 'Umsätze und % blau färben, wenn > 100
    78. For i = 0 To groupcount
    79. If dailyIncomes(sumrow, i) > dailyIncomesComp(sumrow, i) Then
    80. With DGVEvaluation
    81. .Rows(WritingRow).Cells(i + 1).Style.ForeColor = Color.Blue
    82. .Rows(WritingRow).Cells(i + 1).Style.Font = New Font("Microsoft Sans Serif", 12, FontStyle.Bold)
    83. .Rows(WritingRow - 1).Cells(i + 1).Style.ForeColor = Color.Blue
    84. .Rows(WritingRow - 1).Cells(i + 1).Style.Font = New Font("Microsoft Sans Serif", 12, FontStyle.Bold)
    85. End With
    86. End If
    87. Next
    88. DGVEvaluation.Rows.Add()
    89. DGVEvaluation.Rows.Add(yearcomp.ToString)
    90. WritingRow += 2
    91. 'Gesamtumsätze für jede Warengruppe (Vergleichsjahr) eintragen
    92. For i = 0 To groupcount
    93. DGVEvaluation.Rows(WritingRow).Cells(i + 1).Value = dailyIncomesComp(sumrow, i).ToString("#,##0.00")
    94. Next
    95. 'Gesamtkunden(Vergleichsjahr) eintragen
    96. DGVEvaluation.Rows(WritingRow).Cells(col).Value = dailyCustomersComp(sumrow).ToString
    97. End Sub
    Sehr schön. Danke :o)

    Nun würde ich gerne - wenn du noch Lust hast - zum letzten Punkt kommen - den statistischen Rekorden.
    Also höchste Tageseinnahme, meiste Kunden am Tag, höchste Einnahme nach Warengruppe, höchster Monatsumsatz(gesamt) und pro Warengruppe.
    Dazu habe ich wieder ein Demoprojekt rangehangen. Da die Form nichts anderes tut, als diese Daten anzuzeigen, habe ich den Code zur Anzeige eigentlich im Form Load Event.
    Da die Ausführung aber sehr, sehr lange dauert, habe ich dies auf einen Button verlegt.
    Also Demo runterladen, auf Button klicken, und das Problem ist klar.

    Darüberhinaus hätte ich gerne eine Änderung, aber ich glaube, dass dies meinen gesamten Code überflüssig macht und eine Änderung am DataSet nach sich zieht
    Ich würde gerne (zusätzlich zu angehängter Anzeige) die Funtkion einbauen, beim speichern eines neuen Umsatzes nach Rekorden zu suchen.
    Also wenn z.B. der Tagesumsatzrekord für Kategorie1 bei 100€ liegt und ich eine Einnahme von 120€ eintrage, soll dies gemeldet werden.
    Holla - neuer Rekord
    alt 100€ am 01.11.2012
    neu 120€ am 14.06.2020
    Ist es hierfür erforderlich (oder sinnvoll) die Rekorde im DataSet zu speichern?
    Denn dann brauche ich ja nur zu prüfen, ob die neu eingetragene Einnahme größer ist, als der gespeicherte Rekord, und fertig. Auch brauche ich ja dann beim anzeigen der hier hochgeladenen Form nix rechnen, sondern die Daten nur anzeigen.
    Oder würdest du dies anders angehen?
    Dateien
    Ok. Das DataSet wird beim starten der Anwendung geladen.
    Ich habe hier etwas Sorge, dass die Ausführung der Rekordsuche merkbare Zeit in Anspruch nimmt.
    Da das Laden des DataSets ja eh etwas dauert (wenn es später Gestalt, bzw. Größe) hat, würde die Verzögerung ja größer, wenn dann auch noch gerechnet wird. Denn die Datensuche hier ist ja recht umfangreich.

    Aber wenn du sagst geht so, dann machen wir das so.

    Ich werde mich die Tage ransetzen, dieangehängte Solution, um eine Tageseinnahmeform zu erweitern (die brauchen wir ja dann), und den funktionierenden Code schon mal umzugestalten.
    Sooo, ich hab das jetzt mal umgestellt.
    Dabei habe ich die Jahresauswertung (und meinen sämtlichen alten Code) auskommentiert.
    Die Jahresauswertung ist der Teil, der die ganze Zeit verschlingt.
    Den Tagesumsatzrekord und Tageskundenrekord lasse ich im Form Load Event schon mal auf die Form malen.
    Meintest du das so?
    Dateien
    Hat leider nichts mit dem Thema direkt zu tun, da, wie EDR bereits anmerkt, gerade der zeitverschlingende Teil augenscheinlich fehlt, jedoch ist mir was im Code aufgefallen. Es ist schön, dass du fast jeder Funktion einen Kommentar verpasst, jedoch solltest du es auch so machen, dass es dir auch wirklich beim Programmieren hilft, indem du mit XML-Kommentaren arbeitest. Das lässt sich bewerkstelligen indem du, anstatt einem ' drei eintippst. VS erstellt dann automatisch einen entsprechenden Kommentarblock. Dadurch bekommst du dann beim Hovern über Funktionsaufrufe, und im IntelliSense Fenster den Kommentar angezeigt.

    Hier mal ein Vergleich:






    vs.




    SIMDoku (Simple Dokumentenverwaltung)
    Mein Lernprojekt um die verschiedensten Facetten der .NET Entwicklung zu erkunden.
    GitHub

    VB Paradise Dark Theme
    Inoffizieller VB-Paradise Discord.