C# 使用Oledb筛选excel电子表格并返回特定值
我有一个WPF应用程序,我想根据两个变量从中提取特定数据。 数据源是下面的电子表格,没有应用任何特定设置,它只是原始数据 我想要一种我可以称之为的方法,即:C# 使用Oledb筛选excel电子表格并返回特定值,c#,excel,oledb,oledbconnection,C#,Excel,Oledb,Oledbconnection,我有一个WPF应用程序,我想根据两个变量从中提取特定数据。 数据源是下面的电子表格,没有应用任何特定设置,它只是原始数据 我想要一种我可以称之为的方法,即: GetValue("A", "Dec-19") 与: 这将返回值0。 我尝试了许多方法,但无法产生任何功能。 这是我的一个尝试的一个变体,我正在工作 public double GetValue(string type, OleDbConnection TargetBuildOleDbConnection, DateTime Selec
GetValue("A", "Dec-19")
与:
这将返回值0。
我尝试了许多方法,但无法产生任何功能。
这是我的一个尝试的一个变体,我正在工作
public double GetValue(string type, OleDbConnection TargetBuildOleDbConnection, DateTime Selection)
{
string date = Selection.ToString("MMM-yy", ci);
string CustomQuery = "SELECT ['" + date + "'] FROM [SHEET1$A1:Z1] WHERE [Product] = '" + type + "'";
using (DataTable dt = new DataTable())
{
using (DataView dv = new DataView(dt))
{
using (OleDbCommand comm = new OleDbCommand())
{
comm.CommandText = "Select * from [Build Schedule$]";
comm.Connection = TargetBuildOleDbConnection;
using (OleDbDataAdapter da = new OleDbDataAdapter())
{
da.SelectCommand = comm;
da.Fill(dt);
}
}
dv.RowFilter = "SELECT ['" + date + "'] FROM [SHEET1$A1:Z1]"; //throwing exception
double target = dt.Rows[0].Field<int>(0);
return target;
}
}
}
这是您的原始代码的修改版本,有望实现您所期望的:
public double GetValue(string product, OleDbConnection targetBuildOleDbConnection, DateTime dte)
{
const double defaultValue = 0; // Value to return if no match is found
const string prodParamName = "@prod";
using (OleDbCommand comm = new OleDbCommand())
{
comm.Connection = targetBuildOleDbConnection;
comm.CommandText = string.Format("SELECT * FROM [Build Schedule$] WHERE Product={0}", prodParamName);
comm.Parameters.Add(prodParamName, OleDbType.VarWChar); // Maybe VarChar is good enough (?)
comm.Parameters[prodParamName].Value = product;
using (OleDbDataReader rdr = comm.ExecuteReader())
{
if (!rdr.Read()) return defaultValue;
for (var i = 1; i < rdr.FieldCount; i++)
{
var colName = rdr.GetName(i);
double colNumber;
if (double.TryParse(colName, out colNumber)) // If the date headers have actual Excel dates
{
DateTime colDate = DateTime.FromOADate(colNumber); // Convert Excel's date number to a C# date
if (colDate.Month != dte.Month || colDate.Year != dte.Year) continue;
}
else if (colName != dte.ToString("MMM-yy")) // If the date headers are actual Excel strings
continue;
double colValue;
if (double.TryParse(rdr.GetValue(i).ToString(), out colValue)) return colValue;
break; // No point in continuing, since we found the right column, but it did not have a valid double
}
}
return defaultValue;
}
}
请注意以下事项:
代码假定数据位于名为Build Schedule的工作表上
代码没有使用您在ToString调用中使用的ci CultureInfo变量,因为我不知道该变量来自何处
由于函数是double类型,如果没有找到匹配值,则返回0而不是null;如果您在这些情况下更喜欢null,则可以将函数更改为double?类型,但调用此函数的代码必须知道可以返回null
无论日期标题单元格(如11月19日和12月19日单元格)是否包含仅在Excel中格式化为MMM yy的日期值,或者是否包含实际字符串,代码理论上都应有效;如果只想处理一种情况,则可能需要消除for循环中的if或else块
如果您使用的是旧版本的C,那么代码不会利用最新版本C中的某些语法改进
可以优化对右列的搜索,尤其是在连续多次调用此函数的情况下
我测试了这段代码,它似乎每次都返回正确的值。我希望它对您有用。好吧,至少提供您检索数据失败的代码。否则,我们需要为您编写所有来自Scratch抱歉的代码!现在添加了一些东西为什么不直接使用CustomQuery,而不是检索整个表,然后尝试对其进行筛选?无论如何,RowFilter的语法不正确。它应该是一个WHERE表达式,没有单词wherend,使用的连接字符串是什么?什么是正确的图纸名称Build Schedule$或Sheet1$?看起来应该可以-我将在接下来的几天内进行测试,谢谢!非常感谢-经过一些调整后,它工作得非常好,可以与我的代码一起使用。太棒了!很高兴知道!:
public double GetValue(string product, OleDbConnection targetBuildOleDbConnection, DateTime dte)
{
const double defaultValue = 0; // Value to return if no match is found
const string prodParamName = "@prod";
using (OleDbCommand comm = new OleDbCommand())
{
comm.Connection = targetBuildOleDbConnection;
comm.CommandText = string.Format("SELECT * FROM [Build Schedule$] WHERE Product={0}", prodParamName);
comm.Parameters.Add(prodParamName, OleDbType.VarWChar); // Maybe VarChar is good enough (?)
comm.Parameters[prodParamName].Value = product;
using (OleDbDataReader rdr = comm.ExecuteReader())
{
if (!rdr.Read()) return defaultValue;
for (var i = 1; i < rdr.FieldCount; i++)
{
var colName = rdr.GetName(i);
double colNumber;
if (double.TryParse(colName, out colNumber)) // If the date headers have actual Excel dates
{
DateTime colDate = DateTime.FromOADate(colNumber); // Convert Excel's date number to a C# date
if (colDate.Month != dte.Month || colDate.Year != dte.Year) continue;
}
else if (colName != dte.ToString("MMM-yy")) // If the date headers are actual Excel strings
continue;
double colValue;
if (double.TryParse(rdr.GetValue(i).ToString(), out colValue)) return colValue;
break; // No point in continuing, since we found the right column, but it did not have a valid double
}
}
return defaultValue;
}
}