使用DataView排序

时间:2012-01-05 09:36:03

标签: vb.net ado.net

大家好我从dataatabel获取数据的数据视图出了问题(Col1:ID,Col2:Time) 我在desc中按时间排序...当例如{40.21,80.21,70.25,25.2}的值时,数据视图将它们排序为我需要但当其中一个值超过100时,例如{40.21,80.21, 100.25 ,25.2}数据视图总是排序最高的数字是buttom,我不知道为什么..这是一个示例代码

 Dim dt As New DataTable
        dt.Columns.Add("ID")
        dt.Columns.Add("Time")

        dt.Rows.Add(New String() {"1", "90.24"})
        dt.Rows.Add(New String() {"2", "80.25"})
        dt.Rows.Add(New String() {"3", "70.22"})
        dt.Rows.Add(New String() {"4", "102.12"})

        Dim dv As New DataView(dt)
        dv.Sort = "Time Desc"

提前致谢...

3 个答案:

答案 0 :(得分:4)

你正在排序一个字符串,那么你有什么期望? “10000”低于“2”,因为“1”按字母顺序低于“2”,正如“abbbb”低于“b”。

您需要使用正确的数据类型(在本例中我假设为Double)才能获得正确的(数字)排序:

Dim dt As New DataTable
dt.Columns.Add("ID", GetType(Int32))
dt.Columns.Add("Time", GetType(Double))

dt.Rows.Add(1, 90.24)
dt.Rows.Add(2, 80.25)
dt.Rows.Add(3, 70.22)
dt.Rows.Add(4, 102.12)

Dim dv As New DataView(dt)
dv.Sort = "Time Desc"

结果:

    4  102,12
    1   90,24
    2   80,25
    3   70,22

答案 1 :(得分:0)

就像蒂姆所说,你是按字符串排序的。我不得不在多列中处理大量混合数字和字符串,所以我写了一个类来进行排序(下面)。它正确地将数字排序为数字,日期作为日期和混合数字/字符串字段按用户的预期排序。

我有数据列的列 “第1天时间点1” “第14天时间点3” “第15天时间点10” ......和混合的数字和日期。

该类采用数据表和要包含在排序中的列列表。列表中最重要的列,首先添加任意数量的列。

using System;
using System.Data;
using System.Linq;

public class DataTableSorter
{
    public enum SortDirection
    {
        Ascending,
        Descending
    }

    private const string MC_TEMP_COL_NAME = "SorterXXXColumn";
    private const int MC_NUM_PAD_COLS = 12;
    private static string msPAD = new string('0', MC_NUM_PAD_COLS);

    public static DataTable SortTable(DataTable oDT, SortDirection eSortDir, params string[] asColumns)
    {

        //so DataView has limited sorting capability, this builds it out so numbers and strings work out well.
        oDT.Columns.Add(new DataColumn(MC_TEMP_COL_NAME, typeof(string)));

        foreach (DataRow oDR in oDT.Rows)
        {
            string sSortable = string.Empty;

            foreach(string sCol in asColumns)
                sSortable += Sortable(oDR[sCol]);

            oDR[MC_TEMP_COL_NAME] = sSortable;
        }

        //Using DataView for sorting DataTable's data
        using (DataView oSortedView = oDT.DefaultView)
        {
            oSortedView.Sort = string.Format("[{0}] {1}", MC_TEMP_COL_NAME, eSortDir == SortDirection.Ascending ? "ASC" : "DESC");

            using (DataTable oDTreturn = oSortedView.ToTable())
            {

                //remove special sort column
                oDTreturn.Columns.RemoveAt(oDTreturn.Columns.Count - 1);

                return oDTreturn;
            }
        }
    }

    private static string Sortable(object oValue)
    {
        DateTime oDtT;
        if (string.IsNullOrWhiteSpace(oValue.ToString()))
        {
            return string.Empty;
        }
        else if (DateTime.TryParse(oValue.ToString(), out oDtT))
        {
            System.Diagnostics.Debug.Print(oValue.ToString() + "\t" + String.Format("{0:yyyyMMddHHmmss.FFFF}", oDtT));
            return string.Format("{0:yyyyMMddHHmmss.FFFF}", oDtT);
        }
        else
        {
            //pad out all numbers with lots of zeros, so that numbers sort as numbers.
            char[] acVal = oValue.ToString().ToCharArray();
            string sBuff = string.Empty;
            string sRC = string.Empty;

            bool bAfterDecmal = false;

            int iCharCount = acVal.Length;
            for (int i = 0; i < iCharCount; i++)
            {
                char c = acVal[i];

                bool bIsNumeric = "0123456789".Contains(c);

                bool bEndSection = false;
                if (i == (iCharCount - 1))
                {
                    bEndSection = true;
                }
                else
                {
                    char cNext = acVal[i + 1];

                    if (bIsNumeric != "0123456789".Contains(cNext))
                    {
                        bEndSection = true;
                    }
                    else if (c == '.')
                    {
                        bEndSection = true;
                        bIsNumeric = false;
                    }
                    else if (cNext == '.')
                    {
                        bEndSection = true;
                    }
                }

                sBuff += c;

                if (bEndSection)
                {
                    if (bIsNumeric)
                    {
                        if (bAfterDecmal)
                        {
                            // FOR DECMALS, JUST RIGHT-PAD TO MC_NUM_PAD_COLS ZEROS:
                            sRC += (sBuff + msPAD).Substring(0, MC_NUM_PAD_COLS);
                            bAfterDecmal = true;
                        }
                        else
                        {
                            // for integers, left pad to MC_NUM_PAD_COLS zeros.
                            sRC += (msPAD + sBuff).Substring(sBuff.Length);
                        }
                    }
                    else
                    {
                        // upper case all strings, for better ordering.
                        sRC += sBuff.ToUpper();
                    }

                    sBuff = string.Empty;

                } // CHANGE IN NUMERIC STATUS

                if (c == '.')
                    bAfterDecmal = true;
            }

            System.Diagnostics.Debug.Print(oValue.ToString() + "\t" + sRC);
            return sRC;
        }
    }




}

答案 2 :(得分:-1)

  dt.Rows.Add(New String() {"1", "90.24"})

将其更改为

    dt.Rows.Add(New Integer() {"1", "90.24"})