[英]Use of C# Oledb to filter through an excel spreadsheet and return a specific value
I have a WPF app of which I would like to pull specific data from based on two variables.我有一个 WPF 应用程序,我想根据两个变量从中提取特定数据。 The data source is the below spreadsheet, there are no specific settings applied it is simply raw data.数据源是下面的电子表格,没有应用特定的设置,它只是原始数据。
I would like a method of which I could call ie;我想要一种我可以调用的方法,即;
GetValue("A", "Dec-19")
With:和:
GetValue(string Product, DateTime Date)
This would return the value 0. I have tried numerous approaches however am unable to produce anything that functions.这将返回值 0。我尝试了多种方法,但无法产生任何功能。 Here is a variation of an attempt of mine I was working on;这是我正在进行的尝试的一种变体;
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;
}
}
}
This is a modified version of your original code that will hopefully accomplish what you were looking for:这是原始代码的修改版本,有望实现您的需求:
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;
}
}
Please note the following:请注意以下事项:
ci
CultureInfo variable you used in the ToString
call because I did not know where that variable came from该代码不使用您在ToString
调用中使用的ci
CultureInfo 变量,因为我不知道该变量来自哪里double
, it returns 0, instead of null, if no matching value is found;由于函数是double
类型,如果没有找到匹配的值,它返回 0,而不是 null; if you prefer null in these cases, the function can be changed to type double?
如果在这些情况下您更喜欢 null,则可以将该函数更改为double?
, but the code that calls this function must be aware that a null can be returned ,但是调用这个函数的代码一定要知道可以返回nullif
or the else
block inside the for
loop if you only want to handle one case如果您只想处理一种情况,您可能希望消除for
循环中的if
或else
块I tested this code, and it seemed to return the right value every time.我测试了这段代码,它似乎每次都返回正确的值。 I hope it works for you.我希望这个对你有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.