使用DataView排序

问题描述 投票:0回答:3

大家好我从dataatabel获取数据的数据视图有问题(Col1:ID,Col2:时间),我在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"

提前致谢 ...

vb.net ado.net
3个回答
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

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




}

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

改为

    dt.Rows.Add(New Integer() {"1", "90.24"})
© www.soinside.com 2019 - 2024. All rights reserved.