2 Datagridview vergleichen im 1. nur die Einträge darstellen, die im 2. Fehlen

  • VB.NET
  • .NET (FX) 4.0

Es gibt 22 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    2 Datagridview vergleichen im 1. nur die Einträge darstellen, die im 2. Fehlen

    Eigentlich eine Standardaufgabe, habe aber leider weder bei Google noch hier was gefunden.
    Ich habe 2 an ein typsisiertes Dataset gebundene Datagridviews mit Suchbegriffen.
    Das Erste beinhaltet alle Suchbegriffe, das Zweite beinhaltet die dem jeweiligen Datensatz zugewiesenen Suchbegriffe.
    Ich möchte im ersten Datagridview nur die Suchbegriffe darstellen, die im 2. Datagridview fehlen.
    Unter VB6 habe ich die manuell über eine SQL- Abfrage aufgebaut, aber wie ist hier der effektivste Weg unter Beibehaltung der Datenbindung?
    Es gibt eine Tabelle Info, der sind über eine weitere Tabelle die IDs der Suchbegriffe zugeordnet und dann gibt es eine Tabelle Suchbegriffe.
    Der Nutzer soll jetzt nur noch die Suchbegriffe zuordnen können, die noch nicht zugeordnet sind.

    tbl_Info
    tbl_InfoSuchbegriffe
    tbl_Suchbegriffe
    ID_Info
    ID_Info
    InfoID_SuchbegriffID_Suchbegriff

    ID_InfoSuchbegriffSuchbegriff



    Ich glaube fast, die kommst da mit einer Tabelle aus, (die INFO, die ja die eigentlichen Daten hält).
    Füge ein Boolean Feld (z.B. "zugeordnet") hinzu und filtere im jeweiligen, zum Datagridview gehörenden Bindingsource, "zugeordnet=True", bzw "zugeordnet=false"
    Die Anzeige in den Datagridviews erfolgt über einen Joining-View.
    Du brauchst dann nur noch durch geeignet Mecanismen in der INFO-Datatbel das Feld "zugeordnet" in den gewünschten Zustand vesetzen.
    Fummle keinesfalls im Datagridview 'rum !

    Schoofi schrieb:

    n:m Beziehung
    Jo, seh ich auch so.

    Nur werde ich aus deiner Problemstellung nicht schlau:

    Schoofi schrieb:

    Ich habe 2 an ein typsisiertes Dataset gebundene Datagridviews mit Suchbegriffen.
    Das Erste beinhaltet alle Suchbegriffe, das Zweite beinhaltet die dem jeweiligen Datensatz zugewiesenen Suchbegriffe.
    Ich möchte im ersten Datagridview nur die Suchbegriffe darstellen, die im 2. Datagridview fehlen.
    Was ist mit "dem jeweiligen Datensatz" gemeint? Gibt es da noch ein 3. DGV (und wenn ja, was zeigt es an?)?
    Ah, ich verstehe. Soll dann wohl so aussehen:

    Tabelle SuchbegriffZurdnung enthält dann einen Verweis auf den zugeordneten Suchbegriff.
    Das Datagridview für die nicht zugeordneten Suchbegriff muss dann nach jeder erfolgten Zuordnung neu befüllt werden. Dies geschieht wohl am besten mit einer LINQ-Abfrage auf die Tabelle Suchbegriff, in welcher nur die Datensätze zurückggeben werden, die in der Tabelle SuchbegriffZurdnung für den jeweiligen Info-Datensatz noch nicht zugeordnet sind.
    Im Formular ist der aktuelle Datensatz der Tabelle Info schon ausgewählt und wird über Textboxen angezeigt.
    Das Datagridview mit den der Info zugeordneten Suchbegriffen wird auch richtig angezeigt.
    Das Datagridview das alle Suchbegriffe enthält muß nur noch nach den Suchbegriffen gefiltert werden, die in dem Datagridview mit den zugeordneten Suchbegriffen nicht vorkommen und da verließen sie mich.

    Bsp Info=Speiseplan zugeordnet sind Essen und Casino werden im rechten Datagrid dargestellt

    Alle anderen Suchbegriffe möchte ich im linken Datagrid darstellen, nur nicht die, die rechts schon drinstehen.
    ich würde mit Linq2Dataset was probieren.
    Also mit reinem Databinding gibts da wohl eher nix, sondern man muss zusätzlich das eine oder annere Event verarbeiten.
    Hängt auch anne Anforderung: Sollen die Fehlenden nur angezeigt werden, und bleiben dann so, oder willst du was zum Zufügen/entfernen machen, wodurch sich die Fehlenden ja ändern würden.
    Im Anhang eine Anfertigung.

    Bisserl Erläuterung dazu: LinqToDataset

    Aber paar Grundlagen sind schon erforderlich (Enums, Extensions, Lambdas, Linq, Auflistungs-Klassen zB HashSet(of T)).

    Ach zum Reingucken der Code:

    VB.NET-Quellcode

    1. Imports System.IO
    2. Imports CategoryAdministration.NorthWindDts
    3. Imports System.ComponentModel
    4. Public Class frmCategoryAdministration
    5. Public Sub New()
    6. InitializeComponent()
    7. NorthWindDts.Register(Me.AlignOnTop(), True).Fill()
    8. End Sub
    9. Private Sub Button_Click(ByVal sender As Object, ByVal e As EventArgs) _
    10. Handles SaveToolStripMenuItem.Click, ReloadToolStripMenuItem.Click, TestToolStripMenuItem.Click
    11. Select Case True
    12. Case Sender Is SaveToolStripMenuItem
    13. NorthWindDts.Save(Me)
    14. Case Sender Is ReloadToolStripMenuItem
    15. NorthWindDts.Fill()
    16. Case Sender Is TestToolStripMenuItem
    17. End Select
    18. End Sub
    19. Private _ObservedChangeTypes As New HashSet(Of ListChangedType) From {ListChangedType.ItemAdded, ListChangedType.ItemDeleted, ListChangedType.Reset}
    20. Private Sub bsArtikelKategorie_ListChanged(sender As Object, e As ListChangedEventArgs) Handles bsArtikelKategorie.ListChanged
    21. If Not _ObservedChangeTypes.Contains(e.ListChangedType) Then Return
    22. Dim otherKats = bsKategorie.All(Of KategorieRow)().Except(bsArtikelKategorie.All(Of KategorieArtikelRow).Select(Function(art) art.KategorieRow))
    23. Dim hshOtherKats = New HashSet(Of KategorieRow)(otherKats)
    24. Dim dv = TryCast(dgvOtherKategorie.DataSource, DataView)
    25. If dv.NotNull Then dv.Dispose()
    26. dv = NorthWindDts.Kategorie.Where(AddressOf hshOtherKats.Contains).AsDataView
    27. dgvOtherKategorie.DataSource = dv
    28. End Sub
    29. End Class
    Verwendet werden auch ein paar Helper-Extensions, aber das Helpers-Projekt ist ja mit im Zip

    ps: Die Funktionalität ist auf TabPage2
    Dateien

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

    Ich habe inzwischen eine relativ simple Lösung mit Linq gefunden

    VB.NET-Quellcode

    1. Dim qryInfoSuchbegriffe = From s In _InfoDB.tbl_Suchbegriffe, si In _InfoDB.tbl_A_Infos_Suchbegriffe Where s.ID_Suchbegriff = si.ID_Suchbegriff And si.ID_Info = .ID Order By s.Suchbegriff Select ID_Suchbegriff = s.ID_Suchbegriff, Suchbegriff = s.Suchbegriff
    2. Dim qrySuchbegriffe = (From s In _InfoDB.tbl_Suchbegriffe, si In _InfoDB.tbl_A_Infos_Suchbegriffe Where si.ID_Info = .ID Order By s.Suchbegriff _
    3. Select ID_Suchbegriff = s.ID_Suchbegriff, Suchbegriff = s.Suchbegriff).Except(qryInfoSuchbegriffe.AsEnumerable)
    4. With Me.dgvInfoSuchbegriffe
    5. .DataSource = qryInfoSuchbegriffe.ToList
    6. .Columns(0).Visible = False
    7. End With
    8. With Me.dgvSuchbegriffe
    9. .DataSource = qrySuchbegriffe.ToList
    10. .Columns(0).Visible = False
    11. End With
    jo, wenn keine Änderungen an den Datensätzen vorgesehen sind, geht das auch. Kann man allerdings noch stark verbessern, zB:

    VB.NET-Quellcode

    1. Dim qryInfoSuchbegriffe = From si In _InfoDB.tbl_A_Infos_Suchbegriffe Where si.ID_Info = .ID
    2. Let s = si.tbl_SuchbegriffeRow Order By s.Suchbegriff
    3. Select ID_Suchbegriff = s.ID_Suchbegriff, Suchbegriff = s.Suchbegriff
    Die Verbesserei könnte noch viieel weiter gehen, aber ich weiß nicht, ob Interesse...
    Kommt drauf an was die Verbesserungen bewirken. Wenn ich Deine Einbesserung richtig interpretiere spare ich mir einen Vergleich und kann ähnlich wie beim typisierten Dataset auf die Childrows zugreifen.

    Die Bindung macht mir noch an 2 Stellen Sorgen.
    Zum Einen mußte ich zwingend die ID mit einbinden, da sonst statt des Suchbegriffs nur die Länge des Suchbegriffs im Datagridview erschien,
    Zum Anderen habe ich nach dem Aktualisieren der Datensätze die Bindung neu setzen müssen um die Datagrids zu aktualisieren.