如何将值设置为二维 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 = datarange.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 范围?的主要内容,如果未能解决你的问题,请参考以下文章

如何获得正确的范围以将值设置为单元格?

如何将值存储在二维数组中?

如何将值推送到 QML 属性变量二维数组 - 动态?

如何实现excel数据导入批量生成二维码

如何在excel中生成一个在一定范围内的随机数

如何更快地将值写入访问数据库 - VBA(excel)