Classificando linhas em uma tabela de dados

146

Temos duas colunas em a DataTable, assim:

COL1   COL2
Abc    5
Def    8
Ghi    3

Estamos tentando classificar isso com datatablebase COL2em ordem decrescente.

COL1            COL2
ghi             8
abc             4
def             3
jkl             1

Tentamos o seguinte:

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

mas, sem usar um DataView, queremos classificar o DataTablepróprio, não o DataView.

vidya sagar
fonte

Respostas:

355

Receio que você não possa criar facilmente uma DataTable no local, como parece que você deseja.

O que você pode fazer é criar um novo DataTable a partir de um DataView criado a partir do DataTable original. Aplique as classificações e / ou filtros desejados no DataView e crie um novo DataTable a partir do DataView usando o método DataView.ToTable :

   DataView dv = ft.DefaultView;
   dv.Sort = "occr desc";
   DataTable sortedDT = dv.ToTable();
Jay Riggs
fonte
Eu quero o valor crescente em termos de valor do preço que é decimal. como fazer isso?
Ranjith Kumar Nagiri
Essa abordagem parece bem. Mas não existe uma maneira direta de fazer isso? Por que eles não têm um DataTable.sort ("by")?
vapor
28
Obrigado. Vale a pena notar que "occr desc" aqui, "occr" é o nome da coluna, "desc" significa "descendente".
user1032613
22
Isso funcionou para mim dataTable.DefaultView.Sort = "Col1, Col2, Col3". Pouco código limpo.
Sai
7
Assim como o @Sai, você pode modificar o DataTable.DefaultView.Sort diretamente. Não há necessidade de "quebrar" a exibição e recriar uma tabela.
Jonny
40

Isso irá ajudá-lo ...

DataTable dt = new DataTable();         
dt.DefaultView.Sort = "Column_name desc";
dt = dt.DefaultView.ToTable();
Ankita_systematix
fonte
Mentes brilhantes pensam igual. Eu estava prestes a postar a mesma solução depois de ler @ JayR's.
Tirou Chapin
para Column_name porque eu estava confuso o que era OCCR em solução de Jay Riggs :)
Thameem
Solução maravilhosa e fácil :)
M. Fawad Surosh
25

Sua função de uso simples .Selecione.

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

E está feito ...... Happy Coding

Abdul
fonte
Note-se que se, como OP, você está interessado apenas no aspecto de classificação deste e não quer filtrar os resultados, você pode especificá-lo como este: Select("", "CompanyName ASC").
Tawab Wakil
20

Talvez o seguinte possa ajudar:

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

Aqui, você pode usar outras consultas de expressão Lambda também.

Vishnu
fonte
14

Você tentou usar o Select(filterExpression, sortOrder)método no DataTable? Veja aqui um exemplo. Observe que esse método não classificará a tabela de dados no local, se é isso que você está procurando, mas retornará uma matriz classificada de linhas sem usar uma visualização de dados.

Brian Rogers
fonte
13

Ou, se você pode usar um DataGridView, basta ligar para 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);
        }
    }
}

O que daria o resultado desejado:

Visualização do depurador

Gustavo Mori
fonte
@vidyasagar Sem problemas. Além disso, para referência futura, se uma resposta for valiosa, você deve votar (por exemplo, a minha?). E se uma resposta for "THE", marque-a como a resposta (por exemplo, Jay's).
Gustavo Mori
11
 table.DefaultView.Sort = "[occr] DESC";
ivg
fonte
Vidya quer classificar sua mesa por occr em ordem desc. Qual o código simples acima. Ele faz exatamente o que Jay Riggs (resposta aceita) mostrou, exceto que isso é feito em uma linha de código.
ivg 13/02/2015
2
A sugestão era melhorar o post; no futuro, coloque essas informações sobre o código na resposta. Pois isso melhora a chance de alguém votar de uma vez ou até mesmo selecioná-lo como resposta.
ManmegaMan
5

Há duas maneiras de classificar dados

1) classificando apenas os dados e preencha na grade:

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) classifique a visualização padrão semelhante à classificação com o cabeçalho da coluna da grade:

DataGridView datagridview1 = new DataGridView(); // for show data
DataTable dt1 = new DataTable(); // have data
dt1.DefaultView.Sort = "ID DESC";
datagridview1.DataSource = dt1;
Zolfaghari
fonte
1
Obrigado pela resposta. Sua maneira # 1 ajudou no meu caso: Eu tenho um IComparer muito especial definido, de modo a usá-lo eu fiz algo parecido com isto:DataRow[] rows = dt.Rows.Cast<DataRow>().OrderBy(row => row.Field<string>("FIELD_NAME"), MyCustomComparer.Instance).ToArray();
Aleksei
4

Acontece que há um caso especial em que isso pode ser alcançado. O truque é criar a DataTable, coletar todas as linhas de uma lista, classificá-las e adicioná-las. Este caso acabou de aparecer aqui.

Joshua
fonte
3

// Espero que isso ajude você ..

        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;
Kumod Singh
fonte
1

TL; DR

use tableObject.Select(queryExpression, sortOrderExpression)para selecionar dados de maneira ordenada

Exemplo completo

Exemplo de trabalho completo - pode ser testado em um aplicativo de console :

    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();
            }
        }
    }

Resultado

resultado

Zameer
fonte
0

tente isto:

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;
Rand Shaban
fonte
1) Você deve criar uma nova tabela DataTable sortedDT = new DataTable(). 2) Você precisa usar ImportRow(você não pode adicionar linha de diferentes tabela)
marbel82