Чтение / запись значений из файла источника данных 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.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; или же DataTable? Идя этими путями, мы можем все еще быть в состоянии использовать [DataSource]?

Обновление: запись в новый файл не очень хорошо работает. Причина в том, что:

Каждая строка источника данных будет обработана за одну итерацию. Файл источника данных всегда будет одной и той же оригинальной копией. Поэтому вы можете обновить только одну строку за итерацию, и вы потеряете ранее обновленные значения.

Если вы перезаписываете новый файл каждую итерацию, вы получите только одну строку, содержащую обновленные значения; если вы создаете разные файлы на каждой итерации, у вас получается слишком много новых файлов, один файл содержит только одну строку обновленных значений, а все остальные одинаковые. Например, если ваш файл источника данных содержит 5000 строк, вы создадите 5000 новых файлов.

1 ответ

Решение

Чтение DataSource и последующая запись с обновленными данными НЕ будут работать, потому что каждая итерация теста [TestMethod] выполняется с исходным источником данных. Обновленные данные из последней итерации будут перезаписываться на каждой итерации. Вы получите только одну строку обновленных данных с самой последней итерации.

Решение:

data.xlsx:

Scenario    SecondCol   Result
89          23          Value
11          800         Value
888         111         Value
  1. загрузить данные из источника данных в объект Excel.Workbook
  2. обновить данные из Excel.Workbook
  3. перезаписать файл источника данных обновленным объектом Excel.Workbook

Ниже приведен пример. 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();
    }

Обновление: нет необходимости делать новую копию файла источника данных. Файл источника данных может быть обновлен с Excel.Workbook.SaveAs команда, если вы установите readonly=false, Обратите внимание на этот параметр в [DataSource] раздел.

Другие вопросы по тегам