speichern von Umsatzstatistik, wie?

  • VB.NET
  • .NET (FX) 4.5–4.8

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

    Alles klar. Danke! Werde ich versuchen umzusetzen!
    Allerdings scheitere ich gerade an "pillepalle" - wie ich zumindest dachte.
    Ich möchte einfach nur die Row mit dem höchsten Tagesumsatz, sowie die Row mit den höchsten Kunden aus:
    DSIncome.DailyIncome.
    Also das gleiche wie mit den Warengruppen, nur eben mit Gesamtumsatz und Kunden.
    Seid locker 3 Stunden, bin ich dabei meine Linq Abfrage zu schreiben, aber ich scheitere kläglich....
    Bitte helft mir
    Ich sehe nicht, dass du in irgendeiner Tabelle die Spalten "TagesUmsatz" und "Kundenhöhe" hättest. Weiter oben gibts ein Foto mit einer Tabelle "DailyIncome", aber deren Aussagen kriege ich nicht in Verbindung mit deiner neuerlichen Frage.

    Bin auch recht frustriert, dass du das vorherige Thema unerledigt gewechselt hast.
    "Werd ich versuchen umzusetzen" heisst soviel wie "mach ich später", und das wiederum heisst "mach ich nie".
    Ja und was ist denn nu mit deinen Fragen aus Post#59?
    @ErfinderDesRades
    Wenn ich schreibe "mach ich später", dann bedeutet das bei mir, nicht dass von dir behauptete, sondern schlichtweg "mach ich später".
    Vorab (weil das in einem Forum ja jeder behaupten kann), angehängt zwei Screenshots.
    Mir ging es bei meinem Post nur tierisch gegen den Strich, dass ich die scheiß (sorry) Abfrage nach Kundenrekord und Umsatzrekord nicht alleine hinbekommen habe.
    Ich schaffe es dann nicht, aufzuhören drüber nachzudenken, wie der Code auszusehen hat, auch wenn ich nach 3 Stunden probieren die weiße Fahne hisse.

    Da ich den Inhalt (bzw. den Vorteil deines Codes gegenüber meinem) deines Posts bereits beim lesen verstanden habe, war dies keine "offene Herausforderung" - für mich also nicht so wichtig (was deine Hilfe jetzt ganz und gar nicht abwerten soll).
    Also bitte verzeih, wenn ich auf deinen Post nicht (bzw. nur sehr ignorant) eingegangen bin, aber scheiß (sorry) Umsatzrekord nervt mich :(

    Die Frage aus Post 59 hat dein Code ebenfalls beantwortet, da ich ja quasi in der Group Row selbst meine Max.Funktion (für eben diese Group Row) aufrufe.
    Also reicht die eine Schleife (in der Aufrufsub For i = 1 To GroupCount), weil ich ja hier quasi für jede Group Row ihre "eigene" GetIncomeRecord Methode aufrufe. Also muss ich nicht nochmal mit einer Schleife da durch und auch den ProductGroup.Name Vergleich kann ich mir sparen, da ja der Name einfach bekannt ist.

    Bitte nochmal zu meinem aktuellen Problem:
    Ich möchte ganz einfach das gleiche wie mit den Product Groups, mit Kunden und DailyTakings erledigen.
    Also auf gleiche Art und Weise den Max Wert und das Datum aus den beiden Rows
    max Wert aus DSIncome.DailyIncome.DailyTakings / und dazu DsIncome.DailyIncome.Date
    sowie
    max Wert aus DsIncome.DailyIncome.CustomerCount / und dazu auch DsIncome.DailyIncome.date

    Ist ja letztlich das gleiche wie mit den Max Werten aus den Product Groups, nur einfacher, weil die zusätzliche DistributionTable wegfällt, aber ich bekomme es einfach nicht hin.
    Edit:
    Den Max Wert auszulesen habe ich dann doch noch geschafft:

    VB.NET-Quellcode

    1. Dim MaxValue = DSIncome.DailyIncome.Max(Function(x) x.DailyTakings)

    bzw: (Function(x) x.CustomerCount) für die Kunden
    Nun fehlt mir aber noch der Verweis auf die entsprechende Row, um das Datum auszulesen.

    Jedoch geht das im Codebehind wieder nicht...

    VB.NET-Quellcode

    1. ​Partial Class DSIncome
    2. Partial Public Class DailyIncomeRow
    3. Public Function GetMaxUmsatz() As String
    4. Dim MaxValue = Me.Max(Function(x) x.DailyTakings) 'Max ist kein Member von DsIncome.DailyIncomeRow
    5. End Function
    6. End Class
    7. End Class

    ich hör jetzt erstmal auf... macht mich wahnsinnig.
    Bilder
    • 1.jpg

      207 kB, 1.600×900, 69 mal angesehen
    • 2.jpg

      276,21 kB, 1.600×900, 66 mal angesehen

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

    DerSmurf schrieb:

    Ich möchte ganz einfach das gleiche wie mit den Product Groups, mit Kunden und DailyTakings erledigen.
    Keine Ahnung, was du meinst. Was hast du denn mit den ProductGroups erledigt, und wie?
    Ich habe hier, was ich für dein Datenmodell halte:

    Ist das, worauf du dich beziehst?
    Weil wie gesagt, da gibts keine Kunden oder Kundenhöhen - allenfalls ein Kundenaufkommen vermeine ich zu erkennen.
    Aber zeig doch nochmal (anhand eines aktuellen Datenmodell-Bildles), welches Problem du wie gelöst hast, und erklär nochmal anhand eines aktuellen Datenmodell-Bildles, was nun das aktuelle Problem ist.
    Hmm. Ich weiß nicht wie ichs anders beschreiben soll, aber ich versuchs mal.
    Ich beziehe mich auf das DataSet, welches du im letzten Post angehängt hast.

    In DailyIncome speichere ich folgendes:
    CustomerCount: Kunden (für diesen Tag)
    DailyTakings: die Tageseinnahme
    Date: das entsprechende Datum
    Also am 10.01.2020 hatte ich 1700 Kunden und 9.450€ (Gesamt-) Umsatz

    In der Distribution Table:
    DailyIncomeID: der Verweis auf "Date" in DailyIncome
    ProductGroupID: Verweis auf "ProductGroup.Name"
    ProductGroupIncome: die Tageseinnahme pro Produktgruppe

    und ProductGroup ist selbsterklärend.

    Ich möchte nun, den einen Tag herausfinden, an dem es den meisten (Gesamt-) Umsatz gab, sowie diesen Umsatz und den Tag mit den meisten Kunden, sowie die entsprechende Kundenzahl.
    Also das Maximum aus DailyIncome.DailyTakings, und das Maximum aus DailyIncome.CustomerCount.
    UND dazu entsprechend das Datum.
    Also stell dir vor DSIncome hat nur zwei Einträge:
    1. Date = 10.01.2020
    CustomerCount = 1700
    DailyTakings = 9450
    2. Date = 11.01.2020
    CustomerCount = 1400
    DailyTakings = 10200

    So möchte ich maxUmsatz (also 10200 / am 11.01.20.20) und maxKunden(1700 am 10.01.2020) wiedergegeben haben.

    Dies hier war mein Ansatz mittels Linq den Max Umsatz auszulesen:

    VB.NET-Quellcode

    1. Dim MaxValue = DSIncome.DailyIncome.Max(Function(x) x.DailyTakings)

    Hier fehlt natürlich der Verweis auf die entsprechende DataRow, also wollte ich das ganze ins Code behind des DataSet schmeißen (wie die Warengruppen Max Umsätze).

    VB.NET-Quellcode

    1. Partial Class DSIncome
    2. Partial Public Class DailyIncomeRow
    3. Public Function GetMaxUmsatz() As String
    4. Dim MaxValue = Me.Max(Function(x) x.DailyTakings) 'Max ist kein Member von DsIncome.DailyIncomeRow
    5. End Function
    6. End Class
    7. End Class

    Und das Funktioniert eben nicht, wie im Code kommentiert. Aber ich weiß nicht warum :(

    Also bräuchte ich eine Lösung auf die DataRow zu verweisen, in einem normalen Modul (nur der vollständigkeithalber - weils mich ärgert, dass ich es nicht selber hinbekomme)
    und einmal eben die korrekte Lösung im Code behind.
    naja - Max() (also das Maximum) kann nur aus Auflistungen gebildet werden - nicht aus einer einzelnen DailyIncomeRow.
    Das sagt dir auch der Fehler: DailyIncomeRow hat keine Max-Funktion.
    Du willst ja auch das Maximum der ganzen Tabelle rausfinden.
    Eine solche Methode kannste natürlich nicht in einer Row-Klasse ansiedeln, sondern das ist Sache der Table. Also probierma so:

    VB.NET-Quellcode

    1. Partial Class DSIncome
    2. Partial Public Class DailyIncomeDataTable
    3. Public Function GetMaxUmsatz() As String
    4. Dim MaxValue = Me.Max(Function(x) x.DailyTakings) 'Max ist ein Member von DsIncome.DailyIncomeDataTable
    5. End Function
    6. End Class
    7. End Class

    Also man kann nicht nur für jede typisierte DataRow eine Partiale Klasse anlegen, sondern ebenso auch für die typDataTable-Klassen
    Huhu.
    Japp funktioniert, ich musste nur erstmal begreifen, warum der Code der Warengruppen in die Klasse "ProductGroupRow" und das hier in die "DailyIncomeDataTable" gehört- aber das habe ich glaube ich.
    Nun frage ich ich, ob es im aktuellen Beispiel - also beim Suchen des Tagesumsatzrekordes - überhaupt ein Vorteil ist, den Code ins CodeBehind auszulagern. Denn beim Warengruppenumsatz kann ich auf diese Art ja direkt auf die entsprechende Row zugreifen.
    Geht ja hier nicht. Also kann ich hier doch keinen Code sparen, oder denke ich mir da was falsches?
    So sieht mein Code jetzt aus (im "normalen" Modul - also nicht im DataSet Code):

    VB.NET-Quellcode

    1. Dim MaxValue = DSIncome.DailyIncome.Max(Function(x) x.DailyTakings)
    2. Dim TargetIncomeRow = DSIncome.DailyIncome.First(Function(x) x.DailyTakings = MaxValue)
    3. Dim _Date As Date = TargetIncomeRow._Date
    4. LBLMaxIncome.Text = (MaxValue / 100).ToString("#,##0.00 €") & " am: " & _Date.ToShortDateString


    Wenn ich diesen Code nun ins Code Behind auslagere, sieht er doch exakt genauso aus, oder kann ich da noch was ändern?

    VB.NET-Quellcode

    1. Private Sub BTNmaxUmsatzBehind_Click(sender As Object, e As EventArgs) Handles BTNmaxUmsatzBehind.Click
    2. LBLMaxIncome.Text = DSIncome.DailyIncome.GetMaxUmsatz
    3. End Sub

    VB.NET-Quellcode

    1. Partial Class DSIncome
    2. Partial Public Class DailyIncomeDataTable
    3. Public Function GetMaxUmsatz() As String
    4. Dim MaxValue = Me.Max(Function(x) x.DailyTakings)
    5. 'hier bringt mir ja der Verweis auf Me nichts, weils keine Datarow ist.
    6. 'also Me._Date oder sowas geht ja nicht
    7. 'also muss ich mir ja die DataRow wie oben holen
    8. Dim TargetIncomeRow = Me.First(Function(x) x.DailyTakings = MaxValue)
    9. Dim _Date As Date = TargetIncomeRow._Date
    10. Return ((MaxValue / 100).ToString("#,##0.00 €") & " am: " & _Date.ToShortDateString)
    11. End Function
    12. End Class
    13. End Class


    Also wenn ich mir den Code vorstelle, dann werden erst die Rows DailyIncome druchlaufen und der höchste Wert gesucht.
    Dann werden die Rows nochmal durchlaufen, bis der höchste Wert gefunden wird.
    Also zwei mal das gleiche. Das kann doch nicht gut sein - und das muss doch effektiver gehen.

    Ich habe mein Demoprojekt nochmal angehängt, könnte ja evtl. bei der Sache hilfreich sein.
    Bitte nicht an der Optik stören (und auch nicht am Sinn der Controls), das Projekt dient nur mir, damit ich den Code später in mein Hauptprojekt überfüren kann und nicht immer das komplette (Haupt)Projekt hochladen muss.
    Dateien
    • Income.zip

      (139,34 kB, 53 mal heruntergeladen, zuletzt: )

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

    Du kannst den Code natürlich insofern effizienter gestalten, dass die Tabelle nur 1x durchgegangen wird:
    Pseudocode:

    Quellcode

    1. Dim HöchsterWert = -1
    2. Dim ZeileMitHöchstemWert = Nothing
    3. For Each Zeile In DeinerTabelle
    4. Wenn Zeilenwert > HöchsterWert, dann HöchsterWert = Zeilenwert und ZeileMitHöchstemWert = Zeile
    5. Next
    6. Return ZeileMitHöchstemWert

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Es auszuprobieren dürfte schneller gehen als zu posten. Ich tippe aber auf die manuelle Schleife.

    ###########

    Die manuelle Schleife dauert bei meinem Pseudotestcode nur ca. ein Drittel solange wie die Doppel-LINQ-Geschichte.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

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

    VaporiZed schrieb:

    Es auszuprobieren dürfte schneller gehen als zu posten. Ich tippe aber auf die manuelle Schleife.

    das gilt aber nicht für mich. Bis ich einen Code geschrieben habe, der mir Daten in mein DataSet schmeißt und das dann getestet habe vergeht ein bisschen Zeit.
    Aber danke! Ich wandel dann mal deinen Pseudocode auf mein Projekt an und freu mich :)

    Danach mache ich mich dann an die Monatsrekorde, also welcher Monat hat den höchsten Gesamtumsatz, die meisten Kunden usw.
    Aber das sollte ich selber hinbekommen.

    DerSmurf schrieb:

    Nun frage ich ich, ob es im aktuellen Beispiel - also beim Suchen des Tagesumsatzrekordes - überhaupt ein Vorteil ist, den Code ins CodeBehind auszulagern.

    bezüglich dieser Frage interpretiere dann aus deinem Code, dass die Antwort "Nein" lautet.

    edit: @VaporiZed
    Ich habe auch gleich mal die Kunden in die Schleife mit rein geschmissen.
    Ich hatte hier mal was mit einem Datum, wo die Funktion mehr zurückgibt als offensichtlich. Das habe ich geändert, weil du geschrieben hast, dass man sowas nicht macht (unsauber).
    Passt das hier, wenn ich den Namen der Funktion in was gescheites ändere, oder sollte ich hier lieber zwei Funktionen draus machen?

    VB.NET-Quellcode

    1. Private Function GetIncomeRecord() As String
    2. 'Dim MaxValue = DtsSettings.DailyIncome.Max(Function(x) x.DailyIncome)
    3. 'Dim TargetIncomeRow = DtsSettings.DailyIncome.First(Function(x) x.DailyIncome = MaxValue)
    4. Dim MaxIncome = -1
    5. Dim MaxCustomers = -1
    6. Dim IncomeDate As String = Nothing
    7. Dim CustomersDate As String = Nothing
    8. For Each row In DtsSettings.DailyIncome
    9. If row.DailyIncome > MaxIncome Then
    10. MaxIncome = row.DailyIncome
    11. IncomeDate = row._Date.ToShortDateString
    12. End If
    13. If row.CustomerCount > MaxCustomers Then
    14. MaxCustomers = row.CustomerCount
    15. CustomersDate = row._Date.ToShortDateString
    16. End If
    17. Next
    18. Return ((MaxIncome / 100).ToString("##,##0.00") & "|" & IncomeDate & "|" & MaxCustomers.ToString & "|" & CustomersDate)
    19. End Function




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

    DerSmurf schrieb:

    bezüglich dieser Frage interpretiere dann aus deinem Code, dass die Antwort "Nein" lautet.
    Nein, auf diese Frage bin ich gar nicht eingegangen. Letztenendes solltest Du Dir die Frage stellen, welche Klasse für die Wiedergabe von tDS-Daten - auch in aufbereiteter Form - zuständig ist. Das tDS, welches die Daten enthält oder das Form, welches die Daten anzeigen will. Ich bin so dreist und beantworte die Frage: das tDS. Es hat die Daten. Und es ist dafür verantwortlich, diese in der Weise wiederzugeben, wie es die tDS-Nutzer (also das Form) brauchen. Das Form sollte die Daten nicht selber aufarbeiten müssen. Das degradiert sonst das tDS zu einem halbdummen Datenspeicher. Und es widerspräche dem SRP. Das Form sollte im Idealfall effektiv nur Benutzereingaben verarbeiten und Daten anzeigen, die von anderen Klassen aufbereitet zur Verfügung gestellt werden. Es koordiniert/managt also Input und Output. Aber für die Datenverarbeitung selber sollte es im Idealfall eben nicht verantwortlich sein.

    ##########

    POLA eben. Wenn die Prozedur macht, was man durch den Namen erwartet, ist das schon mal gut. Ob man das Ding jetzt noch aufspaltet, ist Dein Bier. Notwendig ist es m.E. hier nicht.
    Bzgl. des Namens: Ein Einkommensrekord. Hm. Ginge namenstechnisch halbwegs. Vielleicht alternativ GetDataAboutDayWithMaximumIncome? Lang, aber m.E. präziser.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

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

    Hmm. OK also ins tds mit dem Code.
    Das aufspalten spare ich mir dann auch, aber dann wäre ja der Name GetDataAboutDayWithMaximumIncome ebenfalls falsch, denn die Funktion gibt ja darüber hinaus noch die meisten Kunden und den Tag dazu zurück.
    Da meine Benennung insgesamt ja aber wahrscheinlich eh mehr als verwirrend ist, muss ich hier später eh nochmal ran.
    Also denk ich mir jetzt was aus und ab gehts.
    Ebenso muss ich ja dann später den Code verschieben, damit er da ist, wo er hingehört.
    Denn bei mir ist ja ziemlich alles in den Klassen der Form.
    So ihr lieben. Ich habe nun meinen Code zum finden des Monats mit den höchsten Monatsumätzen fertig.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Function GetMonthlyIncome(Groupname As String) As String
    2. 'Minimum und Maximum Jahr suchen
    3. Dim maxDate As Integer = Integer.Parse(DtsSettings.DailyIncome.Max(Function(x) x._Date).ToString("yyyy"))
    4. Dim minDate As Integer = Integer.Parse(DtsSettings.DailyIncome.Min(Function(x) x._Date).ToString("yyyy"))
    5. Dim _Date As Date
    6. Dim tempdate As Date
    7. Dim numberofdays As Integer
    8. Dim groupcount As Integer = DtsSettings.ProductGroup.Count
    9. Dim MonthlyIncome As Integer
    10. Dim MaxIncome As Integer
    11. Dim DateofMaxIncome As Date
    12. '1. Schleife für jedes Jahr
    13. For i = minDate To maxDate
    14. '2. Schleife für jeden Monat
    15. For j = 1 To 12
    16. 'Datum zusammenbauen
    17. _Date = Date.Parse("01." & j & "." & i)
    18. 'Anzahl der Tage für aktuellen Monat auslesen
    19. numberofdays = Integer.Parse(DateTime.DaysInMonth(i, j).ToString)
    20. '3. Schleife für jeden Tag des Monats
    21. For k = 0 To numberofdays - 1
    22. 'ausgewähltes Jahr
    23. tempdate = _Date.AddDays(k)
    24. 'Datum in den Einnahmen suchen
    25. Dim IncomeRow = DtsSettings.DailyIncome.FirstOrDefault(Function(x) x._Date.Date = tempdate)
    26. If IncomeRow Is Nothing Then Continue For 'Wenn nicht gefunden, nächster Durchgang
    27. '4. Schleife für jede Warengruppe
    28. For L = 0 To groupcount - 1 'Schleife durch Product Group DataTable
    29. 'Name aus BindingSource lesen
    30. Dim ProductGroup = DirectCast(DirectCast(ProductGroupBindingSource(L), DataRowView).Row, DtsSettings.ProductGroupRow)
    31. If ProductGroup.Name = Groupname Then
    32. 'Warengruppenumsatz für Datum ermitteln und addieren
    33. Dim ProductGroupRow = DtsSettings.Distribution_Table.SingleOrDefault(Function(x) x.DailyIncomeRow._Date.Date = tempdate AndAlso x.ProductGroupRow.Name = groupname)
    34. If ProductGroupRow Is Nothing Then Continue For
    35. 'Umsätze addieren
    36. MonthlyIncome += ProductGroupRow.ProductGroupIncome
    37. End If
    38. Next
    39. Next
    40. If MonthlyIncome > MaxIncome Then
    41. MaxIncome = MonthlyIncome
    42. DateofMaxIncome = Date.Parse("01." & j & "." & i)
    43. End If
    44. MonthlyIncome = 0
    45. Next
    46. Next
    47. Return (MaxIncome / 100).ToString("#,##0.00 €") & "|" & DateofMaxIncome.ToString("MMMM yyyy")
    48. End Function


    Ich müsste mir doch theoretisch die 4. Schleife durch die Warengruppen sparen können, wenn ich den Code an die richtige Stelle schmeiße und ihn etwas umschreibe. Dabei bräuchte ich aber leider nochmal Hilfe.
    Da ich den Code in meinem Hauptprojekt geschrieben habe, hab ich ein Bild des aktuellen DataSets angehängt.
    Soll ich das kurz nochmal in mein Demoprojekt einbauen, oder schafft ihr das ohne Visual Studio?
    Bilder
    • DataSet.jpg

      36,14 kB, 235×492, 55 mal angesehen

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

    Eh ... what? Das ganze Konstrukt ergibt inhaltlich wenig Sinn.
    Warum gehst Du alle möglichen Datumsangaben durch, wenn Du in der Tabelle eh schon stehen hast, an welchen Tagen Du Einnahmen hast?
    Wozu benutzt Du die IncomeRow in Zeile#26/#27, wenn danach eh nix mehr kommt? Um zu wissen, ob Du Einnahmen an dem Tag hattest? Zurück zu Frage 1.
    Ich glaub, da kann man vieles mit LINQ und dem Zugriff auf die vorhandenen Datenbestände eindampfen, damit aus dem 49-Zeiler ein vielleicht 10-Zeiler wird. Aber nicht mehr heute.
    Und: Dass das doppelte LINQ 3x solange wie die manuelle For-Schleife dauert, ist praktisch irrelevant*, spart aber einige Codezeilen ein.

    * bei, ich glaub, 100000 Durchläufen ergaben sich bei mir Zeiten von 150 ms (LINQ) zu 45 (man. For). von daher: irrelevant
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    DerSmurf schrieb:

    Also wenn ich mir den Code vorstelle, dann werden erst die Rows DailyIncome druchlaufen und der höchste Wert gesucht.
    Dann werden die Rows nochmal durchlaufen, bis der höchste Wert gefunden wird.
    Also zwei mal das gleiche. Das kann doch nicht gut sein - und das muss doch effektiver gehen.
    Ja, sehr richtig - dassis ziemlich doof.
    Und da wurde dir vor laaaagnem schon eine Linq-Erweiterung empfohlen: IEnumerable(Of T).MaxBy(), die sowas abdeckt.
    Das war damals also offsichtlich verfrüht, aber jetzt ist der Zeitpunkt vielleicht geeigneter.

    Generell sind sehr sorgfältig gecodete Schleifen minimal schneller als Linq - aber das ist vollkommen uninteressant.
    Das Problem mit vielen Schleifen ist, dasses unübersichtlich wird, dass sich Fehler einschleichen und es unverständlich wird.
    @VaporiZed
    :( ich fand meinen Ansatz voll gut. Da ich ja keine Ahnung habe in welcher Reihenfolge die Daten in meinem DataSet auftauchen, dachte ich mir ich gehe systematisch nach Datum durch.
    Wenn ich das DataSet nach Inhalt durchgehe, muss ich ja prüfen, um welchen Monat es sich handelt damit mir der Monatsumsatz korrekt zusammengerechnet wird. Da fand ich meine Lösung voll gut.
    Die IncomeRow habe ich drin, weil ich 1. noch einen pro Kopf Umsatz ausrechnen möchte (Tages-, bzw Monatasumsätze geteilt durch Kunden) und 2. dachte ich mir, wenn es keine Tageseinnahme gibt, gibt es auch keine Warengruppeneinnahmen, also kann ich diesen Schleifendurchgang überspringen.
    Kannst du mir denn einen Ansatz für eine bessere Lösung geben?

    @ErfinderDesRades
    Zeitlich ist ja dann die Lösung mit dem doppelten durchlaufen doch nicht so schlecht, wie Vaporized gepostet hat.
    Ich erinnere mich ehrlich gesagt nicht einmal an die Linq Erweiterung, aber das was ich so finde, sucht sie mir halt nicht den höchsten Wert an sich, sondern die IncomeRow in der der höchste Wert vorkommt.
    Mein Problem ist, dass ich nur schlecht bei Google etwas zu dieser Erweiterung finde.
    Hast du da evtl. einen Link für mich? Oder eben eine kurze Erklärung.

    DerSmurf schrieb:

    Wenn ich das DataSet nach Inhalt durchgehe, muss ich ja prüfen, um welchen Monat es sich handelt

    Wo ist das Problem? Du kannst doch schreiben:

    VB.NET-Quellcode

    1. Dim RelevantRows = DtsSettings.DailyIncome.Where(Function(x) x._Date.Date.Month = DeinGewünschterMonat AndAlso x._Date.Date.Year = DeinGewünschtesJahr)

    Und dann geht's eben mit den RelevantRows weiter.
    Ok, dass Du die IncomeRow noch verwendest, war jetzt nicht aus Deinem Code rauszulesen. Das ist das Problem, wenn man nicht in anderen Projekten drinsteckt. Dann muss man filtern. Da nehm ich mir nicht die Zeit, durch das komplette Projekt durchzusteigen. Sorry :D

    DerSmurf schrieb:

    Hast du da evtl. einen Link für mich? Oder eben eine kurze Erklärung.
    In Post#58 sind die Links drin ;)

    VaporiZed schrieb:

    Das ginge noch eleganter mit einem MaxBy, entweder von MoreLINQ oder vom EdR. Oder selber gebastelt. Wie Du willst.


    Ach ja:

    DerSmurf schrieb:

    Da ich ja keine Ahnung habe in welcher Reihenfolge die Daten in meinem DataSet auftauchen, dachte ich mir ich gehe systematisch nach Datum durch.
    Du kannst die RelevantRows natürlich auch mit der LINQ-Extension OrderBy() sortieren, entweder direkt nach dem Where() oder im 2. Schritt:

    VB.NET-Quellcode

    1. Dim OrderedRows = RelevantRows.OrderBy(Function(x) x._Date)

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    DerSmurf schrieb:

    Hast du da evtl. einen Link für mich?
    Das wurde dir hier im Thread gepostet und verlinkt.
    Nochmal das Stichwort: MaxBy.

    Erklärung: Es ist eine Extension, die nicht den Maximalwert findet, sondern den Datensatz mit dem Maximalwert.
    Eben genau, was du dir selbst gebastelt hast, und was immer 2 mal durchlaufen muss.
    Die MaxBy-Extension aber läuft nur einmal durch.
    Sopp. MaxBy habe ich jetzt auch verstanden und die Links gefunden.
    Hier werde ich die Funktion von @ErfinderDesRades verwenden. Irgendwie find ich den Kerl cool.
    Und in der "Hospital" Lösung im Anhang des Links ist ja quasi alles drinne.
    Aktuell habe ich es noch nicht drin, denn da ich zur Zeit ja nur die eine Stelle habe, wo ich MaxBy verwenden würde, und es ja wie @VaporiZed aufgezeigt hat, keine relevante Geschwindigkeitseinsparung gibt, nehme ich erstmal "meine" Lösung mit insgesamt weniger Code.
    Allerdings bin ich mir sicher, dass ich diese Funktion doch noch irgendwann mal für was anderes in meinem Projekt brauchen werde.
    Dann bin ich bereit und kanns machen, ohne euch nerven zu müssen :o)

    Zum Code:
    Ich spare mir also die innerste Schleife (die Tage des Monats) und verwende dann den Code:

    VB.NET-Quellcode

    1. ​Dim RelevantRows = DtsSettings.DailyIncome.Where(Function(x) x._Date.Date.Month = DeinGewünschterMonat AndAlso x._Date.Date.Year = DeinGewünschtesJahr)

    Diese RelevantRows gehe ich dann in der zweiten Schleife (Monate) durch.

    VB.NET-Quellcode

    1. For each row in relevantrows
    2. 'Umsätze errechnen
    3. next

    Aber, dann hab ich doch genauso drei Schleifen, wie in meinem jetzigen Code. Nur dass ich, weil ich ja noch die IncomeRow verwende, für diese das gleiche erledigen muss. Ich habe dann also eine Schleife mehr.