В процессе работы с программой 1С:Зарплата и Управление Персоналом (ЗУП), особенно в редакциях, использующих обычные формы (например, 2.5), разработчики и системные администраторы часто сталкиваются с ситуацией, когда внешняя печатная форма идеально работает у одного пользователя, но выдает фатальную ошибку у другого. Ошибка «Индекс находится за границами массива» является одной из самых распространенных и сигнализирует о проблемах в логике обработки данных внутри программного кода обработки.
В данной статье мы подробно разберем, почему возникает эта ошибка в контексте документа «Неявки и болезни организаций», проанализируем программный код, вызывающий сбой, и рассмотрим методику отладки внешних печатных форм.
Рассмотрим ситуацию, описанную в теме: программа сообщает об ошибке при попытке сформировать печатную форму. Текст ошибки прямо указывает на то, что код пытается обратиться к элементу коллекции (массива или таблицы) по индексу, которого не существует. Чаще всего это обращение к индексу [0] в пустом массиве.
Проанализируем фрагмент кода, который стал источником проблемы:
// Найдем дату начала (ДатаС) по конкретному состоянию сотрудника
СтруктураДатаС = Новый Структура;
СтруктураДатаС.Вставить("ПричинаОтсутствия", Перечисления.СостоянияРаботникаОрганизации.ОтпускПоБеременностиИРодам);
// Поиск строк в таблице работников
СтрокаТаблДатаС = ТаблРаботники.НайтиСтроки(СтруктураДатаС);
// Обращение к первому элементу результата поиска
ДатаС = СтрокаТаблДатаС[0].ДатаС;
В этом фрагменте метод НайтиСтроки() возвращает массив строк, соответствующих условию. Если в документе нет ни одной строки, где ПричинаОтсутствия соответствует значению ОтпускПоБеременностиИРодам, метод вернет пустой массив. Попытка получить значение СтрокаТаблДатаС[0] мгновенно вызывает исключение «Индекс находится за границами массива», так как в массиве нет элемента с индексом 0.
Это самый важный вопрос, который часто сбивает с толку. Если код один и тот же, почему поведение различается? Выясним основные причины:
Чтобы исключить падение программы, мы должны всегда проверять, были ли найдены данные, прежде чем обращаться к ним по индексу. Рассмотрим, как должен выглядеть безопасный код:
СтруктураПоиска = Новый Структура("ПричинаОтсутствия", Перечисления.СостоянияРаботникаОрганизации.ОтпускПоБеременностиИРодам);
НайденныеСтроки = ТаблРаботники.НайтиСтроки(СтруктураПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
// Если строки найдены, берем данные из первой найденной строки
ДатаС = НайденныеСтроки[0].ДатаС;
Иначе
// Если строки не найдены, определяем альтернативную логику
ДатаС = '00010101'; // Пустая дата или ДатаНачала из документа
// Можно также вывести предупреждение пользователю
Сообщить("В документе не найдены строки с состоянием 'Отпуск по беременности и родам'!");
КонецЕсли;
Такой подход гарантирует, что даже при отсутствии нужных данных печатная форма либо выведет пустые значения, либо сообщит о проблеме в понятном виде, вместо того чтобы полностью прекратить работу с критической ошибкой.
Для повышения надежности и производительности, особенно при работе с большими документами, рекомендуется использовать запросы. Рассмотрим пример формирования условий заполнения, который упоминался в обсуждении:
| ВЫБОР
| КОГДА НеявкиИБолезниРаботники.ПричинаОтсутствия = ЗНАЧЕНИЕ(Перечисление.СостоянияРаботникаОрганизации.ОтпускПоБеременностиИРодам)
| ТОГДА НеявкиИБолезниРаботники.ДатаНачала
| ИНАЧЕ NULL
| КОНЕЦ КАК ДатаС
При использовании запроса мы можем сразу сгруппировать данные или выбрать только те строки, которые соответствуют РАЗРЕШЕННЫЕ. Это автоматически решает проблему с правами доступа RLS, так как запрос просто не вернет те строки, на которые у пользователя нет прав, и мы снова сможем обработать пустой результат через проверку РезультатЗапроса.Пустой().
Часто разработчики жалуются, что не могут «поймать» ошибку в отладчике, так как форма запускается через механизм дополнительных обработок. Разберем по шагам, как правильно отладить внешнюю печатную форму:
.epf.Печать (в модуле объекта).Печать, передавая в нее ссылку на конкретный тестовый документ.ТаблРаботники и результат метода НайтиСтроки().Проанализировав ситуацию, мы можем выделить несколько правил «хорошего тона» при разработке печатных форм в 1С:
Массив[0] должно быть обернуто в условие Если Массив.Количество() > 0.Таким образом, мы выяснили, что корень проблемы — не в «глюке» программы, а в недостаточной проверке входных данных в алгоритме. Исправив программный код и добавив проверку количества строк в массиве, мы обеспечим стабильную работу печатной формы для всех пользователей, независимо от их прав доступа и особенностей заполнения конкретных документов.