Sortowanie wierszy w tabeli danych


146

Mamy dwie kolumny w a DataTable, tak:

COL1   COL2
Abc    5
Def    8
Ghi    3

Próbujemy posortować to datatablewedług COL2malejącej kolejności.

COL1            COL2
ghi             8
abc             4
def             3
jkl             1

Próbowaliśmy tego:

ft.DefaultView.Sort = "COL2 desc";
ft = ft.DefaultView.ToTable(true);

ale bez użycia a DataView, chcemy posortować DataTablesam, a nie DataView.

Odpowiedzi:


355

Obawiam się, że nie można łatwo utworzyć w miejscu rodzaju DataTable, tak jak brzmi to, jakbyś chciał.

Co możesz zrobić, to utworzyć nowy DataTable na podstawie DataView utworzonego na podstawie oryginalnego DataTable. Zastosuj dowolne rodzaje i / lub filtry, które chcesz w DataView, a następnie utwórz nowy DataTable z DataView przy użyciu metody DataView.ToTable :

   DataView dv = ft.DefaultView;
   dv.Sort = "occr desc";
   DataTable sortedDT = dv.ToTable();

Chcę, aby wartość rosła pod względem wartości ceny, która jest dziesiętna. jak to zrobić?
Ranjith Kumar Nagiri

To podejście wydaje się dobre. Ale czy nie ma na to bezpośredniego sposobu? Dlaczego nie mają DataTable.sort („by”)?
Steam

28
Dzięki. Warto zauważyć, że „occr desc” tutaj, „occr” to nazwa kolumny, „desc” oznacza „malejąco”.
user1032613

22
To zadziałało dla mnie dataTable.DefaultView.Sort = "Col1, Col2, Col3". Trochę czysty kod.
Sai

7
Podobnie jak @Sai, możesz bezpośrednio modyfikować DataTable.DefaultView.Sort. Nie ma potrzeby „wyłamywania” widoku i ponownego tworzenia tabeli.
Jonny

40

To ci pomoże ...

DataTable dt = new DataTable();         
dt.DefaultView.Sort = "Column_name desc";
dt = dt.DefaultView.ToTable();

Wielkie umysły myślą podobnie. Miałem właśnie zamieścić to samo rozwiązanie po przeczytaniu @ JayR's.
Drew Chapin

for Column_name, ponieważ byłem zdezorientowany, co było occr w rozwiązaniu Jaya Riggsa :)
Thameem

Cudowne i łatwe rozwiązanie :)
M. Fawad Surosh

25

Jego proste użycie. Wybierz funkcję.

DataRow[] foundRows=table.Select("Date = '1/31/1979' or OrderID = 2", "CompanyName ASC");
DataTable dt = foundRows.CopyToDataTable();

I gotowe ...... Miłego kodowania


Zauważ, że jeśli, tak jak PO, jesteś zainteresowany tylko w sortowaniu aspektem tego i nie chce, aby filtrować wyniki, można określić ją tak: Select("", "CompanyName ASC").
Tawab Wakil

20

Może poniższe wskazówki mogą pomóc:

DataRow[] dataRows = table.Select().OrderBy(u => u["EmailId"]).ToArray();

Tutaj możesz również użyć innych zapytań wyrażeń Lambda.


14

Czy próbowałeś użyć Select(filterExpression, sortOrder)metody w DataTable? Zobacz tutaj przykład. Zwróć uwagę, że ta metoda nie posortuje tabeli danych w miejscu, jeśli tego właśnie szukasz, ale zwróci posortowaną tablicę wierszy bez korzystania z widoku danych.


13

Lub, jeśli możesz użyć DataGridView, możesz po prostu zadzwonić Sort(column, direction):

namespace Sorter
{
    using System;
    using System.ComponentModel;
    using System.Windows.Forms;

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.dataGridView1.Rows.Add("Abc", 5);
            this.dataGridView1.Rows.Add("Def", 8);
            this.dataGridView1.Rows.Add("Ghi", 3);
            this.dataGridView1.Sort(this.dataGridView1.Columns[1], 
                                    ListSortDirection.Ascending);
        }
    }
}

Co dałoby pożądany rezultat:

Widok debugera


@vidyasagar Nie ma problemu. Ponadto, jeśli odpowiedź jest cenna, na przyszłość należy ją zagłosować (na przykład moja?). A jeśli odpowiedzią jest odpowiedź „THE”, należy ją oznaczyć jako odpowiedź (na przykład, Jay's).
Gustavo Mori

11
 table.DefaultView.Sort = "[occr] DESC";

Vidya chce posortować swój stół według occr w porządku malejącym. Co robi powyższy prosty kod. Robi dokładnie to, co pokazał Jay Riggs (zaakceptowana odpowiedź), z wyjątkiem tego, że jest to zrobione w jednej linii kodu.
ivg

2
Sugestia polegała na ulepszeniu postu; w przyszłości umieść te informacje o kodzie w odpowiedzi. Bo to zwiększa szansę, że ktoś zagłosuje za postem lub nawet wybierze go jako odpowiedź.
ΩmegaMan

5

Istnieją dwa sposoby sortowania danych

1) sortowanie samych danych i wypełnienie siatki:

DataGridView datagridview1 = new DataGridView(); // for show data
DataTable dt1 = new DataTable(); // have data
DataTable dt2 = new DataTable(); // temp data table
DataRow[] dra = dt1.Select("", "ID DESC");
if (dra.Length > 0)
    dt2 = dra.CopyToDataTable();
datagridview1.DataSource = dt2;

2) domyślny widok sortowania, podobny do sortowania z nagłówkiem kolumny siatki:

DataGridView datagridview1 = new DataGridView(); // for show data
DataTable dt1 = new DataTable(); // have data
dt1.DefaultView.Sort = "ID DESC";
datagridview1.DataSource = dt1;

1
Dziękuję za odpowiedź. Twój sposób # 1 pomógł w moim przypadku: zdefiniowałem bardzo specjalny IComparer, więc aby go użyć, zrobiłem coś takiego:DataRow[] rows = dt.Rows.Cast<DataRow>().OrderBy(row => row.Field<string>("FIELD_NAME"), MyCustomComparer.Instance).ToArray();
Aleksei

4

Okazuje się, że istnieje specjalny przypadek, w którym można to osiągnąć. Sztuczka polega na tym, że podczas budowania DataTable zebrać wszystkie wiersze na liście, posortować je, a następnie dodać. Ta sprawa właśnie się pojawiła.


3

// Mam nadzieję, że to ci pomoże ...

        DataTable table = new DataTable();
        //DataRow[] rowArray = dataTable.Select();
        table = dataTable.Clone();
        for (int i = dataTable.Rows.Count - 1; i >= 0; i--)
        {
            table.ImportRow(dataTable.Rows[i]);
        }
        return table;

1

TL; DR

posługiwać się tableObject.Select(queryExpression, sortOrderExpression) wybierz posortowane dane

Kompletny przykład

Kompletny przykład roboczy - można przetestować w aplikacji konsolowej :

    using System;
    using System.Data;

    namespace A
    {
        class Program
        {
            static void Main(string[] args)
            {
                DataTable table = new DataTable("Orders");
                table.Columns.Add("OrderID", typeof(Int32));
                table.Columns.Add("OrderQuantity", typeof(Int32));
                table.Columns.Add("CompanyName", typeof(string));
                table.Columns.Add("Date", typeof(DateTime));

                DataRow newRow = table.NewRow();
                newRow["OrderID"] = 1;
                newRow["OrderQuantity"] = 3;
                newRow["CompanyName"] = "NewCompanyName";
                newRow["Date"] = "1979, 1, 31";

                // Add the row to the rows collection.
                table.Rows.Add(newRow);

                DataRow newRow2 = table.NewRow();
                newRow2["OrderID"] = 2;
                newRow2["OrderQuantity"] = 2;
                newRow2["CompanyName"] = "NewCompanyName1";
                table.Rows.Add(newRow2);

                DataRow newRow3 = table.NewRow();
                newRow3["OrderID"] = 3;
                newRow3["OrderQuantity"] = 2;
                newRow3["CompanyName"] = "NewCompanyName2";
                table.Rows.Add(newRow3);

                DataRow[] foundRows;

                Console.WriteLine("Original table's CompanyNames");
                Console.WriteLine("************************************");
                foundRows = table.Select();

                // Print column 0 of each returned row.
                for (int i = 0; i < foundRows.Length; i++)
                    Console.WriteLine(foundRows[i][2]);

                // Presuming the DataTable has a column named Date.
                string expression = "Date = '1/31/1979' or OrderID = 2";
                // string expression = "OrderQuantity = 2 and OrderID = 2";

                // Sort descending by column named CompanyName.
                string sortOrder = "CompanyName ASC";

                Console.WriteLine("\nCompanyNames data for Date = '1/31/1979' or OrderID = 2, sorted CompanyName ASC");
                Console.WriteLine("************************************");
                // Use the Select method to find all rows matching the filter.
                foundRows = table.Select(expression, sortOrder);

                // Print column 0 of each returned row.
                for (int i = 0; i < foundRows.Length; i++)
                    Console.WriteLine(foundRows[i][2]);

                Console.ReadKey();
            }
        }
    }

Wynik

wynik


0

Spróbuj tego:

DataTable DT = new DataTable();
DataTable sortedDT = DT;
sortedDT.Clear();
foreach (DataRow row in DT.Select("", "DiffTotal desc"))
{
    sortedDT.NewRow();
    sortedDT.Rows.Add(row);
}
DT = sortedDT;

1) Musisz utworzyć nową tabelę DataTable sortedDT = new DataTable(). 2) Musisz użyć ImportRow(nie możesz dodać wiersza z innej tabeli)
marbel82
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.