Programm zur automatischen Rechnungskontrolle - welches Importformat?

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

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

    DerSmurf schrieb:

    Nun stellt sich mir aber die Frage, wie ich diese Schleife nur durch die Daten des ausgewählten Lieferanten laufen lassen kann.
    Mittels LINQ.
    Also als Anfang:

    VB.NET-Quellcode

    1. For Each SupplierSpecificArticle In Dts.Article.Where(Function(x) x.Supplier Is DoppelCastDesSupplierBindingSourceCurrent)

    Ob es das beschleunigen wurde, glaub ich nicht, da ja trotzdem erstmal die ganze Artikel-Tabelle durchgeforstet werden muss.
    Mit fällt aber gerade ein, dass es andersrum (und dann ohne LINQ) wohl etwas schneller gehen dürfte:

    VB.NET-Quellcode

    1. For Each SupplierSpecificArticle In DoppelCastDesSupplierBindingSourceCurrent.GetArticleRows

    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.
    Zu 1.
    ich glaube schon, dass es beschleunigen würde.
    Denn ich durchforste ja EINMAL und habe dann nur noch die Artikel des entsprechenden Lieferanten, welche ich dann immer und immer wieder druchforste. - Besser immer und immer wieder die Artikel eines Lieferanten als alle.

    Zu 2.

    VaporiZed schrieb:

    For Each SupplierSpecificArticle In DoppelCastDesSupplierBindingSourceCurrent.GetArticleRows

    Danke! Ich greife mir einfach von Anfang an nur die Artikel des entsprechende Lieferanten. Hätte ich auch selbst drauf kommen können.
    Soho.
    Ich bin ein wenig stolz, denn ich glaube der Code in meiner Solution ist in den Ansätzen schon ganz gut - also nicht so schlecht.

    Das einzige was unglücklich ist, ist die Aufteilung der Rechnungskontrolle auf zwei DataSets (controlwith und controlwithout), abhängig davon, ob ein Preis von der Rechnung ausgerechnet werden muss, oder nicht.
    Im Beispiel funktioniert bisher nur die Kontrolle, wenn Calculate wrong ist. Den Code für Calculate = True habe ich einfach noch nicht geschrieben.
    Hier weiß ich nicht, wie ich dies realisieren soll (außer mit den beiden DataSets), ohne permanent auf diese boolean prüfen zu müssen.

    Aber bitte gebt mir mal ein Feedback zu meinem Code.
    Eine csv zum importieren habe ich in meiner zip eingefügt.
    Diese ist keine Rechnung, sondern nur eine csv bestehend aus Bezeichnung der Reihe und Spalte. Das fand ich zum testen angenehmer.
    also: 11, 12, 13
    21, 22, 23
    usw.
    Dateien
    Ohne jetzt Ahnung von dem zu haben, was du da machst, habe ich Dir das ungeliebte Dataset mal rausgeworfen und dafür gesorgt, dass die beiden Importtabellen vor dem Import oder Speichern geleert werden.
    Dann habe ich noch den Projektnamen von "Invoie" auf "Invoice" geändert, überall wo's falsch war.

    Mappe1.csv gehört nicht zum Projekt, so etwas solltest du aber besser dem Projekt hinzufügen, dann wirds auch mit vom Projekt verwaltet. Und solche tollen Tools wie der SolutionExplorer vom @ErfinderDesRades würden es auch finden und mit sichern.

    InvoiceControl.zip
    Hallo.
    Danke für deine Mühe.
    Die csv habe ich absichtlich nicht ins Projekt integriert, da sie schlicht rein garnichts mit dem Projekt zu tuen hat.
    Es sind einfach nur hingewurschtelte Daten im csv Format. Die Date habe ich nur "mitgelifert" damit ihr Helfer nicht erst noch eine csv erstellen müsst, bevor ihr euch mein Pogramm anschauen, bzw. testen könnt.

    Das zweite DataSet ist nicht ungeliebt. Ich habe mich danach gerichtet, was ich mal zu meinen Excel Anfängen gelernt habe:
    Gleichartige Daten in ein Tabellenblatt, verschiedenartige Daten auf mehrere Blätter.
    Da ja die Rechnungskontrolle nix mit den gespeicherten Artikeln zu tun hat, habe ich mich für zwei DataSets entschieden.
    Wenn ein DataSet sinnvoller ist als zwei, nehme ich natürlich auch gerne deine Variante mit einem DataSet.
    Aber ich denke das sollte doch für den Programmablauf wurscht sein. Und da ich auch nicht vorhabe die Daten des "Rechnungskontrolle DataSets" zu speichern - ist es wohl auch für den User wurscht.
    Ungeliebt sind die beiden DataTable (ControlWith und ControlWithout) innerhalb des DataSets.
    Hier nochmal der Hintergrund etwas ausführlicher als im letzten Post:
    Manche Rechnungen haben einen Artikelpreis und das wars.
    Dieses schnapp ich mir, schmeiß ihn ins DataSet und er kann mit dem Preis des gespeicherten Artikels verglichen werden.
    Manche Rechnungen sehen aber folgendermaßen aus:
    10 (Menge) | 1,95 (Listenpreis) | 15% (Rabatt) | 16,58 (Gesamtpreis)
    Es gibt also keinen "echten" Einzelpreis.
    Daher die beiden DataTable - eins für die Berechnung der Artikepreis, eins ohne.
    Schmeiß ich beide Varianten in ein DataTable muss ich an folgenden Stellen im Code abfragen, ob gerechnet wird, oder nicht.
    Da erschien mir zwei DataTable irgendwie besser - aber das gefällt mir nicht (es sei denn jemand sagt, ist ok so):

    Hier der Code - meine Problemstellen, bzw. den eventuell Code mit einem DataTable habe ich kommentiert.
    Nun ist die Frage ein DataTable, in dem ich dann nicht verwendete Spalte (ListPrice und Discount) evtl. ausblende, oder eben zwei DataTable?

    VB.NET-Quellcode

    1. 'neue DataTable Row anlegen
    2. Dim NewItem As DtsInvoiceControl.ControlWithoutRow
    3. NewItem = DtsInvoiceControl.ControlWithout.NewControlWithoutRow()
    4. 'auslesen ob mit oder ohne rechnen
    5. If SelectedSupplier.Calculate Then 'wenn mit, prüfen ob Rabattspalte vergeben
    6. If Not SelectedSupplier.IsclmDiscountNull Then
    7. columnDiscount = SelectedSupplier.clmDiscount
    8. Else
    9. MessageBox.Show("Es wurde keine Rabatt Spalte angegeben")
    10. Exit Sub
    11. End If
    12. 'Rekontrolle mittels DtsInvoiceControl.ConrolWith - Rest wie unten, nur mit errechnung des InvoicePrice aus ListPrice abzgl. Discount
    13. Else
    14. 'Re Kontrolle ohne ausrechnen des Preises
    15. For i = 0 To DataGridView1.Rows.Count - 1 'Schleife durch jede Reihe im DGV
    16. If Not DataGridView1.Rows(i).Cells(ColumnArtNr).Value Is Nothing Then 'nur wenn es eine Art.Nr gibt
    17. If Not DataGridView1.Rows(i).Cells(ColumnPrice).Value Is Nothing Then 'und einen Preis er eine Double ist, handelt es sich um einen Artikel
    18. Dim Price As Double
    19. If Double.TryParse(DataGridView1.Rows(i).Cells(ColumnPrice).Value.ToString, Price) Then 'Prüfung ob Preis Double ist
    20. NewItem = DtsInvoiceControl.ControlWithout.NewControlWithoutRow() 'Neue DataTable Row
    21. NewItem.ArtNr = DataGridView1.Rows(i).Cells(ColumnArtNr).Value.ToString 'Ar.Nr. speichern
    22. NewItem.Name = DataGridView1.Rows(i).Cells(ColumnName).Value.ToString 'Name speichern
    23. 'If SelectedSupplier.Calculate then
    24. 'Dim ListPrice as double = Datagridview1.Rows ...
    25. 'Newitem.ListPrice = Listprice
    26. 'Dim Discount as double = Datagridview1.Rows ...
    27. 'NewItem.Discount = Discount
    28. 'NewItem.Price = Listprice - Discount / hier muss ich mir die korrekte Formel noch überlegen
    29. NewItem.InvoicePrice = Price 'Preis speichern
    30. Dim PriceDifference As Double
    31. Dim Articlefound As Boolean = False 'Konrollvariable
    32. 'Schleife durch jeden Artikel des ausgewählten Lieferanten
    33. For Each SupplierSpecificArticle In DirectCast(DirectCast(SupplierBindingSource.Current, DataRowView).Row, DtsArticles.SupplierRow).GetArticleRows
    34. If Not SupplierSpecificArticle.IsArtNrNull Then 'wenn Art.Nr. vergeben
    35. If NewItem.ArtNr = SupplierSpecificArticle.ArtNr Then 'Prüfen ob Art.Nr von Re = gespeicherte Art.Nr.
    36. NewItem.SavedPrice = SupplierSpecificArticle.PurchasingPrice 'gespeicherten Preis speichern
    37. PriceDifference = Price - NewItem.SavedPrice 'Preisdifferenz ausrechnen
    38. NewItem.Difference = PriceDifference 'Preisdifferenz speichern
    39. Articlefound = True
    40. Exit For
    41. End If
    42. End If
    43. Next
    44. If Articlefound Then 'wenn Art.Nr. gefunden
    45. If PriceDifference = 0 Then 'NewItem.Result entsprechend beschriften
    46. NewItem.Result = "korrekt"
    47. ElseIf PriceDifference > 0 Then
    48. NewItem.Result = "zu teuer"
    49. Else
    50. NewItem.Result = "zu preiswert"
    51. End If
    52. Else
    53. NewItem.Result = "nicht gefunden"
    54. End If
    55. DtsInvoiceControl.ControlWithout.Rows.Add(NewItem) 'neue Row in DataTable übernehmen
    56. End If
    57. End If
    58. End If
    59. Next
    60. End If
    61. 'If not SelectedSupplier.Calculate then
    62. ''hier muss ich jetzt die Spalten Listprice und Rabatt (Discount) ausblenden, wenn nicht gerechnet wird.
    63. 'Diese wären ja leer
    64. 'If SelectedSupplier.Calculate then
    65. 'spalten Listprice und Discunt als N2 formatieren
    66. 'DGV vom Import befreien - ans DataSet binden - und Spalten formatieren
    67. With DataGridView1
    68. .Rows.Clear()
    69. .Columns.Clear()
    70. .DataSource = DtsInvoiceControl.ControlWithout
    71. .Columns(0).Visible = False
    72. .AutoResizeColumns()
    73. .Columns(6).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
    74. .Columns(3).DefaultCellStyle.Format = "N2"
    75. .Columns(4).DefaultCellStyle.Format = "N2"
    76. .Columns(5).DefaultCellStyle.Format = "N2"
    77. End With

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