Hilfe bei der Entfernung einer Public Property

  • VB.NET
  • .NET 4.5

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

    Hilfe bei der Entfernung einer Public Property

    Neu

    Nabend
    Ich habe gerade schlechten Code geschrieben, da mir keine Alternative eingefallen ist.
    Es werden neue Artikel angelegt, alte Artikel kopiert und alte Artikel bearbeitet.
    Dabei gibt es eine Abfrage, ob sich der Einkaufspreis, sowie der Verkaufspreis geändert hat und die alten Preise ggf. gespeichert. Das soll aber natürlich nicht passieren, wenn ein Artikel kopiert wird. Hier sollen alter EK und alter VK DBNull bleiben.
    Folgender Code erledigt dies (ich poste nur die relevanten Auszüge):

    VB.NET-Quellcode

    1. Public Class frmEditArticle
    2. Private PurchasingPrice As Double
    3. Private RetailPrice As Double
    4. Private Sub FrmEditArticle_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    5. 'aktuellen EK und VK des geöffneten Artikels speichern
    6. Dim SelectedArticle = DirectCast(DirectCast(ArticleBindingSource.Current, DataRowView).Row, DtsSettings.ArticleRow)
    7. If Not SelectedArticle.IsPurchasingPriceNull Then PurchasingPrice = SelectedArticle.PurchasingPrice
    8. If Not SelectedArticle.IsRetailPriceNull Then RetailPrice = SelectedArticle.RetailPrice
    9. End Sub
    10. 'Sub zum speichern des Artikels
    11. Private Sub SaveArticle()
    12. If CheckUserInput() Then
    13. Me.ValidateChildren()
    14. Me.DialogResult = DialogResult.OK
    15. End If
    16. End Sub
    17. Private Function CheckUserInput() As Boolean
    18. '[...]
    19. 'Prüfen ob Art.Nr gleich ist, wenn ja - wird Artikel bearbeitet
    20. Dim SelectedArticle = DirectCast(DirectCast(ArticleBindingSource.Current, DataRowView).Row, DtsSettings.ArticleRow)
    21. If SelectedArticle.ArtNr = TBArtNr.Text Then ''Diese Abfrage ist reichlich Sinnlos. Bei meiner gebundenen Textbox ist sie natürlich immer True und taugt daher nicht als "Artikel wird kopiert Abfrage"
    22. 'Prüfen ob EK verändert wurde
    23. If Not SelectedArticle.IsPurchasingPriceNull Then
    24. If PurchasingPrice > 0 Then
    25. If Double.Parse(TBPurchasingPrice.Text) <> PurchasingPrice Then
    26. SelectedArticle.OldPurchasingPrice = SelectedArticle.PurchasingPrice
    27. SelectedArticle.LastCalculation = System.DateTime.Now
    28. End If
    29. End If
    30. End If
    31. 'Prüfen ob VK verändert wurde
    32. If Not SelectedArticle.IsRetailPriceNull Then
    33. If RetailPrice > 0 Then
    34. If Double.Parse(TBRetailPrice.Text) <> RetailPrice Then
    35. SelectedArticle.OldSellingPrice = SelectedArticle.RetailPrice
    36. SelectedArticle.LastCalculationSP = System.DateTime.Now
    37. End If
    38. End If
    39. End If
    40. End If
    41. Return True
    42. End Function
    43. End Class


    Das klappt soweit auch alles. Mein Problem ist aber, dass PurchasingPrise und ReailPrice nicht 0 sind, wenn ich einen Artikel kopiere.
    Wenn ich also Artikel1 in 100g angelegt habe, und diesen nun kopiere, um bei der Anlegung des gleichen Artikels in 250g Felder schon vorausgefüllt zu haben, habe ich auch den EK und VK des 100g Artikels in den beiden Variablen.
    Folglich erkennt mein Code eine Änderung und schreibt mir alten EK und VK. Was ja aber falsch ist, es handelt sich um einen neuen Artikel.
    Mein Plan ist also dem Kopieraufruf mitzuteilen, dass ein Artikel kopiert wird. Folgendermaßen:

    VB.NET-Quellcode

    1. Public Class FrmMainForm
    2. Public bolCopyArticle As Boolean = False
    3. 'Sub zum kopieren eines Artikels
    4. Private Sub CopyArticle()
    5. bolCopyArticle = True
    6. Dim Source = DirectCast(ArticleDataGridView.DataSource, BindingSource)
    7. 'Daten des aktuell ausgewählten Artikels auslesen
    8. If Source.Current Is Nothing Then Exit Sub
    9. Dim SelectedArticle = DirectCast(DirectCast(Source.Current, DataRowView).Row, DtsSettings.ArticleRow)
    10. 'Artikelnummer um eins erhöhen
    11. Dim ArtNr As String = increaseArtNR(SelectedArticle.ArtNr)
    12. 'Daten des Artikels an bearbeitenForm übergeben
    13. Dim tpls As New List(Of Tuple(Of DataColumn, Object))
    14. With DtsSettings.Article
    15. 'Werte die belegt sein müssen übergeben
    16. tpls.Add(Tuple.Create(Of DataColumn, Object)(.ArtNrColumn, ArtNr))
    17. tpls.Add(Tuple.Create(Of DataColumn, Object)(.Name1Column, SelectedArticle.Name1))
    18. tpls.Add(Tuple.Create(Of DataColumn, Object)(.VeColumn, SelectedArticle.Ve))
    19. tpls.Add(Tuple.Create(Of DataColumn, Object)(.ListPriceColumn, SelectedArticle.ListPrice))
    20. tpls.Add(Tuple.Create(Of DataColumn, Object)(.DiscountColumn, SelectedArticle.Discount))
    21. tpls.Add(Tuple.Create(Of DataColumn, Object)(.PurchasingPriceColumn, SelectedArticle.PurchasingPrice))
    22. tpls.Add(Tuple.Create(Of DataColumn, Object)(.SalesMarginColumn, SelectedArticle.SalesMargin))
    23. tpls.Add(Tuple.Create(Of DataColumn, Object)(.RetailPriceColumn, SelectedArticle.RetailPrice))
    24. tpls.Add(Tuple.Create(Of DataColumn, Object)(.SupplierIDColumn, SelectedArticle.SupplierID))
    25. tpls.Add(Tuple.Create(Of DataColumn, Object)(.CategoryIDColumn, SelectedArticle.CategoryID))
    26. tpls.Add(Tuple.Create(Of DataColumn, Object)(.TaxColumn, SelectedArticle.Tax))
    27. tpls.Add(Tuple.Create(Of DataColumn, Object)(.ExpiringColumn, SelectedArticle.Expiring))
    28. 'Werte die belegt sein können, übergeben, wenn gefüllt
    29. If Not SelectedArticle.IsName2Null() Then
    30. tpls.Add(Tuple.Create(Of DataColumn, Object)(.Name2Column, SelectedArticle.Name2))
    31. End If
    32. If Not SelectedArticle.IsNoteNull() Then
    33. tpls.Add(Tuple.Create(Of DataColumn, Object)(.NoteColumn, SelectedArticle.Note))
    34. End If
    35. ArticleBindingSource.EditNew(Of frmEditArticle)(tpls)
    36. End With
    37. bolCopyArticle = False
    38. End Sub

    In meiner frmEditArticle Form kann ich dann auf diese Public bolEditArticle prüfen:

    VB.NET-Quellcode

    1. Private Function CheckUserInput() As Boolean
    2. '[...]
    3. 'Prüfen ob Art.Nr gleich ist, wenn ja - wird Artikel bearbeitet
    4. If Not FrmMainForm.bolCopyArticle Then
    5. Dim SelectedArticle = DirectCast(DirectCast(ArticleBindingSource.Current, DataRowView).Row, DtsSettings.ArticleRow)
    6. If SelectedArticle.ArtNr = TBArtNr.Text Then
    7. 'Prüfen ob EK verändert wurde
    8. '[...]
    9. 'Prüfen ob VK verändert wurde
    10. '[...]
    11. End If
    12. End If
    13. Return True
    14. End Function


    Da ich aber für If Not FrmMainForm.bolCopyArticle Then und Public bolCopyArticle As Boolean = False von euch gesteinigt werde - und vermutlich auch gesteinigt gehöre - Suche ich eine Alternative. Aber mir fällt nichts ein.

    Neu

    Hätte ich nicht diese Helpers-Aufrufe vom EdR am Hals (Moment! Hab ich ja auch gar nicht :P ), würde ich der neu zu erstellenden Forminstanz die Variable als Parameter übergeben. Alternativ würde das SubForm per EventRaising nach dem Zustand bei frmMain fragen. Aber ich glaube, dass das auch mit diesem EditNew-Aufruf nicht möglich ist. Oder?
    btw: Die Benennung Deiner Forms ist … moppelt gedoppelt: FrmMainForm?
    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.

    Neu

    VaporiZed schrieb:

    würde ich der neu zu erstellenden Forminstanz die Variable als Parameter übergeben

    Ich glaube das habe ich versucht:

    VB.NET-Quellcode

    1. Public Class frmEditArticle
    2. Private EditArticle As Boolean = False
    3. Public WriteOnly Property SetEditArticle() As Boolean
    4. Set(value As Boolean)
    5. EditArticle = value
    6. End Set
    7. End Property
    8. End Class
    9. Public Class frmMainForm
    10. Private Sub CopyArticle()
    11. Dim CopyForm As New frmEditArticle
    12. CopyForm.SetEditArticle = True
    13. *[...]
    14. ArticleBindingSource.EditNew(Of Copyform)(tpls)
    15. End Property
    16. End Class

    Da meckert VS, dass CopyForm nicht deklariert sei.

    VaporiZed schrieb:

    Alternativ würde das SubForm per EventRaising nach dem Zustand bei frmMain fragen

    das verstehe ich nicht so recht.

    Neu

    @DerSmurf: Warum so umständlich? Warum machste das nicht so, wie in meinem Beispiel deiner Anwendung?:

    VB.NET-Quellcode

    1. Private Sub CustomerCopy()
    2. Dim currentCustomer = bsPerson.At(Of PersonRow) 'der zu kopierende Datensatz
    3. Dim newCustomer = Dts.Person.AddDefaultRow 'Erstellen einer Defaultrow
    4. currentCustomer.CopyTo(newCustomer) 'die Default-Row ist nun der "neue Datensatz"
    5. 'damit kannste dann alle Properties verstellen:
    6. newCustomer.Price = 0
    7. End Sub


    fertig
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    Neu

    Das löst ja aber nicht mein Problem.
    Die Default Row hat nun einen Einkaufspreis und einen Verkaufspreis.
    Wenn ich diese ändere, erkennt mein Code eine Änderung des entsprechenden Preises und schreibt den vorherigen Preis (also den der Default Row) in das Feld "alterEK", bzw. "alterVK".
    Und das soll ja nicht.

    Neu

    Dann änder' deine Prüfung ab - ist doch sicher einfacher als der 100-Zeilen-Code zum Kopieren des Datensatzes... da fällt dir sicher was besseres ein
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    Neu

    DerSmurf schrieb:

    ArticleBindingSource.EditNew(Of Copyform)(tpls)
    Nee, die Angabe (Of …) ist immer eine Typangabe, keine Instanzangabe. Ich mach sowas vom Schema her ganz old style:

    VB.NET-Quellcode

    1. Using Dialog As New Frm…
    2. Dialog.SetData(Parameter)
    3. Dialog.ShowDialog(Me)
    4. End Using
    Klar, ich kann nicht die tollen Dinge nutzen, die hinter/in den Helpers stecken. Aber is mir wurscht.

    Das mit dem EventRaising:

    VB.NET-Quellcode

    1. Private Sub SubFormAufruf()
    2. Using Dialog As New Frm…
    3. AddHandler Dialog.WillWasWissen, AddressOf AnfrageVomSubForm
    4. Dialog.SetData(Parameter)
    5. Dialog.ShowDialog(Me)
    6. RemoveHandler Dialog.WillWasWissen, AddressOf AnfrageVomSubForm
    7. End Using
    8. End Sub
    9. Private Sub AnfrageVomSubForm(sender As Object, e As WasImmerGebrauchtWirdEventArgs)
    10. e.DieBenötigteInfo = DerWertDerInfo
    11. End Sub
    12. End Class
    13. 'Im SubForm
    14. Friend Class SubForm
    15. Friend Event WillWasWissen As EventHandler(Of WasImmerGebrauchtWirdEventArgs)
    16. '…
    17. Private Sub AnfrageAnsMainForm
    18. Dim e As New WasImmerGebrauchtWirdEventArgs
    19. RaiseEvent WillWasWissen With {.sender = Me, WasImmerGebrauchtWirdEventArgs = e}
    20. If e.DieBenötigteInfo =
    21. End Sub
    22. End Class

    Aus'm Kopf heraus vom Prinzip her.
    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.

    Neu

    Nebenschauplatz: Das mit den Tuples ist eiglich im Zusammenhang mit meiner fabelhaften TupleList gedacht - damit wäre sowas möglich:

    VB.NET-Quellcode

    1. Private Sub CopyArticle()
    2. bolCopyArticle = True
    3. Dim Source = DirectCast(ArticleDataGridView.DataSource, BindingSource)
    4. 'Daten des aktuell ausgewählten Artikels auslesen
    5. If Source.Current Is Nothing Then Exit Sub
    6. Dim rwArt = DirectCast(DirectCast(Source.Current, DataRowView).Row, DtsSettings.ArticleRow)
    7. 'Artikelnummer um eins erhöhen
    8. Dim ArtNr As String = increaseArtNR(rwArt.ArtNr)
    9. 'Daten des Artikels an bearbeitenForm übergeben
    10. With Dts.Article
    11. Dim tpls = TupleList.From(Of DataColumn, Object)(.ArtNrColumn, ArtNr)(.Name1Column, rwArt.Name1)(.VeColumn, rwArt.Ve) _
    12. (.ListPriceColumn, rwArt.ListPrice)(.DiscountColumn, rwArt.Discount)(.PurchasingPriceColumn, rwArt.PurchasingPrice) _
    13. (.SalesMarginColumn, rwArt.SalesMargin)(.RetailPriceColumn, rwArt.RetailPrice)(.SupplierIDColumn, rwArt.SupplierID) _
    14. (.CategoryIDColumn, rwArt.CategoryID)(.TaxColumn, rwArt.Tax)(.ExpiringColumn, rwArt.Expiring)
    15. 'Werte die belegt sein können, übergeben, wenn gefüllt
    16. If Not rwArt.IsName2Null() Then
    17. tpls.Add(.Name2Column, rwArt.Name2)
    18. End If
    19. If Not rwArt.IsNoteNull() Then
    20. tpls.Add(.NoteColumn, rwArt.Note)
    21. End If
    22. ArticleBindingSource.EditNew(Of frmEditArticle)(tpls)
    23. End With
    24. bolCopyArticle = False
    25. End Sub
    Ungetestet, weil ich hab dein Dataset nicht.



    Den Haupt-Schauplatz, also das mit EK und VK, alter EK, neuer PurchasingPrice, und warum man eine ArticleRow kopieren muss, aber DefaultValues machen Probleme, oder doch nicht, und wat nicht alle... - das habich nicht kapiert.
    Das Datenmodell ist auch ganz anders, zB ich hab hier eine lauffähige Version, da hiess es noch Artikel.

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

    Neu

    tragl schrieb:

    Dann änder' deine Prüfung ab - ist doch sicher einfacher als der 100-Zeilen-Code zum Kopieren des Datensatzes... da fällt dir sicher was besseres ein

    Eben nicht. Denn wie soll ich - ohne eine Abfrage ob kopiert wird - herausfinden, ob sich der Einkaufspreis geändert hat?
    Wenn ich editiere steht in Article.PurchasingPrice z.B. 3,20€ - änder ich das auf 3,50€ erkennt mein Code, dass sich der Purchasing Preis geändert hat und alles gut.
    Aber wenn ich den Artikel kopiere mit gleichem PurchasingPrice von 3,20€ und ändere diesen auf 3,50€ erkennt mein Code ja die gleiche Änderung - was er aber eben bei einer Kopie nicht soll.

    Event Raising ist dann ja aber auch raus. Da muss ich ja auch vorher instanzieren :(

    Dann ist das einzige, was mir alternativ noch einfällt, eine (sinnlose) Datacolumn vom Typ boolean anzulegen.
    Diese kann ich ja wahrscheinlich in der Tuple mit übergeben. Wenn diese True ist, wird kopiert.
    Aber ist auch nicht wirklich schöner, als mein Public Mist hier.

    Edit: @ErfinderDesRades
    Die Tuples List geht in meinem Fall nicht, da ich hier nur die HelpersSmallEd dran habe.

    Zum Hauptschauplatz.
    meine Article DataTable hat folgende (hier relevanten Rows)
    .OldpurchasingPrice (alter Einkaufspreis)
    .OldSellingPrice (alter Verkaufspreis)
    .PurchasingPrice (aktueller Einkaufspreis)
    .RetailPrice (aktueller Verkaufspreis)

    Alter Einkaufspreis und alter Verkaufspreis, sollen gespeichert / geändert werden, wenn sich der aktuelle Preis ändert.
    Also aktueller Einkaufspreis ist 3,00€. Nun wirds teurer und kostet 3,20€. Wenn ich also .PurchasingPrice auf 3,20€ ändere, ändert sich automatisch .OldPurchasingPrice auf 3,00€.
    Das soll aber natürlich nur passieren wenn ich einen Artikel editiere mit Source.EditCurrent(Of frmEditArticle)
    Wenn ich einen Artikel kopiere, sollen sich .OldpurchasingPrice und .OldSellingPrice natürlich nicht ändern, denn ich gebe ja einen neuen Artikel ein.
    Also ich habe gerade einen neuen Artikel Cola 100ml für 1,20€ angelegt.
    Den kopiere ich jetzt, damit die Felder (Lieferant, Kategorie, der Name, usw.) schon ausgefüllt sind.
    Ich ändere nur den Namen in Cola 200ml - aber ich ÄNDERE ja auch .PurchasingPrice. Denn Cola 200ml kostet 2,00€.
    Nun steht aber in .OldPurchasingPrice 1,20€. soll aber nicht, denn ich hab ja nix geändert, sondern einen neuen Artikel erstellt.
    Verständlich so?

    Hier nochmal der Code (vielleicht gibt es ja doch eine Abfrage, die mir nicht einfällt): Private Sub FrmEditArticle_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub FormLoad [...]
    2. Dim SelectedArticle = DirectCast(DirectCast(ArticleBindingSource.Current, DataRowView).Row, DtsSettings.ArticleRow)
    3. If Not SelectedArticle.IsPurchasingPriceNull Then PurchasingPrice = SelectedArticle.PurchasingPrice
    4. If Not SelectedArticle.IsRetailPriceNull Then RetailPrice = SelectedArticle.RetailPrice
    5. End Sub
    6. Private Sub DieValidierungssub()
    7. 'Prüfen ob Art.Nr gleich ist, wenn ja - wird Artikel bearbeitet
    8. Dim SelectedArticle = DirectCast(DirectCast(ArticleBindingSource.Current, DataRowView).Row, DtsSettings.ArticleRow)
    9. If SelectedArticle.ArtNr = TBArtNr.Text Then
    10. 'Prüfen ob EK verändert wurde
    11. If Not SelectedArticle.IsPurchasingPriceNull Then
    12. If PurchasingPrice > 0 Then
    13. If Double.Parse(TBPurchasingPrice.Text) <> PurchasingPrice Then
    14. SelectedArticle.OldPurchasingPrice = SelectedArticle.PurchasingPrice
    15. SelectedArticle.LastCalculation = System.DateTime.Now
    16. End If
    17. End If
    18. End If
    19. 'Prüfen ob VK verändert wurde
    20. If Not SelectedArticle.IsRetailPriceNull Then
    21. If RetailPrice > 0 Then
    22. If Double.Parse(TBRetailPrice.Text) <> RetailPrice Then
    23. SelectedArticle.OldSellingPrice = SelectedArticle.RetailPrice
    24. SelectedArticle.LastCalculationSP = System.DateTime.Now
    25. End If
    26. End If
    27. End If
    28. End If
    29. End sub

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

    Neu

    ... und wenn du das im Edit-Dialog abfängst? Also z.B. beim Textbox-Leave von PurchasingPrice wird geprüft, ob der sich unterscheidet zum alten (den alten kannste ja vorher dir wegspeichern).
    Wenn ne Änderung ist, dann für OldPurchasingPrice den alten Wert eintragen und fertig.

    Also sowas hier:

    VB.NET-Quellcode

    1. Private _oldPrice As Double
    2. Private _rw As ArticleRow
    3. Private Sub frm_Load(sender as Object, e as Eventargs) Handles Me.Load
    4. Dim rw = ArticleBindingSource.At(Of ArticleRow)
    5. _rw = rw
    6. _oldPrice = _rw.OldPurchasingPrice
    7. End Sub
    8. Private Sub tb_Leave(sender As Object, e As EventArgs) Handles NeuerPreisTextbox.Leave
    9. If NeuerPreisTextbox.Text <> _oldPrice.ToString Then _rw.OldPurchasingPrice = _oldPrice
    10. End Sub


    ich krieg' das mit dem Formatieren im Forum nicht hin, wenn das nicht aus VisualStudio stammt.. egal, man wird sehen was ich damit meine denke ich ;)
    Beim Kopieren der Row verlässt du ja nicht die Textbox, weil du den Edit-Dialog garnicht offen hast. Zur Not machst ne Abfrage rein:
    - ne question ob der Preis in den alten übernommen werden soll
    - oder machst beim Kopieren ne Abfrage mit Feldeingabe, was der Preis nu sein soll

    oder oder oder
    machst ne Spalte "IsCopied" als Boolean rein und lässt die beim Kopieren eines Artikels auf True setzen, sonst überall False.
    Dann kannste das bei deiner Preisprüfung abfragen und lässt die Artikel dann eben weg.

    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    Neu

    Ist ja wurscht, ob ich das im TextBox Event, oder in meiner Speicher Sub abfrage.
    Wenn ein Artikel kopiert wird (und ich den Preis ändere), habe ich einen Eintrag für .OldPurchasingPrice.
    Denn wenn ich kopiere ArticleBindingSource.EditNew(Of frmEditArticle)(tpls) hat _rw ja auch einen PurchasingPrice.
    Wenn ich diesen nun ändere, erhalte ich einen .OldPurchasingPrice - was ich aber nicht will.
    Dieser Eintrag in .OldPurchasingPrice soll nur erfolgen, wenn ich einen Artikel bearbeite ArticleBindingSource.EditCurrent(Of frmEditArticle)

    Aber wie gesagt. In beiden Fällen hab ich ja in _rw einen .PurchasingPrice, will aber nicht immer die Änderung in .OldPurchasingPrice stehen haben.

    Neu

    DerSmurf schrieb:

    wenn ich einen Artikel bearbeite


    bearbeitest du denn einen kopierten Artikel?
    Wenn ja, dann nimm die vorgeschlagene Property "IsCopied" oder wie auch immer man die nennen mag und frag die Property dann in deiner Prüfung ab.
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    Neu

    tragl schrieb:

    bearbeitest du denn einen kopierten Artikel?

    Ja, ich bearbeite einen kopierten Artikel. Es ändert sich mindestens die Art.Nr (weil diese unique sein müssen).
    Der Name ändert sich in aller Regel auch. und eben auch der Preis in manchen Fällen.

    tragl schrieb:

    Wenn ja, dann nimm die vorgeschlagene Property

    Aber wie soll ich die Property setzen, wenn ich meine frmEditArticle nicht vorher instanziere?
    ArticleBindingSource.EditNew(Of frmEditArticle)(tpls)

    Deswegen ist ja die Property Public in der Mainform. Aber das stinkt.

    Neu

    DerSmurf schrieb:

    Aber wie soll ich die Property setzen, wenn ich meine frmEditArticle nicht vorher instanziere?


    VB.NET-Quellcode

    1. Private Sub CustomerCopy()
    2. Dim currentCustomer = bsPerson.At(Of PersonRow) 'der zu kopierende Datensatz
    3. Dim newCustomer = Dts.Person.AddDefaultRow 'Erstellen einer Defaultrow
    4. currentCustomer.CopyTo(newCustomer) 'die Default-Row ist nun der "neue Datensatz"
    5. 'damit kannste dann alle Properties verstellen:
    6. newCustomer.IsCopied = True
    7. bsPerson.Position = bsPerson.FindX("ID", newCustomer.ID) 'die neue Row als aktuelle Position setzen
    8. bsPerson.EditCurrent(Of dlgKunde)
    9. End Sub


    fertig. Da brauchst keine Tuples usw. weil die Row ja schon da is.
    Und im Edit-DIalog fragst du eben bei deiner Prüfung ab, ob das ne Kopie ist oder nicht.

    EDIT: Im Übrigen:
    weil diese unique sein müssen

    wenn deine DataColumn auf Unique eingestellt ist, musste gucken ob das Kopieren dann noch so geht (das weiß Edr sicher besser), denn dann darf ja kein Wert
    in der Kopie landen, wo Uniqe eingestellt ist.

    UNd noch ein Edit: Warum müssen Artikel-Nummern unique sein? Ich kenn das bei uns so, dass durchaus diverse Lieferanten mal die gleiche Artikelnummer für unterschiedliche Artikel nutzen.
    Bsp. Lieferant A -> Artikelnr. 123 für Pommes
    Lieferant B -> Artikelnr. 123 für CUrrywurst
    ... und jetzt hab ich Hunger, na toll :D

    Naja, gute n8
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    Neu

    DerSmurf schrieb:

    Also aktueller Einkaufspreis ist 3,00€. Nun wirds teurer und kostet 3,20€. Wenn ich also .PurchasingPrice auf 3,20€ ändere, ändert sich automatisch .OldPurchasingPrice auf 3,00€.
    Wie haste das hingekriegt, dass sich das automatisch ändert?
    Wäre es nicht besser, es würde sich unautomatisch ändern, nämlich nur wenn solle?

    Neu

    Automatisch ist wohl das falsche Wort.
    Alte EK und VK werden gespeichert, ohne dass der User das mitbekommt.
    Mit dem Code den ich oben im Spoiler untergebracht habe.
    Also im Form Load die alten EK und VK in je eine Property.
    In der Speichern Sub wird dann geprüft, ob Article.PurchasingPrice <> PurchasingPrice (Property aus LoadEvent).
    Wenn true hat sich der Preis geändert und der alte Preis wird in .OldPurchasingPrice gespeichert.
    Article.OldPurchasingPrice = PurchasingPrice

    Neu

    zunächstmal: Eiglich doof, dass PurchasingPrice + RetailPrice Nullable sind, oder? Macht den Code ziemlich umständlich und unleserlich.
    Und auf deutsch hätte ich das auch eher verstanden - aber du arbeitest sicherlich in einem internationalen Team, wo Englisch die Lingua Franca ist, oder?

    Aber jetzt ist mir das Hauptproblem wieder durch die Lappen: Wieso, wenn du mit der Tupelei da iwelche Vorbelegungen hinzauberst - wieso hat sich dann der PurchasingPrice geändert oder was auch immer?

    Ansonsten denkich fast, die arme alte EditNew(Of T)-Extension ist malwieder überfordert.
    War sie beim Tragl-Werk auch, da haben wir dann eine Variante gebastelt, der man statt des DialogForm-Typ-Parameters ein richtiges DialogForm-Objekt übergeben muss.

    Oder du musst dann eben händisch tun, was ansonsten die EditNew-Methode tut: Form instanzieren, deren Dataset registrieren, die richtige BindingSource mit dem richtigen DataRowview belegen, sonstige Vorbelegungen, modal anzeigen, DialogResult auswerten, BindingSource committen oder canceln.

    EditNew(Of T) war eben nur als ShortCut gedacht für DataRow-Edit mittels einfacher Dialoge :S

    Neu

    mir wird schwindelig mit diesen ganzen Listen, scheint jetzt sich selbst "Überlistet" zu haben.
    hier eine Idee .. erstelle doch eine Tabelle die "ArtikelHistory"
    dort schreibst du wer was wann verändert hat, eine Tabelle die sich selbst immer selbst abfragen soll wie du es gerade machst halte ich nicht für sinnvoll

    Bei gößeren Firmen ist dies immer der Fall z.b. Automobile Industrie, dort siehst du ja ab und zu eine
    ..Rückrufaktion !
    dort wird immer angegeben Model Baujahr von bis Monat
    das was der Fahrer nicht sieht ist z.b. der Turbolader aus Charge 123 wurde in 12345 Fahrzeugen verbaut, geändert wurde das Teil am XX.XX.XXXX
    für diese Bauteil kann aber auch eine sogenannte "TeilHistory" abgefragt werden

    und jetzt brauch ich einen Kaffee

    Neu

    Zu Bennenung und Nullable:
    Spoiler anzeigen

    ErfinderDesRades schrieb:

    zunächstmal: Eiglich doof, dass PurchasingPrice + RetailPrice Nullable sind, oder? Macht den Code ziemlich umständlich und unleserlich.
    Und auf deutsch hätte ich das auch eher verstanden - aber du arbeitest sicherlich in einem internationalen Team, wo Englisch die Lingua Franca ist, oder?

    Bei dem Projekt hier handelt es sich um eins meiner ersten. Ich mache seid ca. anderthalb Jahren an dem Teil rum, verwende es aber auch seid ca. 1 Jahr im Laden.
    Wenn ich das ganze neu machen würde - und das werde ich irgendwann müssen, würde ich einiges anders machen.
    Es sind alle! Spalten in der DataTable nullable und es ist im DataSet alles englisch, weil ichs damals nicht besser wusste.
    Auch ist die Benennung an sich schlecht (egal in welcher Sprache). Aber ich denke wie gesagt neu machen ist hier besser.
    Daher das Angelmarken Lernprojekt, damit ich überhaupt weiß auf was ich beim sauberen Coden achten muss.
    Aber ich denke mir, wenn schon schlecht, dann wenigstens Konsequent. Ich kann mich dann z.B. darauf verlassen, dass mein Programm abschmiert, wenn ich die DBNull Prüfung vergesse. Immer.


    Ich versuche dir das Problem am Beispiel zu erläutern:
    Bild1: zeigt die Form nach BS.EditNew(of frmEditArticle) nachdem ich da Daten reingeschrieben habe.
    Wenn ich nun speichere und den Artikel wieder öffne BS.EditCurrent(of frmEditArticle ist .OldPurchasingPrice und .OldSellingPreice DBNull. Das ist erwünscht.

    Bild2: zeigt die Form nach BS.EditNew(of frmEditArticle) (Tuple)
    Ich möchte nun das gleiche Futter in 2,5kg anlegen. Das kostet aber natürlich mehr, ich ändere EK und VK vor dem speichern.
    Wenn ich den Artikel jetzt speichere und öffne - Bild3 - stehen da bei den alten Preisen EK und VK von Hundefutter mit Ente 1kg.
    Das ist aber wie gesagt nur so erwünscht, wenn sich der Preis tatsächlich ändert.
    Also nur wenn ich einen Artikel mit EditCurrent aufrufe, und an einem Artikel etwas ändere, soll der alte Preis gespeichert werden.#

    Ich finde aber auf der Form (in den Daten der Form) keinen logischen unterschied, ob ich sie nun mit EditCurrent, oder editNew und Tuple aufgerufen habe. Also in beiden Fällen habe ich ja eine Datarow, welche einen Preis hat der sich ggf. ändert. Da kann ich ja nicht abfangen, ob bearbeitet oder kopiert wird.
    Eine Property wäre hilfreich. Wenn ich im kopieren Aufruf (EditNew mit Tuple) eine Property von frmSelectedArticle setzen könnte.
    Bilder
    • Bild1.png

      45,16 kB, 2.142×1.094, 8 mal angesehen
    • Bild 2.png

      45,67 kB, 2.142×1.094, 7 mal angesehen
    • Bild3.png

      47,4 kB, 2.142×1.094, 8 mal angesehen

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