none
Excel. Получение строки из объекта Range и запись данных в отдельные ячейки. RRS feed

  • Вопрос

  • Здравствуйте!

    Язык C#. Подключаюсь к Excel с помощью позднего связывания. Задача такая: записать данные в файл. Сначала хотел с помощью Range выделить одну ячейку и записать в нее данные. Но, потом решил, что лучше будет выделить сразу целую строку, а потом уже работать с отдельными ячейками. Запись данных происходит, но не смотря на это во все ячейки, а не только в выбранную. Собственно, вопрос почему это происходит и как исправить. Спасибо.

    Код:

                string app_id = "Excel.Application";
                Type exceltype = Type.GetTypeFromProgID(app_id);
                object app = Activator.CreateInstance(exceltype);
    
                object workbooks = app.GetType().InvokeMember("Workbooks", BindingFlags.GetProperty, null, app, null);
                object workbook = workbooks.GetType().InvokeMember("Add", BindingFlags.InvokeMethod, null, workbooks, null);
                object worksheets = workbook.GetType().InvokeMember("Worksheets", BindingFlags.GetProperty, null, workbook, null);
                object worksheet = worksheets.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, worksheets, new object[] { 1 });
                object range = worksheet.GetType().InvokeMember("Range", BindingFlags.GetProperty, null, worksheet, new object[] { "A1", "C1" });
    
                object rows = range.GetType().InvokeMember("Rows", BindingFlags.GetProperty, null, range, null);
                object row = rows.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, rows, new object[] { 1 });
                object cells = row.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, row, new object[] { 1 });
                object cell = cells.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, cells, new object[] { 1 });
    
                cell.GetType().InvokeMember("Value", BindingFlags.SetProperty, null, cell, new object[] { "текст" });
                workbook.GetType().InvokeMember("SaveAs", BindingFlags.InvokeMethod, null, workbook, new object[] { @"D:\d1.xlsx" });


    • Изменено nik_w 24 июля 2012 г. 13:28
    24 июля 2012 г. 13:27

Ответы

  • В общем, оказалось, что объект Range позволяет обращаться к отдельным элементам(ячейкам) внутри себя. Т.е не надо было брать коллекцию строк, строку, коллекцию ячеек, ячейку как это сделано выше. Нужно лишь выделить нужный диапазон, получить отдельную ячейку с помощью Item и записать в нее значение.Что, собственно, я и сделал:

    object range = worksheet.GetType().InvokeMember("Range", BindingFlags.GetProperty, null, worksheet, new object[] { d1, d2 }); object item = null; for (int i = 0; i < str_data.Length; i++) { item = range.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, range, new object[] { i + 1 }); item.GetType().InvokeMember("Value", BindingFlags.SetProperty, null, item, new object[] { str_data[i] }); item.GetType().InvokeMember("ColumnWidth", BindingFlags.SetProperty, null, item, new object[] { str_data[i].Length }); } app.GetType().InvokeMember("DisplayAlerts", BindingFlags.SetProperty, null, app, new object[] { false }); workbook.GetType().InvokeMember("SaveAs", BindingFlags.InvokeMethod, null, workbook, new object[] { @"D:\d1.xls", file_format }); app.GetType().InvokeMember("Quit", BindingFlags.InvokeMethod, null, app, null);

    Marshal.ReleaseComObject(workbooks);
                Marshal.ReleaseComObject(workbook);
                Marshal.ReleaseComObject(worksheets);
                Marshal.ReleaseComObject(worksheet);
                Marshal.ReleaseComObject(range);
                Marshal.ReleaseComObject(item);

    где d1 и d2-диапазон, str_data-массив типа string с данными. Переменная file_format имеет значение 56, что соответствует формату xls; формату xlsx соответствует значение 51.Этот код не претендует на 100% правильность, возможно, можно и лучше.

    • Помечено в качестве ответа nik_w 25 июля 2012 г. 14:06
    25 июля 2012 г. 14:05

Все ответы

  • В общем, оказалось, что объект Range позволяет обращаться к отдельным элементам(ячейкам) внутри себя. Т.е не надо было брать коллекцию строк, строку, коллекцию ячеек, ячейку как это сделано выше. Нужно лишь выделить нужный диапазон, получить отдельную ячейку с помощью Item и записать в нее значение.Что, собственно, я и сделал:

    object range = worksheet.GetType().InvokeMember("Range", BindingFlags.GetProperty, null, worksheet, new object[] { d1, d2 }); object item = null; for (int i = 0; i < str_data.Length; i++) { item = range.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, range, new object[] { i + 1 }); item.GetType().InvokeMember("Value", BindingFlags.SetProperty, null, item, new object[] { str_data[i] }); item.GetType().InvokeMember("ColumnWidth", BindingFlags.SetProperty, null, item, new object[] { str_data[i].Length }); } app.GetType().InvokeMember("DisplayAlerts", BindingFlags.SetProperty, null, app, new object[] { false }); workbook.GetType().InvokeMember("SaveAs", BindingFlags.InvokeMethod, null, workbook, new object[] { @"D:\d1.xls", file_format }); app.GetType().InvokeMember("Quit", BindingFlags.InvokeMethod, null, app, null);

    Marshal.ReleaseComObject(workbooks);
                Marshal.ReleaseComObject(workbook);
                Marshal.ReleaseComObject(worksheets);
                Marshal.ReleaseComObject(worksheet);
                Marshal.ReleaseComObject(range);
                Marshal.ReleaseComObject(item);

    где d1 и d2-диапазон, str_data-массив типа string с данными. Переменная file_format имеет значение 56, что соответствует формату xls; формату xlsx соответствует значение 51.Этот код не претендует на 100% правильность, возможно, можно и лучше.

    • Помечено в качестве ответа nik_w 25 июля 2012 г. 14:06
    25 июля 2012 г. 14:05
  • Спасибо, что поделились решением.

    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    25 июля 2012 г. 14:30
    Отвечающий