Итак, вам дают файл Excel, в котором есть несколько листов, которые вам надо заполнить. Никаких особо проблем с заполнением у вас не возникает. Вы находите свою навороченную обработку, которая уже заполняла файл Excel, вычисляя по-модному цены номенклатуры и перспективных клиентов с контактными данными. Но тут БАА-Ц оказывается это обработка работала еще под УТ 10.3 или БП 2.0, в общем написано под наше доброе обычное толстое приложение. А нам же надо всё под тонкого клиента (УТ 11, БП 3.0..) Вроде бы ничего страшно, сейчас быстро переделаем, но заглянув вовнутрь, оказывается, что сделать надо много и переделать, т.к. все данные из базы теперь в управляемых формах получаем на сервере и не все типы данных можно передать обратно на клиент. Имеем ввиду, что Excel стоит только на клиенте. Конечно, Excel может стоять и на сервере, но делать обработку и отсылать клиенту. надеясь, что у него Excel всё-таки стоит как-то не очень. К тому же всё чаще и чаще встречаются сервера 1С, работающие на Linux.
Немного поразмыслив, накидал обработку-библиотеку, которая позволяет организовать эту работу немного проще. Обработка может сама по себе работать и её брать за основу или же её можно встроить в конфигурации в обработки (в коде надо поменять пару строк).
Как писали и пишут под обычное приложение процедуру заполнения листов Excel причём эта процедура могла располагаться как и в модуле форме, так в модуле обработке^
Процедура ЗаполнитьЛистыExcel()
Excel = Новый COMОбъект("Excel.Application");
КнигаExcel=Excel.WorkBooks.Open(ИмяФайлаExcel);
Excel.Visible = 0;
ЛистЦены = КнигаExcel.Sheets("Цены");
//получаем как-то выборку по ценам
НомерСтроки = 0;
Пока ВыборкаПоЦенам.Следующий() Цикл
ЛистЦены.Сells(номерСтроки,1).Value = ВыборкаПоЦенам.Цена;
//....
ЛистЦены.Сells(номерСтроки,10).Value = ВыборкаПоЦенам.ЕдиницаИзмерения;
НомерСтроки = НомерСтроки + 1;
КонецЦикла;
ЛистКонтрагенты = КнигаExcel.Sheets("Контрагенты");
//получаем как-то выборку по ценам
НомерСтроки = 0;
Пока ВыборкаПоКонтрагентам.Следующий() Цикл
ЛистЦены.Сells(номерСтроки,1).Value = ВыборкаПоКонтрагентам.Наименование;
//....куча разных колонок
ЛистЦены.Сells(номерСтроки,5).Value = ВыборкаПоКонтрагентам.ИНН;
ЛистЦены.Сells(номерСтроки,6).Value = ВыборкаПоКонтрагентам.КПП;
НомерСтроки = НомерСтроки + 1;
КонецЦикла;
Excel.DisplayAlerts = Ложь;
Excel.ActiveWorkbook.SaveAs(ИмяФайлаExcel);
Excel.Workbooks.Close();
Excel.Application.Quit();
Excel.Quit();
КонецПроцедуры
Основной здесь момент, что в одной процедура получаем выборку, т.е. данные из базы, и сразу ей начинаем заполнять лист Excel. В управляемых формах так нельзя, поэтому пишем вот так:
&НаКлиенте
Процедура ЗаполнитьЛистыExcel
Excel = Новый COMОбъект("Excel.Application");
КнигаExcel =Excel.WorkBooks.Open(ИмяФайлаExcel);
Excel.Visible = 0;
ДанныеЛистовExcel = ЗаполнитьДаннымиЛистыНаСервере();
ЗаполнитьЛистыExcel(КнигаExcel,ДанныеЛистовExcel);
Excel.DisplayAlerts = Ложь;
Excel.ActiveWorkbook.SaveAs(ИмяФайлаExcel);
Excel.Workbooks.Close();
Excel.Application.Quit();
Excel.Quit();
КонецПроцедуры
&НаСервере
Функция ЗаполнитьДаннымиЛистыНаСервере()
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
КнигаExcel = ВнешниеОбработки.Создать(ОбработкаОбъект.ИспользуемоеИмяФайла,Ложь);
//КнигаExcel = Обработки.ИнтерфейсExcel.Создать(); Так пишем если обработку встроили в конфигурацию
ЛистЦены = КнигаExcel .Sheets("Цены");
//получаем как-то выборку по ценам
НомерСтроки = 0;
Пока ВыборкаПоЦенам.Следующий() Цикл
ЛистЦены.Сells(номерСтроки,1).Value = ВыборкаПоЦенам.Цена;
//....
ЛистЦены.Сells(номерСтроки,10).Value = ВыборкаПоЦенам.ЕдиницаИзмерения;
НомерСтроки = НомерСтроки + 1;
КонецЦикла;
ЛистКонтрагенты = КнигаExcel.Sheets("Контрагенты");
//получаем как-то выборку по ценам
НомерСтроки = 0;
Пока ВыборкаПоКонтрагентам.Следующий() Цикл
ЛистЦены.Сells(номерСтроки,1).Value = ВыборкаПоКонтрагентам.Наименование;
//....куча разных колонок
ЛистЦены.Сells(номерСтроки,5).Value = ВыборкаПоКонтрагентам.ИНН;
ЛистЦены.Сells(номерСтроки,6).Value = ВыборкаПоКонтрагентам.КПП;
НомерСтроки = НомерСтроки + 1;
КонецЦикла;
Возврат КнигаExcel.ПолучитьДанныеКниги();
КонецФункции
Вот в принципе и всё. Т.е. код из обычного приложения можно просто скопировать и вставить в серверную функцию управляемой формы и всё будет работать также, данные возввращаются методом КнигаExcel.ПолучитьДанныеКниги(). В обработке реализованы методы:
Sheets(ИмяЛиста) - получает лист Excel по имени (если листа с таким именем не будет в книгу Excel будет добавлен такой лист)
Cells(НомерСтроки, НомерКолонки) - получение ячейки по координатом. Для установке значения нужно установить свойство Value
Пока этих методов мне хватило, может что-то ещё из арсенала Excel можно будет реализовать.
Таким образом , я вижу применения данного подхода в следующих случаях:
- Рефакторинг кода обычного приложения под управляемые формы при работе с Excel
- Абстрагирование от задачи компоновки структур данных листов Excel на сервере, чтобы сосредоточиться на логике получения самих данных.
К статье приложена обработка с методами и тестовый пример заполнения данных двух листов Excel.