我甚至不确定我是否使用了正确的术语;我会根据需要更新问题和标题。
我正在使用OpenXmlSDK填充预先存在的Excel 2010 .xlsm
文件 - 一个启用宏的工作表。
我可以很好地访问工作表和单元格。
但是,我无法弄清楚如何访问或更新单元格中的数据,该单元格是从另一个工作表中的某个范围获取其值的下拉控件。
它在工作表上标记为“H13”,然后右键单击>>格式控制显示
Input range: 'anotherWorksheet'!$N$3:$N$54
Cell link: 'anotherWorksheet'!$M$3
每当我尝试获取对此单元格的引用时,我找不到它 - 我得到null
值
我尝试了两种访问方法:
我甚至不确定我是否使用了正确的术语;我会根据需要更新问题和标题。
我正在使用OpenXmlSDK填充预先存在的Excel 2010 .xlsm
文件 - 一个启用宏的工作表。
我可以很好地访问工作表和单元格。
但是,我无法弄清楚如何访问或更新单元格中的数据,该单元格是从另一个工作表中的某个范围获取其值的下拉控件。
它在工作表上标记为“H13”,然后右键单击>>格式控制显示
Input range: 'anotherWorksheet'!$N$3:$N$54
Cell link: 'anotherWorksheet'!$M$3
每当我尝试获取对此单元格的引用时,我找不到它 - 我得到null
值
我尝试了两种访问方法:
// http://msdn.microsoft.com/en-us/library/ff921204.aspx
private static Cell GetCell(Worksheet worksheet, string addressName)
{
return worksheet.Descendants<Cell>().Where(
c => c.CellReference == addressName).FirstOrDefault();
}
和
// Given a worksheet, a column name, and a row index,
// gets the cell at the specified column and
// http://stackoverflow.com/questions/527028/open-xml-sdk-2-0-how-to-update-a-cell-in-a-spreadsheet
private static Cell GetCell(Worksheet worksheet, string columnName, uint rowIndex)
{
Row row = GetRow(worksheet, rowIndex);
if (row == null)
return null;
return row.Elements<Cell>().Where(c => string.Compare
(c.CellReference.Value, columnName +
rowIndex, true) == 0).FirstOrDefault();
}
// Given a worksheet and a row index, return the row.
private static Row GetRow(Worksheet worksheet, uint rowIndex)
{
return worksheet.GetFirstChild<SheetData>().
Elements<Row>().Where(r => r.RowIndex == rowIndex).First();
}
两者都为目标单元格null
生成H13
,但提供对周围单元格的引用(即“H12,H14,G13”
实际上,I13
也会产生null
,但该单元格中没有任何内容。但是,如果我无法获得参考,我怎么能用SDK填充它?这不是我的主要观点。
我将接收与下拉列表中的一个条目匹配的数据;我只需要实际填充/选择目标电子表格中的特定条目。
如何使用OpenXmlSDK执行此操作?我尝试过使用各种开源库,但似乎都没有支持.xslm
文件(客户端提供的文件,不能以其他格式使用;宏必须在启动时执行等)。
虽然我正在使用C#,但由于我的问题是关于OpenXmlSDK,我会接受使用该框架的其他语言的答案。
答案 0 :(得分:1)
简答:单元格不存在,因此null
引用。
我创建了一个带有列表(下拉列表)的小工作表,DataValidation指向另一个工作表中的一系列单元格。
使用Open XML SDK 2.0 Productivity Tool反映文件我看到,而不是创建单元格并将其附加到工作表,而是创建了一个DataValidation(CellReference等于目标)。
using X14 = DocumentFormat.OpenXml.Office2010.Excel; [....] X14.DataValidations dataValidations1 = new X14.DataValidations() { Count = (UInt32Value)1U }; dataValidations1.AddNamespaceDeclaration("xm", "http://schemas.microsoft.com/office/excel/2006/main"); X14.DataValidation dataValidation1 = new X14.DataValidation() { Type = DataValidationValues.List, AllowBlank = true, ShowInputMessage = true, ShowErrorMessage = true }; X14.DataValidationForumla1 dataValidationForumla11 = new X14.DataValidationForumla1(); Excel.Formula formula1 = new Excel.Formula(); formula1.Text = "Lists!$A$1:$A$51"; dataValidationForumla11.Append(formula1); Excel.ReferenceSequence referenceSequence1 = new Excel.ReferenceSequence(); referenceSequence1.Text = "A1"; dataValidation1.Append(dataValidationForumla11); dataValidation1.Append(referenceSequence1); dataValidations1.Append(dataValidation1);
除非工作表位置具有预设值,否则在运行时访问它时实际上不会是“单元格”。
回想起来,这是有道理的。但在视觉上,它看起来像一个细胞,所以它并不明显......
不是一个细胞:
注意:如果从DataValidation中进行选择并保存,则单元格现在具有值,因此它存在:
是一个细胞:
当返回空引用时,可以通过创建新单元格并将其附加到目标行来解决此问题。
现在的困难在于需要引用共享字符串表的验证,并且不接受原始文本作为单元格值....
更新:我能够找到与单元格关联的DataValidation,找到目标工作表和范围,找到该范围内的目标值,并获取与该值关联的SharedStringsTable引用。但无论我插入目标单元格的价值如何,Excel打开时都被认为是坏数据。
最后,我放弃了,回到Excel Interop,然后找到a method to select a dropdown field from within (ugh) Interop.