При разработке внешних обработок и доработке механизмов групповой печати в конфигурациях на базе Библиотеки стандартных подсистем (например, «Бухгалтерия предприятия 3.0») разработчики нередко сталкиваются с ошибкой «Индекс находится за границами массива». Дополнительно возникает вопрос: как перевести логику вывода документов в файл Excel из режима обычных форм (1С 8.2) на стандарты управляемого приложения 1С 8.3.
Разберем детально причины возникновения этих сложностей, проанализируем ошибки в исходном коде и рассмотрим правильные варианты программного формирования и сохранения печатных форм в файл.
Выясним причину исключительной ситуации, возникающей в клиентской процедуре печати. Посмотрим на фрагмент исходного кода:
Если МассивАктов.Количество Тогда
СтрСпПечФормАкт = СоздатьСпиокЗначенийДляВыбора("АктСверкиВзаиморасчетов", Истина, ЭтаФорма.НастройкаПечатиАкт);
Если ТабПечФорм[0].Обработчик = "" Тогда
//Внешняя форма
ПечатьВнешнейПечатнойФормы(МассивАктов);
Иначе
//Встроенная
УправлениеПечатьюКлиент.ВыполнитьКомандуПечати(
ТабПечФорм[0].МенеджерПечати,
ТабПечФорм[0].Идентификатор,
МассивАктов,
Неопределено,
ПараметрыПечати
);
КонецЕсли;
КонецЕсли;
В этом участке кода присутствуют сразу две критические ошибки:
Если ТабПечФорм[0].Обработчик = "" Тогда. Коллекция ТабПечФорм на момент вызова пуста или не инициализирована. Обращение по индексу [0] к пустой таблице значений или массиву всегда вызывает исключение выхода за границы. Кроме того, результат функции СоздатьСпиокЗначенийДляВыбора присваивается переменной СтрСпПечФормАкт, а проверка выполняется над ТабПечФорм, что указывает на рассинхронизацию переменных.Если МассивАктов.Количество Тогда содержит синтаксическую ошибку встроенного языка 1С. Во-первых, Количество() у массива — это метод, а не свойство, поэтому требуются круглые скобки. Во-вторых, в конструкции Если ожидается строго булево значение. Платформа 1С не выполняет неявное приведение чисел к булеву типу, поэтому необходимо явное сравнение: Если МассивАктов.Количество() > 0 Тогда.Рассмотрим, как обеспечить безопасный доступ к элементам коллекции. Перед получением нулевого элемента всегда следует выполнять проверку на заполненность:
Если ТабПечФорм.Количество() > 0 Тогда
Если ТабПечФорм[0].Обработчик = "" Тогда
ПечатьВнешнейПечатнойФормы(МассивАктов);
Иначе
УправлениеПечатьюКлиент.ВыполнитьКомандуПечати(
ТабПечФорм[0].МенеджерПечати,
ТабПечФорм[0].Идентификатор,
МассивАктов,
Неопределено,
ПараметрыПечати
);
КонецЕсли;
КонецЕсли;
Метод УправлениеПечатьюКлиент.ВыполнитьКомандуПечати предназначен исключительно для интерактивного вывода печатных форм пользователю на экран. Если стоит задача автоматически выгрузить акты сверки в файл Excel, этот метод не подходит.
Разберем правильные способы программного формирования табличного документа на сервере и его последующего сохранения.
Рассмотрим использование стандартной серверной функции БСП УправлениеПечатью.СформироватьПечатныеФормы. Этот метод берет на себя создание всех служебных структур и гарантирует корректную работу со встроенными макетами документов.
&НаСервере
Функция ПолучитьТабличныйДокументАктаСверки(МассивАктов)
ПараметрыПечати = Новый Структура;
ПечатныеФормы = УправлениеПечатью.СформироватьПечатныеФормы(
"Документ.АктСверкиВзаиморасчетов",
"АктСверки",
МассивАктов,
ПараметрыПечати,
Неопределено
);
Если ПечатныеФормы.КоллекцияПечатныхФорм.Количество() > 0 Тогда
Возврат ПечатныеФормы.КоллекцияПечатныхФорм[0].ТабличныйДокумент;
КонецЕсли;
Возврат Неопределено;
КонецФункции
Проанализируем второй вариант — прямой вызов экспортной процедуры Печать модуля менеджера документа АктСверкиВзаиморасчетов. При таком подходе необходимо правильно подготовить входные параметры.
Обратите внимание на параметр ОбъектыПечати: он представляет собой коллекцию типа СписокЗначений. Данный список связывает ссылки на документы с областями табличного документа для постраничной разбивки и нумерации. При прямом вызове мы передаем в него пустой список, который будет заполнен внутри процедуры печати.
&НаСервере
Функция СформироватьПечатьНапрямую(МассивАктов)
КоллекцияПечатныхФорм = УправлениеПечатью.ПодготовитьКоллекциюПечатныхФорм("АктСверки");
ОбъектыПечати = Новый СписокЗначений;
ПараметрыВывода = УправлениеПечатью.ПодготовитьСтруктуруПараметровВывода();
Документы.АктСверкиВзаиморасчетов.Печать(
МассивАктов,
Новый Структура,
КоллекцияПечатныхФорм,
ОбъектыПечати,
ПараметрыВывода
);
СтрокаТаблицы = КоллекцияПечатныхФорм.Найти("АктСверки", "ИмяМакета");
Если СтрокаТаблицы <> Неопределено Тогда
Возврат СтрокаТаблицы.ТабличныйДокумент;
КонецЕсли;
Возврат Неопределено;
КонецФункции
Посмотрим, как сохранить полученный табличный документ в файл на диске. В 1С 8.3 для указания формата файла используется системное перечисление ТипФайлаТабличногоДокумента.
Важные особенности форматов:
ТипФайлаТабличногоДокумента.XLSX (поддерживает более 1 млн строк).ТипФайлаТабличногоДокумента.XLS (имеет жесткое ограничение в 65 536 строк).Пример сохранения табличного документа на стороне сервера:
&НаСервере
Процедура СохранитьТабличныйДокументВФайл(ТабличныйДокумент, ПолноеИмяФайла)
Если ТабличныйДокумент <> Неопределено Тогда
ТабличныйДокумент.Записать(ПолноеИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
КонецЕсли;
КонецПроцедуры
Помните, что выполнение метода Записать на сервере сохраняет файл в файловую систему сервера. Если файл необходимо передать на рабочий компьютер пользователя, поместите сформированный файл или двоичные данные во временное хранилище и используйте стандартные клиентские методы получения файлов (например, ПолучитьФайл или НачатьПолучениеФайловССервера).