Wert in DataTable an erster Position hinzufügen.

  • VB.NET
  • .NET 3.5

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

    Wert in DataTable an erster Position hinzufügen.

    Hallo
    Ich exportiere aus meinem Programm die DataTable "Category" als xml mittels DataSet.DataTableName.Writexml(file).
    Die DataTable hat nur die beiden Spalten ID und Name.
    In einem anderen Programm importiere ich diese xml und füge eine Row mit dem Namen "alle" hinzu.
    Der Code hierzu sieht folgendermaßen aus:

    VB.NET-Quellcode

    1. Dim TempCategory = Application.StartupPath & "\TEMPCategory.xml"
    2. 'Temporäre Kategorien laden
    3. If File.Exists(TempCategory) Then
    4. 'alte Daten löschen
    5. DtsSettings.Category.Clear()
    6. 'neue Daten schreiben
    7. DtsSettings.Category.ReadXml(TempCategory)
    8. DtsSettings.Category.AddCategoryRow("alle")
    9. Else
    10. MessageBox.Show("Die Importdatei konnte nicht geladen werden.", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error)
    11. Exit sub
    12. End If
    13. 'Temporäre xml löschen
    14. File.Delete(TempCategory)


    Die Anzeige dieses DataTable in einem gebundenen DGV sieht nun folgendermaßen aus:
    Getränke
    Nahrungsmittel
    Zubehör
    Diverses
    alle

    Ich hätte jedoch gerne die Kategorie "alle" an oberster Stelle - also über Getränke.
    Also habe ich mir gedacht, tausche ich einfach diese beiden Zeilen:

    VB.NET-Quellcode

    1. 'neue Daten schreiben
    2. DtsSettings.Category.ReadXml(TempCategory)
    3. DtsSettings.Category.AddCategoryRow("alle")

    Allerdings kommt es dann beim Starten der Anwendung zu einem Fehler - wahrscheinlich weil eine ID doppelt belegt ist.
    Kategorie alle müsste die ID -1 haben, sowie die erste importierte Kategorie auch.
    Wie stelle ich es an, dass meine Kategorie alle die oberste Kategorie ist? Kann ich da händisch eine ID beim anlegen der Row "alle" setzen, oder macht man so etwas nicht?
    Also sowas in der Art (bringt aber auch nix - "alle" bleibt unten :(

    VB.NET-Quellcode

    1. ​ DtsSettings.Category.ReadXml(TempCategory)
    2. 'DtsSettings.Category.AddCategoryRow("alle")
    3. Dim newCategory As DtsSettings.CategoryRow
    4. newCategory = DtsSettings.Category.NewCategoryRow()
    5. With newCategory
    6. .ID = 0
    7. .Name = "alle"
    8. End With
    9. DtsSettings.Category.Rows.Add(newCategory)

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

    Manuelle Änderungen der ID sehe ich als kritisch an. Testweise könntest Du (da ein tDS bei Standardeinstellungen mit den IDs bei -1 anfängt), die alle-Zeile einfügen, deren ID danach auf 0 setzen und dann die TempCategory importieren. Da eine ID an manch anderer Stelle verwendet wird, v.a. bei Verweisen und ggf. in Datenbanken oder Backups, ist das Rumspielen an denselbigen immer kritisch. Sinnvoller ist es m.E. aber, der ganzen Tabelle eine Positionsspalte mitzugeben, die Du ggf. automatisch befüllst (von 1 beginnend aufsteigend, an der gleichen Einstellungsstelle wie bei ID; weniger Schreibarbeit) oder aber selber die Positionen der einzelnen Kategorien festlegst (mehr Flexibilität).
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Ja das ist die Frage Das mit ID 0 habe ich mir auch schon gedacht - folgender Code funktioniert:

    VB.NET-Quellcode

    1. 'alte Daten löschen
    2. DtsSettings.Category.Clear()
    3. 'neue Daten schreiben
    4. Dim newCategory As DtsSettings.CategoryRow
    5. newCategory = DtsSettings.Category.NewCategoryRow()
    6. With newCategory
    7. .ID = 0
    8. .Name = "alle"
    9. End With
    10. DtsSettings.Category.AddCategoryRow(newCategory)
    11. DtsSettings.Category.ReadXml(TempCategory)


    Jetzt ist nur die Frage, wie kritisch es ist, eine DataTable mit der ID 0 zu haben. Das müsst ihr mir sagen.
    Mit der DataTable passiert nix weiter. Sie wird nicht weiter bearbeitet - ich greife nur die Current Eigenschaft der BindingSource ab, um meine Artikel entsprechend gruppieren zu können. Das wars.
    Also musst du sagen, ob mein Code so bleiben kann - oder ob manuell ID setzen einfach ein NoGo ist - was man halt nicht macht.

    Dann mach ich es so wie du gesagt hast. Eine Sortierspalte hinzufügen, wo meine Category "alle" den Wert 0 hat, die restlichen (importieren) Spalten fangen bei 1 an und haben autoincrement +1.
    Ich kann ja bestimmt diese Sortierspalte auf- oder absteigend sortieren, auch wenn ich sie im DGV nicht anzeigen lasse.

    Edit:

    VaporiZed schrieb:

    oder aber selber die Positionen der einzelnen Kategorien festlegst (mehr Flexibilität).

    was genau meinst du hiermit?

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

    Man kann auch mit DataRowCollection.Insert(index, dr) eine DataRow dahin-operieren, wo man sie haben will.

    Generell macht Importieren Probleme, wenn in eine Tabelle importiert wird, wo schon Datensätze drinne sind - da kanns dann zu ID-Kollisionen kommen.

    Eine reservierte ID - etwa 0 für "alle" - gefällt mir auch nicht sonderlich.
    Was, wenn nun einer eine reservierte Id für "kein" haben will (kommt bei mir öfter vor)?
    Mit Kategorieposition selber festlegen meinte ist, dass Du eben ohne AutoIncrement arbeitest, sondern die Werte für die Positionierung manuell vergibst, also alle.Position = 0, Getränke.Position = 1, Nahrungsmittel.Position = 2, Zubehör.Position = 3, Diverses.Position = 4
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Ich habe nun im DataTable Category eine Spalte Position angelegt. Diese hat autoincrement, fängt bei 2 an und dann increment +1.
    Meiner eingefügten Spalte "alle" gebe ich beim Erstellen die Position 1 mit. Das geht jedoch nur mit der "normalen" Mehtode uzm hinzufügen einer DataRow, nicht mit der Variante in einer Zeile:

    VB.NET-Quellcode

    1. Dim newCategory As DtsSettings.CategoryRow
    2. newCategory = DtsSettings.Category.NewCategoryRow()
    3. With newCategory
    4. .Name = "alle"
    5. .Position = 1
    6. End With
    7. DtsSettings.Category.AddCategoryRow(newCategory)

    VB.NET-Quellcode

    1. DtsSettings.Category.AddCategoryRow("alle", 1)
    gibt mir einen Fehler bei der Überladungsauflösung, da keine zugreifbare "AddCategoryRow" diese Anzahl von Argumenten akzeptiert.


    Auf der Form, auf der dann die Kategorien angezeigt werden, lasse ich im DGV nur den Namen anzeigen (nicht die Position) und sortiere das ganze in der BindingSource nach Position:

    VB.NET-Quellcode

    1. Private Sub frmNewOrder_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    2. CategoryBindingSource.Sort = "Position"
    3. End Sub
    Wenn sie AutoIncrement ist, kannst Du sie nicht mit AddCategoryRow festlegen, richtig. Das zeigt Dir IntelliSense aber auch an. Um AutoIncrement-Spaltenwerte kümmert sich dann die AddCategoryRow-Prozedur
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Naja, es geht mit der AddCategoryRow Methode ohne Überladung.
    Aber stimmt - ich brauch ja garnix festlegen - ich kann ja auch absteigend sortieren.
    Wenn ich erst importiere und dann manuell eine Row hinzufüge, hat sie ja automatisch die höchste Position...

    Edit: ah ne kann ich nicht - dann sind die restlichen Kategorien ja verkehrt herum sortiert (im Vergleich zur Sortierung beim anlegen)
    Also werd ichs wohl so lassen wies ist. Dann ist "alle" oben und die restlichen so sortiert, wie ichs angelegt hab.

    VB.NET-Quellcode

    1. Dim newCategory As DtsSettings.CategoryRow
    2. newCategory = DtsSettings.Category.NewCategoryRow()
    3. With newCategory
    4. .Name = "alle"
    5. .Position = 1
    6. End With
    7. DtsSettings.Category.AddCategoryRow(newCategory)

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

    Kürzer ist das hier aber schon:

    VB.NET-Quellcode

    1. DtsSettings.Category.AddCategoryRow("alle")
    2. DtsSettings.Category.Last.Position = 1
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.