Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从Excel数据源文件读取/写入值_C#_Excel_Visual Studio_Coded Ui Tests - Fatal编程技术网

C# 从Excel数据源文件读取/写入值

C# 从Excel数据源文件读取/写入值,c#,excel,visual-studio,coded-ui-tests,C#,Excel,Visual Studio,Coded Ui Tests,从中,我了解到我们无法更新到正在读取的CSV数据源文件,但我们是否有可能更新到Excel数据源 [TestMethod] [DataSource("System.Data.Odbc", "Dsn=Excel Files;Driver={Microsoft Excel Driver (*.xls)};dbq=|DataDirectory|\\data.xlsx;defaultdir=.;driverid=790;maxbuffersize=2048;pagetimeo

从中,我了解到我们无法更新到正在读取的CSV数据源文件,但我们是否有可能更新到Excel数据源

[TestMethod]
[DataSource("System.Data.Odbc", "Dsn=Excel Files;Driver={Microsoft Excel Driver (*.xls)};dbq=|DataDirectory|\\data.xlsx;defaultdir=.;driverid=790;maxbuffersize=2048;pagetimeout=5;readonly=false;", "Sheet1$", DataAccessMethod.Random)]
public void ExcelReadWrite()
{
    String a = TestContext.DataRow["Scenario"].ToString();
    String b = "New Order # generated from the app";
    Console.WriteLine(a + ": " + b);
    TestContext.DataRow["Order#"] = b; //Is this possible? if yes, how to write it back?
}
如果这不起作用,我应该采取什么方法? 可能是Microsoft.Office.Interop.Excel;还是数据表?沿着这些路径,我们还能使用[DataSource]吗

更新: 写一个新文件并不能很好地工作。原因是:

每个数据源行将在一次迭代中处理。数据源文件将始终是相同的原始副本。因此,每次迭代只能更新一行,并且会丢失以前更新的值


如果每次迭代都覆盖新文件,则最终只有一行包含更新的值;如果每次迭代都创建不同的文件,那么最终会产生太多的新文件,一个文件只包含一行更新的值,其余的都是相同的。例如,如果您的数据源文件包含5000行,您将创建5000个新文件。

读取数据源然后用更新的数据写回将不起作用,因为每次迭代测试[TestMethod]都是使用原始数据源执行的。上次迭代中更新的数据将在每次迭代中被覆盖。最后只得到最后一次迭代中的一行更新数据

解决方案:

将数据源中的数据加载到Excel.工作簿对象中 更新Excel.工作簿的数据 使用更新的Excel.工作簿对象覆盖数据源文件 下面是一个例子。data.xlsx是Excel数据源文件

    [TestMethod]
    [DataSource("System.Data.Odbc", "Dsn=Excel Files;Driver={Microsoft Excel Driver (*.xls)};dbq=|DataDirectory|\\data.xlsx;defaultdir=.;driverid=790;maxbuffersize=2048;pagetimeout=5;readonly=false", "Sheet1$", DataAccessMethod.Sequential)] // This is working Excel.xlsx connection!!! Excel (ODBC, Dsn)

    public void ExcelReadWrite()
    {
        //Open copied Excel file and create Excel object
        string projectName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
        //string dir = Environment.CurrentDirectory + @"\..\..\..\";
        string dir = System.IO.Directory.GetParent(Environment.CurrentDirectory).Parent.Parent.FullName;
        string targetFilename = "data.xlsx";
        string targetFile = dir + projectName + @"\" + targetFilename;

        object missing = Type.Missing;
        object misValue = System.Reflection.Missing.Value;
        Excel.Application excel = new Excel.Application();
        Excel.Workbook wb = excel.Workbooks.Open(targetFile, true, false);
        Excel.Worksheet ws = wb.Sheets[1];
        Excel.Range wr = ws.UsedRange;
        int rowCount = wr.Rows.Count;
        int colCount = wr.Columns.Count;

        //make some example data update for current iteration 
        int row = TestContext.DataRow.Table.Rows.IndexOf(TestContext.DataRow); //current iteration data row. zero base
        int generatedData = Convert.ToInt32(TestContext.DataRow[0]) + Convert.ToInt32(TestContext.DataRow[1]); //read from DataSource
        ws.Cells[row + 2, 3] = generatedData; //Worksheet, not zero base, and header row counts
        // ======================================================
        excel.DisplayAlerts = false;

        wb.SaveAs(targetFile, Excel.XlFileFormat.xlWorkbookDefault, misValue,
                                             misValue, misValue, misValue,
                                             Excel.XlSaveAsAccessMode.xlExclusive, misValue,
                                             misValue, misValue, misValue, misValue);
        wb.Close(missing, missing, missing);
        excel.Quit();
    }
更新:
无需制作数据源文件的新副本。如果设置readonly=false,则可以使用Excel.WORKING.SaveAs命令更新数据源文件。请注意[DataSource]部分中的此设置。

使用数据源驱动数据没有将新值写回数据源的功能。您可以通过写入新文件、复制未更改的字段和插入新值来实现类似的功能。您真正的问题是什么?为什么您认为需要修改数据源中的值?一个例子是,假设我们执行一个多次迭代的测试,使用业务提供的数据生成数百个订单,以覆盖不同的场景。我们希望在输入的同一数据行上写入订单号和其他相关信息。我们以前使用过HP UFT,现在希望继续使用CodedUI。如果无法对原始文件本身执行此操作,我可以使用您的解决方案将所有内容收集在一起写入新文件。更新中的单词是错误的。数据可以以追加模式写入新文件,因此每次迭代都会将其值写入文件末尾。使用基于StreamWriter outStream=new StreamWriterYourOutputFile.csv的内容,true;其中true表示附加到现有文件。如果您通过代码在[TestMethod]或[TestInitialize]中创建新文件,则每次迭代都会得到一个新文件,这当然会覆盖上一次迭代生成的数据。您唯一能做的就是手动创建/复制输出文件,并在每次迭代中附加到该文件。这只适用于文本文件,但不适用于Excel文件。希望我的观点表达清楚。如果你读了我写的东西,而不是你认为我写的东西,你会意识到我说的是以附加模式写入新文件。每次迭代都可以将其不变的输入数据加上修改后的值附加到新文件中。在运行结束时,有两个文件,原始和未更改的输入文件加上一个包含所有新值的新文件。关键点是,您实际上必须使用两个单独的文件,无论它们在开始时是否相同。一个是数据源,它是只读的,并驱动迭代;另一个是您读/写/更新的。对于csv文件,可以是附加模式,但对于Excel,每次迭代都必须覆盖整个文件。
    [TestMethod]
    [DataSource("System.Data.Odbc", "Dsn=Excel Files;Driver={Microsoft Excel Driver (*.xls)};dbq=|DataDirectory|\\data.xlsx;defaultdir=.;driverid=790;maxbuffersize=2048;pagetimeout=5;readonly=false", "Sheet1$", DataAccessMethod.Sequential)] // This is working Excel.xlsx connection!!! Excel (ODBC, Dsn)

    public void ExcelReadWrite()
    {
        //Open copied Excel file and create Excel object
        string projectName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
        //string dir = Environment.CurrentDirectory + @"\..\..\..\";
        string dir = System.IO.Directory.GetParent(Environment.CurrentDirectory).Parent.Parent.FullName;
        string targetFilename = "data.xlsx";
        string targetFile = dir + projectName + @"\" + targetFilename;

        object missing = Type.Missing;
        object misValue = System.Reflection.Missing.Value;
        Excel.Application excel = new Excel.Application();
        Excel.Workbook wb = excel.Workbooks.Open(targetFile, true, false);
        Excel.Worksheet ws = wb.Sheets[1];
        Excel.Range wr = ws.UsedRange;
        int rowCount = wr.Rows.Count;
        int colCount = wr.Columns.Count;

        //make some example data update for current iteration 
        int row = TestContext.DataRow.Table.Rows.IndexOf(TestContext.DataRow); //current iteration data row. zero base
        int generatedData = Convert.ToInt32(TestContext.DataRow[0]) + Convert.ToInt32(TestContext.DataRow[1]); //read from DataSource
        ws.Cells[row + 2, 3] = generatedData; //Worksheet, not zero base, and header row counts
        // ======================================================
        excel.DisplayAlerts = false;

        wb.SaveAs(targetFile, Excel.XlFileFormat.xlWorkbookDefault, misValue,
                                             misValue, misValue, misValue,
                                             Excel.XlSaveAsAccessMode.xlExclusive, misValue,
                                             misValue, misValue, misValue, misValue);
        wb.Close(missing, missing, missing);
        excel.Quit();
    }