(C# - Excel) 如何将公式写入每个现有行的新创建列?
(C# - Excel) How do I write a formula to a newly created column for each existing row?
假设您有一个 excel 文件,其中包含一堆数字和行,大约 100 行。
我想以编程方式编写一个包含公式的列,该公式将每个现有行的一堆字段的值加在一起。
所以首先,当然,我会为 Excel 文件创建 Openfiledialog,找到路径,通过 OleDb 打开它。记下来了现在说我有以下 table:
[好友 |金钱 |钱丢了 |日子过去了 |解决方案]
Bilbo , 50 , 50 , 7 , *公式在这里
Bilso , 80 , 50 , 7 , *公式在这里
等...
问题是,我没有确切的行数,所以我必须枚举 OleDb 连接找到的任何内容。
该公式类似于 =(B2-C2)*D2,但 2 也是错误的,它必须相对于它所在的任何行,即:第 3 行将为 =(B3-C3)*D3。我不知道该怎么做。
我发现直接写入单元格也不会使公式直接处理数字。
=====
编辑:
private Excel.Application Xls;
private Excel.Workbooks WBs;
private Excel.Workbook WB;
private Excel.Worksheet WS;
private Excel.Sheets SS;
Excel.Range cellsRange = null;
Excel.Range columnRange = null;
Excel.Range rowRange = null;
int numberOfColumns = 0;
int numberOfRows = 0;
private void btnColumn_Click(object sender, EventArgs e)
{
if (btnColumn.FlatStyle == FlatStyle.Flat)
btnColumn.FlatStyle = FlatStyle.Standard;
else
{
btnColumn.FlatStyle = FlatStyle.Flat;
}
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Excel Files|*.xls;*.xlsx";
openFileDialog.ShowDialog();
string pather = openFileDialog.FileName;
if (pather == "" || pather == " " || pather == null)
{
return;
}
if (!string.IsNullOrEmpty(openFileDialog.FileName))
{
try
{
Xls = new Excel.Application();
WBs = Xls.Workbooks;
WB = WBs.Open(pather, 0, false, 5, "", "", true,
XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
SS = WB.Worksheets;
WS = SS.get_Item(1);
cellsRange = WS.Cells;
columnRange = cellsRange.Columns;
rowRange = cellsRange.Rows;
numberOfColumns = columnRange.Count;
numberOfRows = rowRange.Count;
int LastCell = numberOfColumns+1;
WS.Cells[1, LastCell] = "Tax Formula";
for (int i = 2; i < numberOfRows; i++)
{
//string niceFormula = "=SUM(L" + i + ",M" + i + ")*N"+ i ;
//WS.Cells[i, LastCell].Formula = niceFormula;
WS.Cells[i, LastCell].Value = (WS.Cells[i, 12] + WS.Cells[i, 13]) * WS.Cells[i, 14];
}
//==========================
WB.Save();
}
catch (Exception ex)
{
MessageBox.Show("Write Excel: " + ex.Message);
}
finally
{
GC.Collect();
GC.WaitForPendingFinalizers();
WB.Close();
Xls.Quit();
releaseObject(cellsRange);
releaseObject(columnRange);
releaseObject(rowRange);
releaseObject(SS);
releaseObject(WS);
releaseObject(WBs);
releaseObject(WB);
releaseObject(Xls);
}
MessageBox.Show("Finished Updating File", "Task complete");
}
}
有人知道为什么这段代码在写入尝试时抛出以下错误吗?
HRESULT: 0x800A03EC
为方便起见,重新粘贴了整个代码。它仍然吐出 HRESULT 错误。
目标项目是 4 行深,1 行 headers,大约 16 列宽。
编辑:
您可能想试试这个:
numberOfColumns = WS.UsedRange.Columns.CountLarge;
numberOfRows = WS.UsedRange.Rows.CountLarge;
呃,如果你使用 CountLarge
而不是 Count
,也将它们更改为 long
而不是 int
好的 - 我终于开始工作了 - 不知道为什么我有这么多问题。
对我来说,我显然必须让应用程序可见,否则它就不起作用。
可能还有另一种解决方法 - 我从这里提取它:
这段代码终于对我有用了:
请注意,这是一个控制台应用程序(我想我会排除这种可能性),但您应该能够添加魔法线。
Application excelApp = new Application();
excelApp.SheetsInNewWorkbook = 1;
////////////////////////////////////////////
//Add these lines to make it work???
////////////////////////////////////////////
try {
excelApp.Visible = true;
}
catch {}
////////////////////////////////////////////
Workbook excelWB = excelApp.Workbooks.Open(@"C:\test.xls", Type.Missing, false);
_Worksheet excelWS = excelWB.Sheets[1];
Range cellsRange = excelWS.UsedRange;
long LastCell = cellsRange.Columns.CountLarge + 1;
long numberOfRows = cellsRange.Rows.CountLarge;
excelWS.Cells[1, LastCell] = "Tax Formula";
for (int i = 2; i <= numberOfRows; i++)
{
string niceFormula = "=SUM(L" + i + ",M" + i + ")*N" + i;
excelWS.Cells[i, LastCell].Formula = niceFormula;
}
excelWB.Close(true);
excelApp.Quit();
之前:
之后:
如何使用 excel 电子表格填充 DataTable:
//////////////////////////////////////////////////////////////////////////////////
//This function is absolute magic >.> - Fill DataTable with excel spreadsheet
//HDR=YES means "Spreadsheet has headers" Change to NO if not.
//name = "Log"; - This is the Sheet name to pull the data from
//////////////////////////////////////////////////////////////////////////////////
//oconn takes an SQL like command (Select Everything from name sheet) using con
//HDR=YES means that our data has headers :)
//////////////////////////////////////////////////////////////////////////////////
String constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + copyToPath + ";Extended Properties='Excel 12.0 XML;HDR=YES;';";
OleDbConnection con = new OleDbConnection(constr);
OleDbCommand oconn = new OleDbCommand("Select * From [Log$]", con);
con.Open();
OleDbDataAdapter sda = new OleDbDataAdapter(oconn);
DataTable data = new DataTable();
sda.Fill(data);
con.Close();
//////////////////////////////////////////////////////////////////////////////////
为什么不用R1C1参考样式?这样你的公式就不需要相对于列。
供参考:
https://excelmate.wordpress.com/2013/04/22/excel-r1c1-reference-style-vs-a1/
假设您有一个 excel 文件,其中包含一堆数字和行,大约 100 行。
我想以编程方式编写一个包含公式的列,该公式将每个现有行的一堆字段的值加在一起。
所以首先,当然,我会为 Excel 文件创建 Openfiledialog,找到路径,通过 OleDb 打开它。记下来了现在说我有以下 table:
[好友 |金钱 |钱丢了 |日子过去了 |解决方案]
Bilbo , 50 , 50 , 7 , *公式在这里
Bilso , 80 , 50 , 7 , *公式在这里
等...
问题是,我没有确切的行数,所以我必须枚举 OleDb 连接找到的任何内容。 该公式类似于 =(B2-C2)*D2,但 2 也是错误的,它必须相对于它所在的任何行,即:第 3 行将为 =(B3-C3)*D3。我不知道该怎么做。
我发现直接写入单元格也不会使公式直接处理数字。
=====
编辑:
private Excel.Application Xls;
private Excel.Workbooks WBs;
private Excel.Workbook WB;
private Excel.Worksheet WS;
private Excel.Sheets SS;
Excel.Range cellsRange = null;
Excel.Range columnRange = null;
Excel.Range rowRange = null;
int numberOfColumns = 0;
int numberOfRows = 0;
private void btnColumn_Click(object sender, EventArgs e)
{
if (btnColumn.FlatStyle == FlatStyle.Flat)
btnColumn.FlatStyle = FlatStyle.Standard;
else
{
btnColumn.FlatStyle = FlatStyle.Flat;
}
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Excel Files|*.xls;*.xlsx";
openFileDialog.ShowDialog();
string pather = openFileDialog.FileName;
if (pather == "" || pather == " " || pather == null)
{
return;
}
if (!string.IsNullOrEmpty(openFileDialog.FileName))
{
try
{
Xls = new Excel.Application();
WBs = Xls.Workbooks;
WB = WBs.Open(pather, 0, false, 5, "", "", true,
XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
SS = WB.Worksheets;
WS = SS.get_Item(1);
cellsRange = WS.Cells;
columnRange = cellsRange.Columns;
rowRange = cellsRange.Rows;
numberOfColumns = columnRange.Count;
numberOfRows = rowRange.Count;
int LastCell = numberOfColumns+1;
WS.Cells[1, LastCell] = "Tax Formula";
for (int i = 2; i < numberOfRows; i++)
{
//string niceFormula = "=SUM(L" + i + ",M" + i + ")*N"+ i ;
//WS.Cells[i, LastCell].Formula = niceFormula;
WS.Cells[i, LastCell].Value = (WS.Cells[i, 12] + WS.Cells[i, 13]) * WS.Cells[i, 14];
}
//==========================
WB.Save();
}
catch (Exception ex)
{
MessageBox.Show("Write Excel: " + ex.Message);
}
finally
{
GC.Collect();
GC.WaitForPendingFinalizers();
WB.Close();
Xls.Quit();
releaseObject(cellsRange);
releaseObject(columnRange);
releaseObject(rowRange);
releaseObject(SS);
releaseObject(WS);
releaseObject(WBs);
releaseObject(WB);
releaseObject(Xls);
}
MessageBox.Show("Finished Updating File", "Task complete");
}
}
有人知道为什么这段代码在写入尝试时抛出以下错误吗?
HRESULT: 0x800A03EC
为方便起见,重新粘贴了整个代码。它仍然吐出 HRESULT 错误。
目标项目是 4 行深,1 行 headers,大约 16 列宽。
编辑:
您可能想试试这个:
numberOfColumns = WS.UsedRange.Columns.CountLarge;
numberOfRows = WS.UsedRange.Rows.CountLarge;
呃,如果你使用 CountLarge
而不是 Count
long
而不是 int
好的 - 我终于开始工作了 - 不知道为什么我有这么多问题。
对我来说,我显然必须让应用程序可见,否则它就不起作用。
可能还有另一种解决方法 - 我从这里提取它:
这段代码终于对我有用了:
请注意,这是一个控制台应用程序(我想我会排除这种可能性),但您应该能够添加魔法线。
Application excelApp = new Application();
excelApp.SheetsInNewWorkbook = 1;
////////////////////////////////////////////
//Add these lines to make it work???
////////////////////////////////////////////
try {
excelApp.Visible = true;
}
catch {}
////////////////////////////////////////////
Workbook excelWB = excelApp.Workbooks.Open(@"C:\test.xls", Type.Missing, false);
_Worksheet excelWS = excelWB.Sheets[1];
Range cellsRange = excelWS.UsedRange;
long LastCell = cellsRange.Columns.CountLarge + 1;
long numberOfRows = cellsRange.Rows.CountLarge;
excelWS.Cells[1, LastCell] = "Tax Formula";
for (int i = 2; i <= numberOfRows; i++)
{
string niceFormula = "=SUM(L" + i + ",M" + i + ")*N" + i;
excelWS.Cells[i, LastCell].Formula = niceFormula;
}
excelWB.Close(true);
excelApp.Quit();
之前:
之后:
如何使用 excel 电子表格填充 DataTable:
//////////////////////////////////////////////////////////////////////////////////
//This function is absolute magic >.> - Fill DataTable with excel spreadsheet
//HDR=YES means "Spreadsheet has headers" Change to NO if not.
//name = "Log"; - This is the Sheet name to pull the data from
//////////////////////////////////////////////////////////////////////////////////
//oconn takes an SQL like command (Select Everything from name sheet) using con
//HDR=YES means that our data has headers :)
//////////////////////////////////////////////////////////////////////////////////
String constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + copyToPath + ";Extended Properties='Excel 12.0 XML;HDR=YES;';";
OleDbConnection con = new OleDbConnection(constr);
OleDbCommand oconn = new OleDbCommand("Select * From [Log$]", con);
con.Open();
OleDbDataAdapter sda = new OleDbDataAdapter(oconn);
DataTable data = new DataTable();
sda.Fill(data);
con.Close();
//////////////////////////////////////////////////////////////////////////////////
为什么不用R1C1参考样式?这样你的公式就不需要相对于列。
供参考: https://excelmate.wordpress.com/2013/04/22/excel-r1c1-reference-style-vs-a1/