C#DataFilter找不到列System.Data.Evaluate.Exception

C#DataFilter找不到列System.Data.Evaluate.Exception,c#,excel,datatable,dataview,C#,Excel,Datatable,Dataview,我正在将excel工作表导出到数据表dt 然后我有了设置日期格式的代码: CultureInfo culture = (CultureInfo)CultureInfo.CurrentCulture.Clone(); culture.DateTimeFormat.ShortDatePattern = "yyyy-MMM-dd"; culture.DateTimeFormat.LongTimePattern = ""; Thread.CurrentThread

我正在将excel工作表导出到数据表dt

然后我有了设置日期格式的代码:

CultureInfo culture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
culture.DateTimeFormat.ShortDatePattern = "yyyy-MMM-dd";
culture.DateTimeFormat.LongTimePattern = "";
Thread.CurrentThread.CurrentCulture = culture;
我的筛选器字符串如下所示:

string strFilter = "CONVERT([Creation date], 'System.DateTime') <= '2021-02-23' AND CONVERT([Creation date], 'System.DateTime') >= '2020-12-01'";
执行上述操作后,我得到一个System.Data.Evaluate.exception类型的异常,并显示消息:“找不到列[OK]”。Hresult:-2146232032

在源excel文件中,我要筛选的列名为“创建日期”,此列在excel中被识别为常规格式。列中的示例值:2020-12-29 14:05:332020-07-03 13:05:19

如何使用日期条件筛选此数据视图


编辑-解决方案

在筛选之前,我创建了一个DateTime类型的新列“Creation_date”,并从旧列中添加了解析值

public DataTable getDtWithDateType(DataTable dt) 
    {
        
        dt.Columns.Add("Creation_date", typeof(DateTime));
        
        foreach(DataRow row in dt.Rows)
            {
                row["Creation_date"] = DateTime.ParseExact(row["Creation date"].ToString(), "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);   
                            }

        return dt;
        }

一旦我有了扩展的数据表,我就能够实现Svetoslav Angelov提出的Linq解决方案。

这就是我使用Linq的方式,简单高效


public DataTable FilterDataTable(DataTable dt, DateTime minDate, DateTime maxDate, int columnIndex)
        {
            DataTable output = dt.Clone();
            var filterMenuRows = dt.AsEnumerable().Where(
                r => r.Field<DateTime>(columnIndex) >= minDate
                && r.Field<DateTime>(columnIndex) <= maxDate);
            if (filterMenuRows != null && filterMenuRows.Any())
            {
                output = filterMenuRows.CopyToDataTable();
            }

            return output;
        }

假设在填充数据表时使用迭代:

DataTable dt = new DataTable();
            dt.Columns.Add("NAME", typeof(string));
            dt.Columns.Add("ADDRESS", typeof(string));
            dt.Columns.Add("NOTE", typeof(string));
            dt.Columns.Add("BIRTH_DATE", typeof(DateTime));
            
            //excel is not zero based!!
            int maxExcelRows = 20001;
            int maxExcelColumns = 5;
            DataRow nextRow = dt.NewRow();
            for (int i = 1; i <= maxExcelRows; i++)
            {
                for (int j = 1; j <= maxExcelColumns; j++)
                {
                    //new line
                    if (j == 1)
                    {
                        nextRow = dt.NewRow();
                    }

                    //write the values
                    if (xlRange.Cells[i, j] != null && xlRange.Cells[i, j].Value != null)
                    {
                        if (j == 5) // your DateTime column here
                        {
                            // NOTE: use the exact format of the outer document
                            nextRow[j - 1] = DateTime.ParseExact(xlRange.Cells[i, j].Value.ToString(), "yy/MM/dd HH:mm:ss", CultureInfo.InvariantCulture); ;
                        }
                        else
                        {
                            nextRow[j - 1] = xlRange.Cells[i, j].Value.ToString();
                        }
                    } 
                }
                dt.Rows.Add(nextRow);
            }

DataTable dt=newdatatable();
添加(“名称”,类型(字符串));
添加(“地址”,类型(字符串));
添加(“注释”,类型(字符串));
添加(“出生日期”,类型(日期时间));
//excel不是基于零的!!
int maxExcelRows=20001;
int maxExcelColumns=5;
DataRow nextRow=dt.NewRow();

对于(int i=1;我正在处理由前一位员工创建的解决方案。此外,据我所知,CopyToDataTable()存在一些问题方法。不建议使用字符串作为DateTime…我强烈建议您在从excel导入时将数据解析为DateTime,这样您就不会有任何问题。工作表上的格式无关紧要…一旦您将其作为数据表导入C#内存,则无论格式如何(它是对象类型),要筛选的代码都应该工作。我猜您没有找到正确的列索引,或者数据表中的列不是DateTime类型。如果您可以指定一些数据,例如3-4行,请尝试使用断点进行调试。我可以尝试检查。使用System.Globalization;DateTime d=DateTime.ParseExact(“12/02/21 10:56:09”,“yy/MM/dd HH:MM:ss”,CultureInfo.InvariantCulture);当您使用you`r方法时,我将尝试在上面的答案中解释整个过程。只需在末尾添加另一个DateTime列,并迭代所有行,以使用正确的对象类型填充它。正如我的第一条评论所述..不建议使用字符串作为DateTime
public DataTable FilterDataTable(DataTable dt, string filter, string columnName)
        {
            DataTable output = dt.Select(columnName +"='" + filter + "'"); 
            
            return output;
        }
DataTable dt = new DataTable();
            dt.Columns.Add("NAME", typeof(string));
            dt.Columns.Add("ADDRESS", typeof(string));
            dt.Columns.Add("NOTE", typeof(string));
            dt.Columns.Add("BIRTH_DATE", typeof(DateTime));
            
            //excel is not zero based!!
            int maxExcelRows = 20001;
            int maxExcelColumns = 5;
            DataRow nextRow = dt.NewRow();
            for (int i = 1; i <= maxExcelRows; i++)
            {
                for (int j = 1; j <= maxExcelColumns; j++)
                {
                    //new line
                    if (j == 1)
                    {
                        nextRow = dt.NewRow();
                    }

                    //write the values
                    if (xlRange.Cells[i, j] != null && xlRange.Cells[i, j].Value != null)
                    {
                        if (j == 5) // your DateTime column here
                        {
                            // NOTE: use the exact format of the outer document
                            nextRow[j - 1] = DateTime.ParseExact(xlRange.Cells[i, j].Value.ToString(), "yy/MM/dd HH:mm:ss", CultureInfo.InvariantCulture); ;
                        }
                        else
                        {
                            nextRow[j - 1] = xlRange.Cells[i, j].Value.ToString();
                        }
                    } 
                }
                dt.Rows.Add(nextRow);
            }