如何将值设置为二维 Excel 范围?
Posted
技术标签:
【中文标题】如何将值设置为二维 Excel 范围?【英文标题】:how to set values to a two-dimensional Excel range? 【发布时间】:2013-06-12 09:56:53 【问题描述】:我需要从一个特定格式的测试用例列表中构建一个 Excel 表,以便将其上传到服务器。 我很难在文件中填充“预期”和“实际”的二维范围。 我使用相同的方法来填充标题(一维数组)和步骤(二维数组)。
流程是:
-
取消对 TestCase 范围的资助(一些标题 + 步骤)。假设:第一次迭代的 A1 到 E14。
在标题的 testCase 范围内取消子(本地)范围(例如:A1 到 C1)。
在标题的 testCase 范围内删除另一个子(本地)范围(在我的例子中:D1 到 E14)。
使用测试用例值(标题和步骤)填充两个子范围。
重复使用相同的本地范围(步骤 2-3)取消下一个电子表格范围(在我的情况下为 A14 到 E28),然后填充它们,依此类推...
源值是一个字典,表示测试用例的步骤(键 = 预期和值 = 实际)。
这是我使用的代码:
public class TestCase
public Dictionary<string, string> steps;
Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
Workbooks workBooks = excelApp.Workbooks;
Workbook workbook = workBooks.Add(XlWBATemplate.xlWBATWorksheet);
Worksheet worksheet = (Worksheet)workbook.Worksheets[1];
excelApp.Visible = true;
foreach (TestCase testCase in TestCaseList.Items.GetList())
Range worksheetRange = GetRangeForTestCase(worksheet);
//The step above is equivalent to:
// Range worksheetRange = worksheet.get_Range("A1", "E14");
//for the first foreach iteration.
Range stepsRange = worksheetRange.get_Range("D1", "E14");
//This is a local range within the worksheetRange, not the worksheet,
//so it is always have to be between D1 to E14 for a 14th steps test case.
//Anyway, it should work at least for the 1st iteration.
//for test evaluation only. All cells between D1 to E14 are filled with "ccc"
test.Value = "ccc";
//This list of pairs which are converted to Array[,] is about to be converted to a two dimensional array
list = new List<object>();
foreach (KeyValuePair<string, string> item in testCase.Steps)
//Here I build the inside Array[,]
object[] tempArgs = item.Key, item.Value;
list.Add(tempArgs);
object[] args = Type.Missing, list.ToArray() ;
test.GetType().InvokeMember("Value", System.Reflection.BindingFlags.SetProperty, null, test, args);
//Now, all the "ccc" within the Excel worksheet are disapeared, so the Range is correct, but the value of args[] are not set!!
运行此代码的实际结果是范围已定义(可能正确)但其值设置为空, 虽然 - 我可以在运行时看到 args 数组中的正确值。 我还尝试设置更大的范围并使用 range.Value = "Pake value" 填充它,并看到在运行我的代码之后,正确的步骤范围变为空白! 所以,范围是正确的,数组中填充了我的值,InvokeMember 方法被正确调用:) 但是,所有值都设置为 null..
帮助...
【问题讨论】:
【参考方案1】:可以通过以下方式之一设置一个单元格或 1dim 数组:
Range range = SetRange();//Let's say range is set between A1 to D1
object[] args = 1, 2, 3, 4 ;
//Directly
range.Value = args;
//By Reflection
range.GetType().InvokeMember("Value", System.Reflection.BindingFlags.SetProperty, null, range, args);
2dim 数组不能直接设置,因此必须使用反射流来设置值矩阵。这个矩阵必须在集合之前建立,像这样:
Range range = SetRange();//Let's say range is set between A1 to C5
int rows = 5;
int columns = 3;
object[,] data = new object[rows, columns];
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
//Here I build the inside Array[,]
string uniqueValue = (i + j).ToString();
data[i, j] = "Insert your string value here, e.g: " + uniqueValue;
object[] args = data ;
range.GetType().InvokeMember("Value", System.Reflection.BindingFlags.SetProperty, null, range, args);
【讨论】:
你为什么使用反射?只需使用range.Value = data
或range.Value2 = data
。【参考方案2】:
至于你的问题,所有的范围都设置为null,我认为这是由于错误的参数。
为什么Type.Missing 在参数列表中?
因此,这应该是朝着正确方向迈出的一步:
object[] args = list.ToArray() ;
test.GetType().InvokeMember("Value", System.Reflection.BindingFlags.SetProperty, null, test, args);
此外,list.ToArray 只会生成 数组数组 而不是 矩阵,因此您应该以不同的方式构建矩阵,例如:
object[,] data = new object[14, 2];
int row = 0;
foreach (KeyValuePair<string, string> item in testCase.Steps)
//Here I build the inside Array[,]
data[row, 0] = item.Key;
data[row, 1] = item.Value;
++row;
object[] args = data ;
使用 InvokeMember 而不是更简单的方法背后的原因是什么:
test.Value = data;
?
希望这会有所帮助...
【讨论】:
为什么Type.Missing 在参数列表中? 如果要使用这种类型的shell,请在参数列表中设置它。事实上,这不是必需的。 list.ToArray 不会生成矩阵: 没错。这就是我的代码的缺陷。我将使用您采样的模式。谢谢! 为什么使用 InvokeMember 而不是直接设置 Range.Value? 我认为“value”属性可能仅用于设置单个值(单个单元格或范围),而 InvokeMember 有一个额外的设置数组的使用。无论如何,我会在早上再检查一次,如果可以使用直接设置,当然是首选。 InvokeMember 只是一种不同的、非常复杂的方式,使用反射来做同样的事情。如果你需要做一些更高级的事情,它有时会很有用,但不是在一般情况下。 :)以上是关于如何将值设置为二维 Excel 范围?的主要内容,如果未能解决你的问题,请参考以下文章