Mitgliederverwaltung - Hilfe bei der Erstellung sauberen Codes
- VB.NET
- .NET (FX) 4.5–4.8
Sie verwenden einen veralteten Browser (%browser%) mit Sicherheitsschwachstellen und können nicht alle Funktionen dieser Webseite nutzen.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Es gibt 244 Antworten in diesem Thema. Der letzte Beitrag () ist von tragl.
-
-
Ja, das geht natürlich.
Aber besser ist ja, den Grund herauszufinden, warum @ErfinderDesRades das rein gemacht hat. Muss ja einen Grund haben.
Also vielleicht sollte man ja generell einen DefaultValue festlegen.
Könnte hier mal bitte jemand mit mehr als zwei Worten antworten?
Edit zu 2:
Die Methode scheint u.a. ja mein DataSet aus der xml zu füllen.
Verwendest du hier den Pfad ..\..\DataStuff\AngelmarkenData.xml nur während der Erstellung des Programmes und änderst in dann später?
Die (ich glaube durch SolutionExplorer kpoierte) Angelmarken.xml sieht folgendermaßen aus:
<?xml version="1.0" encoding="utf-8" ?> <dtsAngelmarken xmlns="http://tempuri.org/StechuhrDts.xsd"> </dtsAngelmarken>
handelt es sich hier um einen Fehler im SolutionExplorer?
Und ich schaffe es nicht, das DataSet in die xml zu bringen.
Auf welche Form muss ich hier verweisen, und warum?
Also wie bekomme ich mein DataSet in xml?Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „DerSmurf“ ()
-
DerSmurf schrieb:
Ja, das geht natürlich.
Aber besser ist ja, den Grund herauszufinden, warum @ErfinderDesRades das rein gemacht hat. Muss ja einen Grund haben.
DerSmurf schrieb:
Also vielleicht sollte man ja generell einen DefaultValue festlegen.
DerSmurf schrieb:
Könnte hier mal bitte jemand mit mehr als zwei Worten antworten?
Naja, meinetwegen:
Es ist ja höchst angeraten, immerAllowNull=False
zu setzen, soweit es irgend geht, und bei Strings gehts immer.
Andernfalls verkompliziert sich die Datenverarbeitung enorm, weil du bei jedem(!!!!) Abruf vorher mit einer Extra-Methode erstmal prüfen musst, ob der Wert überhaupt abgerufen werden kann.
AlsoAllowNull=False
ok?
Wenn aberAllowNull=False
, und du hast keinen Defaultwert, dann macht die DataTable bei neuen DataRows eben defaultmässig immer erstmal DbNull rein.
Logisch, was sonst? hat ja kein Defaultwert.
Dummerweise gibts dann aber 5 Zeilen weiter einen Fehler, weilAllowNull=False
Übrigens kann man das alles (und noch mehr) hier nachlesen: codeproject.com/Articles/10309…l-Datamodel-for-Beginners und die beiden Folge-Artikel
Wenn du dich ans von mir gegebene Template hältst, gehts so:
DerSmurf schrieb:
Auf welche Form muss ich hier verweisen, und warum?
Meist das MainForm.
Das Form zu übergeben ist sinnvoll, wenn Eingaben nicht abgeschlossen sind - dann ruft die Save-Methode BindingSource.EndEdit auf. Und ausserdem Form.Validate - da kann man auch noch Wert-Gültigkeiten überprüfen, bevor sie gespeichert werden.
Und noch einige andere Sachen - ach - es ertönt glaub noch ein "Plink!" als Feedback, wenn erfolgeich gespeichert wurde.
Übrigens kannste die frmAngelmarken_Closed auch weglassen, wenn du das Dataset entsprechend registrierst:
Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()
-
Vielen Dank für die Erklärung und den Link!
Ich habe nun die Personenverwaltung, inklusive Speicherung, fertiggestellt.
Deine Nachfrage ob gespeichert werden soll, habe ich aber erstmal auskommentiert.
Das erscheint mir für diesen Verwendungszweck erstmal lästig. Aber kann ich ja wieder entkommentieren, wenn es hier ein Plus bringt, an das ich gerade nicht denke.
Also die TabPage Personen ist dann (erstmal) fertig. Was haltet ihr davon?
Und eine Frage wäre noch offen.
DerSmurf schrieb:
Verwendest du hier den Pfad ..\..\DataStuff\AngelmarkenData.xml nur während der Erstellung des Programmes und änderst in dann später?
Also sonst wäre ja meine DataSet.xml zwei Ordner über der exe. Das wäre ja komisch. -
ErfinderDesRades schrieb:
ach - es ertönt glaub noch ein "Plink!
Danke, ich hatte mich auf dem Firmen-PC schon gefragt, wo die dusseligen Sounds her kommen - bei mir daheim sind die Systemsounds ausgeschaltet
Konnte ich damit dann auch mal rausnehmen
Vorweg: bei mir ist die Solution nicht lauffähig - die Helpers sind nicht korrekt eingebunden - selbst wenn ich die Verweise auf
GeneralHelpers
undWinFormHelpers
aktualisiere erhalte ich fehler:
@DerSmurf:
Ich hab deine KeyPress mal in KeyDown zusammengefasst:
VB.NET-Quellcode
- Private Sub frmAngelmarken_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
- If e.KeyCode = Keys.K AndAlso e.Modifiers = Keys.Control Then
- If TCMain.SelectedTab Is TPPersons Then PersonCopy()
- e.SuppressKeyPress = True
- End If
- If Me.TBPersonSearch.Focused Then
- e.SuppressKeyPress = True
- End If
- Select Case e.KeyCode
- Case Keys.Escape : If TCMain.SelectedTab Is TPPersons Then DelPersonSearch()
- Case Keys.Delete : If TCMain.SelectedTab Is TPPersons Then PersonDelete()
- Case Keys.Back
- If TCMain.SelectedTab Is TPPersons Then
- If TBPersonSearch.Text.Length > 0 Then TBPersonSearch.Text = TBPersonSearch.Text.Substring(0, TBPersonSearch.Text.Length - 1)
- End If
- e.SuppressKeyPress = True
- End Select
- End Sub
Das hier kann ich mir nicht erklären - sollte doch automatisch passieren, wenn die Textbox selektiert ist oder?
BindingSource.FilterX kannste wie folgt nutzen:
PersonBindingSource.FilterX("Name LIKE *?* OR Vorname LIKE *?*", TBPersonSearch.Text, TBPersonSearch.Text)
StattExit Sub
nimmst duReturn
StattPersonBindingSource.RemoveCurrent()
müsste glaub sinnvollerweise die Row gelöscht werden:Person.Delete
StattPersonBindingSource
würde ich die Bs wie folgt benamen:bsPerson
@ErfinderDesRades: Ich vermisse hier dieBindingSource.At(Of TypedRow)
-Extension - hattest du die nicht mehr in den Helpers?
Und warum geht eigentlich sowas nicht?:
also dasaddpersonrow(rwOriginal)
geht, aberDim rwKopie
mit Erstellen der Kopie (damit ich die neue Row direkt griffbereit hätte) geht leider nicht..
Deine Tuple-Methode zum Kopieren einer Person versteh' ich nicht.. das wird sicher mit einer
dtsAngelmarken.Person.AddPersonRow(SelectedPerson)
gehen, die dann rausfinden und editieren...
Jo, so in etwa sähe bei mir der Code auffrmAngelmarken
aus:
Spoiler anzeigen VB.NET-Quellcode
- Imports System.ComponentModel, System.Drawing, System.Windows.Forms
- Imports Angelmarken.dtsAngelmarken
- Public Class frmAngelmarken
- #Region "Form"
- Public Sub New()
- InitializeComponent()
- Me.Text = Date.Now.ToString
- If NotifyPropertyChanged.IsInDesignMode Then Return
- ControlStyling.StyleControls(Me)
- Dts.DataFile("..\..\DataStuff\AngelmarkenData.xml").Register(Me, True).Fill
- End Sub
- Private Sub frmAngelmarken_Load(sender As Object, e As EventArgs) Handles MyBase.Load
- 'verstecken der Reiter vom Main TabControl
- With TCMain
- .SuspendLayout()
- .SizeMode = TabSizeMode.Fixed
- .ItemSize = New Size(0, 1)
- .Appearance = TabAppearance.Buttons
- .ResumeLayout()
- End With
- End Sub
- Private Sub frmAngelmarken_Closed(sender As Object, e As EventArgs) Handles Me.Closed
- Dts.Save(Me, True)
- End Sub
- Private Sub frmAngelmarken_KeyPress(sender As Object, e As KeyPressEventArgs) Handles MyBase.KeyPress
- 'Tasten in TB übergeben
- If TCMain.SelectedTab Is TPPersons Then TBPersonSearch.AppendText(e.KeyChar)
- End Sub
- Private Sub frmAngelmarken_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
- If e.KeyCode = Keys.K AndAlso e.Modifiers = Keys.Control Then
- If TCMain.SelectedTab Is TPPersons Then PersonCopy()
- e.SuppressKeyPress = True
- End If
- If Me.TBPersonSearch.Focused Then
- e.SuppressKeyPress = True
- End If
- Select Case e.KeyCode
- Case Keys.Escape : If TCMain.SelectedTab Is TPPersons Then DelPersonSearch()
- Case Keys.Delete : If TCMain.SelectedTab Is TPPersons Then PersonDelete()
- Case Keys.Back
- If TCMain.SelectedTab Is TPPersons Then
- If TBPersonSearch.Text.Length > 0 Then TBPersonSearch.Text = TBPersonSearch.Text.Substring(0, TBPersonSearch.Text.Length - 1)
- End If
- e.SuppressKeyPress = True
- End Select
- End Sub
- #End Region 'Form
- #Region "Clickables"
- Private Sub btn_Click(sender As Object, e As EventArgs) Handles BTNHome.Click,
- BTNNewSale.Click,
- BTNPersonCopy.Click,
- BTNPersonDelete.Click,
- BTNPersonDelSearch.Click,
- BTNPersonEdit.Click,
- BTNPersonNew.Click,
- BTNPersons.Click,
- BTNSettings.Click
- Select Case True
- Case sender Is BTNHome : Me.TCMain.SelectedTab = TPHome
- Case sender Is BTNNewSale : Me.TCMain.SelectedTab = TPSale
- Case sender Is BTNPersonCopy : PersonCopy()
- Case sender Is BTNPersonDelete : PersonDelete()
- Case sender Is BTNPersonDelSearch : DelPersonSearch()
- Case sender Is BTNPersonEdit : PersonEdit()
- Case sender Is BTNPersonNew : bsPerson.EditNew(Of frmEditPerson)
- Case sender Is BTNPersons : Me.TCMain.SelectedTab = TPPersons
- Case sender Is BTNSettings : Me.TCMain.SelectedTab = TPSettings
- End Select
- End Sub
- #End Region 'Clickables
- #Region "Tab Page Personen"
- Private Sub PersonEdit()
- bsPerson.EditCurrent(Of frmEditPerson)
- End Sub
- Private Sub PersonCopy()
- 'Daten der aktuell ausgewählten Person auslesen
- If bsPerson.Current Is Nothing Then Return
- Dim selectedPerson = bsPerson.At(Of PersonRow)
- dtsAngelmarken.Person.AddPersonRow(SelectedPerson)
- 'neue Row abfangen und an Edit-Dialog übergeben
- End Sub
- Private Sub PersonDelete()
- If bsPerson.Current Is Nothing Then Return
- 'ausgewählten Person auslesen
- Dim selectedPerson = bsPerson.At(Of PersonRow)
- If MessageBox.Show(Person.Vorname & " " & Person.Name & " und all seine Einkäufe werden gelöscht. " & Environment.NewLine &
- "Sind sie sicher?", "Person löschen", MessageBoxButtons.YesNo) = DialogResult.Yes Then
- selectedPerson.Delete()
- End If
- End Sub
- Private Sub DelPersonSearch()
- TBPersonSearch.Text = ""
- End Sub
- 'Filter für Personbindingsource (Suchen Textbox)
- Private Sub TBPersonSearch_TextChanged(sender As Object, e As EventArgs) Handles TBPersonSearch.TextChanged
- bsPerson.FilterX("Name LIKE *?* OR Vorname LIKE *?*", TBPersonSearch.Text, TBPersonSearch.Text)
- End Sub
- #End Region
- End Class
"Na, wie ist das Wetter bei dir?"
"Caps Lock."
"Hä?"
"Shift ohne Ende!"Dieser Beitrag wurde bereits 9 mal editiert, zuletzt von „tragl“ ()
-
Bin jetzt am Handy und lese @ErfinderDesRades Beiträge auf Codeproject, daher erstmal nur die Reaktion auf die Lauffähigkeit.
Den gleichen Fehler bekomme ich auch (auch in der Vorlage, die ich kopiert habe), wenn ich die gesamte Projektmappe erstelle.
Jedes Projekt einzeln erstellen, klappt aber wunderbar. Deswegen hab ich gedacht, dass die beiden Helper Projekt aufeinander zugreifen und deswegen ein erstellen des einen, ohne den anderen nicht möglich ist (Was ja beim kompilieren der gesamten Mappe passiert)
Hab ich falsch gedacht und immernoch ein Problem durch die Vorlage? -
DerSmurf schrieb:
Hab ich falsch gedacht und immernoch ein Problem durch die Vorlage?
jo, keine Ahnung - ist wohl eine neuere Version der Helpers als meine. Ich nutz alle Helpers in einem Separaten Helpers-Projekt und binde das in meine Projekte ein, damit läuft alles..
Edit: zur größten Not musst du Bescheid sagen, dann schick' ich dir meine Helpers rüber - könnten auch ne Teamviewer-Sitzung machen und das einmal einbauen, kann mir die Fehler grad nicht erklären.
Aber mal warten was Edr dazu sagt
"Na, wie ist das Wetter bei dir?"
"Caps Lock."
"Hä?"
"Shift ohne Ende!" -
-
-
Anbei mal meine Version.
Wie gesagt: nur die Verweise auf die eingebundenen Projekte erneuert.
Und kann sein, dass ich auch Framework-Versionen aller Projekte angeglichen hab - eine Solution läuft auch dann nicht, wenn die Helpers eine höhere Version haben als die Haupt_Anwendung.
Warum Projekte einzeln kompilieren, gemeinsam aber nicht ist mir nicht nachvollziehbar.
In meiner Welt muss eine Solution nach Nuget_restaurieren, dann Menü-Erstellen-Alles_Bereinigen, und dann Menü-Erstellen-Alles_Compilieren, laufen. -
Ja sehr schön.
Deine Solution läuft jetzt auch bei mir ohne Probleme.
Ich habe mir hieraus erstmal ein neues Template gebastelt, weil das werde ich ja später bestimmt noch brauchen.
Wenn ich das Template nun kopiere, kann ich die neue Solution auch ohne Probleme (also Gesamte Projektmappe kompilieren) laufen lassen :o)
So. Kommen wir zum Code.
1. KeyPress / Down:
Spoiler anzeigen Sinn und Zweck dieser Subs ist u.a. dass der User die Textbox nicht seleltieren muss um zu suchen.
Da es ja eh nur diese eine Stelle gibt, wo ich auf der Form was hinschreiben kann, fände ich ein selektieren lästig.
tragl schrieb:
Das hier kann ich mir nicht erklären - sollte doch automatisch passieren, wenn die Textbox selektiert ist oder?
VB.NET-Quellcode
Private Sub frmAngelmarken_KeyPress(sender As Object, e As KeyPressEventArgs) Handles MyBase.KeyPress
'Tasten in TB übergeben
If TCMain.SelectedTab Is TPPersons Then TBPersonSearch.AppendText(e.KeyChar)
End Sub
Das sorgt eben dafür, dass das geht.
Dementsprechend breche ich die Sub ab, wenn die Textbox selektiert ist (damit die Eingabe nicht doppelt erscheint).
Mein Problem mit dieser Methode im Keydown ist, dass jede Taste in der Textbox erscheint, also z.B. auch STRG. Hier würde ich nämlich:
verwenden um dass zu erreichen. Aber vielleicht gehts ja anders, oder vlt. alles zusammen im Keypress, damit ich eine der beiden Subs entfernen kann.
Ich bekomme nur die Entf Taste im Keypress irgendwie nicht abgefangen (dann könnte ich ja KeyDown entfernen):
da passiert nüscht. Wenn ich einen Haltepunkt im Keypress setze und die Entf Taste drücke, passiert nix - ich lande nicht im Code.
Mit deiner Keydown Methode, ist übrigens keine Verwendung der Tastatur mehr möglich.
2.PersonBindingSource.FilterX hab ich geändert.
3.tragl schrieb:
Statt Exit Sub nimmst du Return
Hab ich an allen Stellen geändert. Warum ist Return besser, wo ist der Unterschied? Nehme ich immer Return statt Exit Sub?
4.tragl schrieb:
Statt PersonBindingSource würde ich die Bs wie folgt benamen: bsPerson
Jo, hab ich gestern Abend in einem von EdRs codeproject Blogs gelesen und entsprechend geändert (Hier weiß ich dann ausnahmsweise mal warum ich das tun sollte :o)
5.tragl schrieb:
Statt PersonBindingSource.RemoveCurrent() müsste glaub sinnvollerweise die Row gelöscht werden: Person.Delete
Der Objektkatalog sagt zu BindingSource.RemoveCurrent : "Entfernt das aktuelle Element aus der Liste." - genau das will ich doch?
6.tragl schrieb:
Deine Tuple-Methode zum Kopieren einer Person versteh' ich nicht.. das wird sicher mit einer
dtsAngelmarken.Person.AddPersonRow(SelectedPerson) gehen, die dann rausfinden und editieren...
Das Problem hatte ich mal mit einem anderen Programm (und angehängten HelpersSmallEd). Da hat mir EdR diese Tuple Methode erklärt.
Ich weiß nicht, ob es mit den "großen" Helpers anders geht. Aber da wird sich @ErfinderDesRades bestimmt einmischen
7. Ich lade die Solution hier mal neu hoch.
Das Programm ließ sich (vor dem kopieren mit Solution Explorer) bei mir fehlerfrei kompilieren.
Wenn ich die Angelmarken.sln mit dem SolutionExplorer öffne und auf "BackupZip" klicke, und dann die Solution öffne, die sich im Ordner "BackZip" befindet öffne, erhalte ich beim kompileiren folgenden Fehler:
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets(2182,5): warning MSB3245: Dieser Verweis konnte nicht aufgelöst werden. Die "Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"-Assembly wurde nicht gefunden. Stellen Sie sicher, dass die Assembly auf dem Datenträger vorhanden ist. Falls dieser Verweis im Code erforderlich ist, können Kompilierungsfehler auftreten.
Es lässt sich aber alle kompilieren.
Die GeneralHelpers verweisen jetzt aber auf eine Newtonsoft.Json. Bei Pfad ist angegeben, dass die Referenz nicht gefunden werden kann.
Das betrifft jetzt aber nicht nur die kopierte Solution, sondern im Original taucht die gleiche Warnung (und der gleiche falsche Verweis) auf.
Also wurde durch die SolutionExplorer Kopie die Original Helpers verändert.
Wenn ich den Verweis auf die Newtonsoft.Json entfernte, läuft alles wieder.
Nachdem ich diesen Verweis jetzt entfernt habe, ist er beim erneuten kopieren auch nicht wieder aufgetaucht.
Also die Solution im Anhang läuft bei mir anstandslos (das Main Projekt auch).
Ist hier in meinem VS was falsch eingestellt, mach im Solution Explorer was falsch? Was ist hier los? -
DerSmurf schrieb:
Was ist hier los?
Newtonsoft.Json ist eine dll, die über Nuget bezogen wird.
Ich dachte, ich hätte die Nuget-Abhängigkeit aus den Helpers entfernt.
Übrigens ists ja nur ein Warning, kein Fehler.
PS: Bei dem, was du geuppt hast, ist auch alles sauber.
Das mit den Tuples scheint mir ganz korrekt so.
Bedient eine Überladung der .EditNew()-Extension, wenn man eine Vorbelegung im neuen Datensatz haben will.
Ist umständlich - kann man vlt. besser machen. Aber ich wollte mir für diese Sonderlocke nicht das Hirn kaputt-denken.
Tatsächlich ist mit meine Helpers sogar eine recht kompakte Syntax möglich:VB.NET-Quellcode
- 'statt
- With dtsAngelmarken.Person
- Dim tpls As New List(Of Tuple(Of DataColumn, Object))
- tpls.Add(Tuple.Create(Of DataColumn, Object)(.NameColumn, SelectedPerson.Name))
- tpls.Add(Tuple.Create(Of DataColumn, Object)(.StrasseColumn, SelectedPerson.Strasse))
- tpls.Add(Tuple.Create(Of DataColumn, Object)(.HausnummerColumn, SelectedPerson.Hausnummer))
- tpls.Add(Tuple.Create(Of DataColumn, Object)(.PLZColumn, SelectedPerson.PLZ))
- tpls.Add(Tuple.Create(Of DataColumn, Object)(.OrtColumn, SelectedPerson.Ort))
- BSPerson.EditNew(Of frmEditPerson)(tpls)
- End With
- ' so:
- With dtsAngelmarken.Person
- Dim tplss = TupleList.From(Of DataColumn, Object)(.NameColumn, SelectedPerson.Name)(.StrasseColumn, SelectedPerson.Strasse) _
- (.HausnummerColumn, SelectedPerson.Hausnummer)(.PLZColumn, SelectedPerson.PLZ)(.OrtColumn, SelectedPerson.Ort)
- BSPerson.EditNew(Of frmEditPerson)(tpls)
- End With
Nehme ich immer Return statt Exit Sub?
Nur die allermeisten Coder mögen Exit Sub nicht. Und Exit Function auch nicht.
Ist auch nicht so richtig wirklich ganz nachvollziehbar, warum es für dasselbe zwei verschiedene Syntaxe geben muss.
Der Objektkatalog sagt zu BindingSource.RemoveCurrent : "Entfernt das aktuelle Element aus der Liste." - genau das will ich doch?
.Remove entfernt den Datensatz, trägt aber nix in die Änderungsverfolgung ein.
Falls die Änderung auf eine Datenbank soll geht das nur mit .Delete.
Solange nur eine .xml bespielt wird ist egal, weil weg ist weg.
Achso - ein Unterschied besteht auch bei DatasetOnly, nämlich Löschweitergabe: die wird auch nur durch .Delete umgesetzt.
Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von „ErfinderDesRades“ ()
-
ErfinderDesRades schrieb:
PS: Bei dem, was du geuppt hast, ist auch alles sauber.
das hab ich doch geschrieben oO...
Was ist mit den anderen Fragen?
Und warum taucht der Verweis mal auf - und mal nicht? -
-
Ich werde mich das nächste mal etwas mehr in Geduld üben :o)
ErfinderDesRades schrieb:
.Remove entfernt den Datensatz, trägt aber nix in die Änderungsverfolgung ein.
Falls die Änderung auf eine Datenbank soll geht das nur mit .Delete.
Wenns für die xml egal ist, ists wohl besser, ich gewöhne mir .Delete an.
Dann gibts wohl später keine Hudeleien, wenn ich mal eine DB anbinden sollte. -
@DerSmurf:
Lad nochmal eine laufende Solution hoch, dann guck' ich mir mal das mit den Key-Events an und bastel' dir ggf.
noch die ein oder anderen nützlichen Helpers (Bsp.Bindingsource.At(Of TypedRow)
etc. rein.
Kann mich da morgen abend drum kümmern.
LG"Na, wie ist das Wetter bei dir?"
"Caps Lock."
"Hä?"
"Shift ohne Ende!" -
-
Da mein Code ja soweit ohne "Mängel" zu sein scheint, bis auf die Verwendungung von KeyPress und KeyDown, was ich aber ja noch später beheben kann und was keinen Einfluss auf den weiteren Code hat, mache ich über Pfingsten die Einstellungen fertig.
Also eine GUI für das Anlegen von Lieferanten, Angelmarken (Artikeln), usw.
Hier muss ich aber glaube ich vorher meine DataTable "Marke" noch verändern.
Es werden dort folgende Marken gespeichert:
1. Gruppe
Fischereiabgabe Erwachsen 1 Jahr - 12 Euro
Fischereiabgabe Erwachsen 5 Jahre - 40 Euro
Fischereiabgabemarke Kinder 1 Jahr - 2,50 Euro
Ausweis für Fischereiabgabemarke (dort werden eben die Marken eingeklebt)
Die Preise sind immer gleich, egal wann gekauft wird.
2. Gruppe
DAV Erwachsen 1 Jahr - 73 Euro
DAV Jugendliche 1 Jahr - 20 Euro
Ausweis für DAV Marken - 1 Euro
Hier sind aber eben die Preise nicht immer gleich:
Neue Mitglieder (egal ob Erwachsen oder Jugend) zahlen 5 Euro Aufnahme - Neu ist, wer im vergangenen Jahr keine Marke gekauft hat
Verzug (ab dem 01.04.) 5 Euro - wer also seine Marke nach diesem Datum kauft zahlt 5 Euro
Es wird aber nur Verzug ODER neues Mitglied berechnet. Also nur einmal 5 Euro aufgeschlagen.
3.Gruppe
Mecklenburg Karte - 10,50 Euro
Sachsen Anhalt Karte - 10,50 Euro
Hier sind die Preise auch immer gleich - verkauf erfolgt aber nur, wenn Kunde Fischereischein hat.
Für Gruppe 1 und 3 passt meine DataTable Marke ja.
Damit auch Gruppe 2 sonnvoll gespeichert werden kann, würde ich folgende Änderungen an der Table vornhemen:
Eine AllowNull Spalte "Verzugsdatum" - um zu speichern ab wann Verzug fällig ist. Mit IsMarke.VerzugsdatumNull kann ich abfragen ob überhaupt Verzug anfällt.
Decimal Spalte Verzugsgebühren - um zu speichern wie hoch der Verzug ist
Booleanspalte Neuanmeldung - True = Extrakosten für neue Mitglieder
Decimal Spalte Neuanmeldungsgebühren - um zu speichern wie hoch die Anmeldegebühren sind
Boolean Fischereischein nötig: brauche ich aktuell nur bei Sachsen Anhalt und MV. Aber wenn so kann ich das im DataSet hinterlegen und muss später nichts im Code ändern, falls man z.B. für DAV Marken auch einen Fischereischein benötigt. Oder ich mal neue Marken bekomme, die ich noch nicht habe.
Macht das für euch so Sinn, wie ich das vorhabe? -
Ich würde Marken mit Verzug als eigene Artikel einstellen.
Da dynamisch abhängig vom Heute-Datum automatisch einen Preisaufschlag berechnen - der ja per DataRelation in EinkaufPosition eingehen muss - da müsste man schon bisserl tricksen, indem man bei Programmstart codeseitig geeignete berechnete Spalten einträgt ins Dataset.
Hmm - wird auch schwierig mit Lieferung und Abrechnung.
Neues Konzept: Aufschläge jeder Art sind besondere Artikel, und werden beim Einkauf als Extra-Einkauf-Positionen zugefügt.
So wie im Supermarkt der FlaschenPfand eine Extra-Position auffm Bon ist. -
DerSmurf schrieb:
Eine AllowNull Spalte "Verzugsdatum" - um zu speichern ab wann Verzug fällig ist
und hier würd' ich nicht mit AllowNull arbeiten, sondern mit einem besonderen "Default-Datum", was du abbprüfen kannst /z.B. 01.01.1900"Na, wie ist das Wetter bei dir?"
"Caps Lock."
"Hä?"
"Shift ohne Ende!"
-
Ähnliche Themen
-
8 Benutzer haben hier geschrieben
- DerSmurf (112)
- ErfinderDesRades (62)
- tragl (60)
- VaporiZed (6)
- Dksksm (2)
- petaod (1)
- Kasi (1)
- ISliceUrPanties (1)