VBNET - CONFRONTO TRA DUE DATATABLE CON STRUTTURA DIVERSA

di il
4 risposte

VBNET - CONFRONTO TRA DUE DATATABLE CON STRUTTURA DIVERSA

Salve a tutti, dovrei sottrarre delle righe ad un datatable (DT1) che sono contenute in un altro datatable (DT2).

Facendo qualche ricerca ho trovato questo

        Dim dt1 As DataTable = New DataTable
        Dim dt2 As DataTable = New DataTable
        Dim dt3 As DataTable = New DataTable
        dt1.Columns.Add("Codice")
        dt2.Columns.Add("Codice")
        dt3.Columns.Add("Codice")
        Dim workRow As DataRow
        Dim i As Integer
        For i = 0 To 9
            workRow = dt1.NewRow()
            workRow("Codice") = i
            dt1.Rows.Add(workRow)
        Next
        For i = 2 To 5
            workRow = dt2.NewRow()
            workRow("Codice") = i
            dt2.Rows.Add(workRow)
        Next
        dt3 = dt1.AsEnumerable().Except(dt2.AsEnumerable(), DataRowComparer.Default).CopyToDataTable()
        dg3.DataSource = dt3

Funziona tutto a meraviglia, nel senso che in DT3 ottengo effettivamente DT1-DT2.

Però se a DT1 aggiungo un'altra colonna, quindi DT1 è diverso da DT2 a livello di struttura, la “sottrazione” non funziona più.

Mi restituisce di nuovo l'intero DT1.

       Dim dt1 As DataTable = New DataTable
       Dim dt2 As DataTable = New DataTable
       Dim dt3 As DataTable = New DataTable
       dt1.Columns.Add("Codice")
       dt1.Columns.Add("Nome")
       dt2.Columns.Add("Codice")
       dt3.Columns.Add("Codice")
       Dim workRow As DataRow
       Dim i As Integer
       For i = 0 To 9
           workRow = dt1.NewRow()
           workRow("Codice") = i
           workRow("Nome") = "Nome " & i
           dt1.Rows.Add(workRow)
       Next
       For i = 2 To 5
           workRow = dt2.NewRow()
           workRow("Codice") = i
           dt2.Rows.Add(workRow)
       Next
       dt3 = dt1.AsEnumerable().Except(dt2.AsEnumerable(), DataRowComparer.Default).CopyToDataTable()
       dg3.DataSource = dt3

Quindi, vi chiedo, per cortesia, se esiste un modo per poter dire di verificare solo sulla colonna codice (quella che hanno in comune DT1 e DT2) se esiste lo stesso valore…allora elimina l'intera riga.

Spero di essermi spiegato.

Grazie

4 Risposte

  • Re: VBNET - CONFRONTO TRA DUE DATATABLE CON STRUTTURA DIVERSA

    06/06/2023 - ato ha scritto:


    Quindi, vi chiedo, per cortesia, se esiste un modo per poter dire di verificare solo sulla colonna codice (quella che hanno in comune DT1 e DT2) se esiste lo stesso valore…allora elimina l'intera riga.

    Dai una occhiata all'implementazione proposta in fondo a questo articolo:

    Dim dt3 = (
      From d1 in dt1.AsEnumerable
      Join d2 in dt2.AsEnumerable
      On d1("Codice").ToString Equals d2("Codice").ToString
      Select d2
    ).CopyToDataTable()

    P.S.: ho riscritto solo parte del codice trovato nel post, ma non l'ho verificato con il compilatore, anche se dovrebbe rendere l'idea (pensa tu al resto).

    Ciao!

  • Re: VBNET - CONFRONTO TRA DUE DATATABLE CON STRUTTURA DIVERSA

    Se vuoi usare LINQ, devi crearti il comparatore che implementi IEqualityComparer. È sicuramente la soluzione più efficiente, se sai cosa stai facendo.

    Altrimenti vai di esercizio sscolastico: imposti un For Each sulle righe di dt1 e ci annidi un For Each sulle righe di dt2. Appena trovi corrispondenza esci dal ciclo e non aggiungi la riga a dt3. Se arrivi in fondo a dt2 senza trovare il codice allora la aggiungi. Se non hai milionate di righe non dovrebbe essere un problema. Nel caso puoi valutare di ordinare dt2 per codice ed implementare una ricerca binaria.

    Sistemi ce ne sono a carrettate.

  • Re: VBNET - CONFRONTO TRA DUE DATATABLE CON STRUTTURA DIVERSA

    06/06/2023 - Alka ha scritto:


    06/06/2023 - ato ha scritto:


    Quindi, vi chiedo, per cortesia, se esiste un modo per poter dire di verificare solo sulla colonna codice (quella che hanno in comune DT1 e DT2) se esiste lo stesso valore…allora elimina l'intera riga.

    Dai una occhiata all'implementazione proposta in fondo a questo articolo:

    Dim dt3 = (
      From d1 in dt1.AsEnumerable
      Join d2 in dt2.AsEnumerable
      On d1("Codice").ToString Equals d2("Codice").ToString
      Select d2
    ).CopyToDataTable()

    P.S.: ho riscritto solo parte del codice trovato nel post, ma non l'ho verificato con il compilatore, anche se dovrebbe rendere l'idea (pensa tu al resto).

    Ciao!

    Grande!!!!! 

    Grazie davvero :)

    Devo documentarmi di più.

    esco un attimo fuori tema, magari lo posto nella sezione database, lo scrivo qui giusto a corredo del motivo del mio post.

    Il motivo per cui ho deciso di fare con i Datatable è perchè non riesco a costruire un query con mysql che mi faccia questo :

    Ho una tabella clienti, ed una movimenti che ha il campo importo.

    Ora io vorrei estrarre tutti i clienti che da una data D1 ad un'altra data D2 hanno fatto un totale (sum(Importo)) di xeuro, ma solo in quel periodo, cioè tra D1 e D2 e non esternamente a D1 e D2.

    per esempio se D1=2002 e D2=2003 

    Mario Rossi ha i seguenti totali :

    dal 2000 al 2001 totale di 50 euro

    dal 2002 al 2003 totale di 50 euro

    Mario rossi deve essere escluso perchè ha lo stesso totale anche in altri intervalli di date (2000-2001), quindi rifiltro, con una nuova query con date esterne a D1 e D2 in un nuovo datatable e poi utilizzo il to codice per escluderlo.

    Grazie ancora.

  • Re: VBNET - CONFRONTO TRA DUE DATATABLE CON STRUTTURA DIVERSA

    Quindi la tua necessità è diversa, devi comparare tra due date ed estrarre il risultato… non devi per forza prendere i dati da una parte e l'altra, inserirle in un 3 posto e poi caricarlo….

    Ma una query tipo:

    Dim dData1 = DateTimePicker1.Value.Date
    Dim dData2 = DateTimePicker2.Value.Date
    Dim trova As New OleDbDataAdapter("SELECT * FROM tuatabella WHERE tuocampodiriferimento BETWEEN #" & dData1.ToString("MM\/dd\/yyyy 00\:00\:00") & "# AND #" & dData2.ToString("MM\/dd\/yyyy 23\:59\:59"), myConnection)

    Io almeno ho fatto così e poi ovviamente completando il codice me lo vedo su un DGV…. poi magari se è questo che cerchi puoi trovare info nel forum dove hanno gia ampiamente spiegato tutto (a me che avevo postato il problema :-) )

    o magari ho capito male io boh….

    ciao

Devi accedere o registrarti per scrivere nel forum
4 risposte