Как исправить ошибку «Индекс находится за границами массива» во внешней печатной форме 1С:ЗУП

Программист 1С v8.3 (Обычные формы) 1С:Зарплата и Управление Персоналом
← На главную

В процессе работы с программой 1С:Зарплата и Управление Персоналом (ЗУП), особенно в редакциях, использующих обычные формы (например, 2.5), разработчики и системные администраторы часто сталкиваются с ситуацией, когда внешняя печатная форма идеально работает у одного пользователя, но выдает фатальную ошибку у другого. Ошибка «Индекс находится за границами массива» является одной из самых распространенных и сигнализирует о проблемах в логике обработки данных внутри программного кода обработки.

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

Анализируем причину возникновения ошибки

Рассмотрим ситуацию, описанную в теме: программа сообщает об ошибке при попытке сформировать печатную форму. Текст ошибки прямо указывает на то, что код пытается обратиться к элементу коллекции (массива или таблицы) по индексу, которого не существует. Чаще всего это обращение к индексу [0] в пустом массиве.

Проанализируем фрагмент кода, который стал источником проблемы:


// Найдем дату начала (ДатаС) по конкретному состоянию сотрудника
СтруктураДатаС = Новый Структура;
СтруктураДатаС.Вставить("ПричинаОтсутствия", Перечисления.СостоянияРаботникаОрганизации.ОтпускПоБеременностиИРодам);

// Поиск строк в таблице работников
СтрокаТаблДатаС = ТаблРаботники.НайтиСтроки(СтруктураДатаС);

// Обращение к первому элементу результата поиска
ДатаС = СтрокаТаблДатаС[0].ДатаС;

В этом фрагменте метод НайтиСтроки() возвращает массив строк, соответствующих условию. Если в документе нет ни одной строки, где ПричинаОтсутствия соответствует значению ОтпускПоБеременностиИРодам, метод вернет пустой массив. Попытка получить значение СтрокаТаблДатаС[0] мгновенно вызывает исключение «Индекс находится за границами массива», так как в массиве нет элемента с индексом 0.

Почему у одного пользователя работает, а у другого — нет?

Это самый важный вопрос, который часто сбивает с толку. Если код один и тот же, почему поведение различается? Выясним основные причины:

  1. Различия в данных документа: Первый пользователь мог открыть документ, в котором действительно выбран «Отпуск по беременности и родам». Второй пользователь открыл другой экземпляр документа (или создал новый), где указана иная причина (например, «Болезнь»). Поскольку код жестко ориентирован только на одно значение перечисления, он ломается на любых других данных.
  2. Ограничение прав доступа (RLS): Если в информационной базе настроены права доступа на уровне записей, то второй пользователь может просто не «видеть» строки в табличной части или данные о состоянии сотрудника, даже если они заполнены. Для системы под этим пользователем таблица выглядит пустой, что приводит к пустому массиву в результате поиска.
  3. Кэширование данных: Иногда старая версия внешней печатной формы может «зависнуть» в кэше конкретного пользователя. Однако, как мы видим из обсуждения, чистка кэша не всегда помогает, так как проблема обычно кроется в логике кода.

Шаг 1: Исправляем код и добавляем проверку на пустой результат

Чтобы исключить падение программы, мы должны всегда проверять, были ли найдены данные, прежде чем обращаться к ним по индексу. Рассмотрим, как должен выглядеть безопасный код:


СтруктураПоиска = Новый Структура("ПричинаОтсутствия", Перечисления.СостоянияРаботникаОрганизации.ОтпускПоБеременностиИРодам);
НайденныеСтроки = ТаблРаботники.НайтиСтроки(СтруктураПоиска);

Если НайденныеСтроки.Количество() > 0 Тогда
    // Если строки найдены, берем данные из первой найденной строки
    ДатаС = НайденныеСтроки[0].ДатаС;
Иначе
    // Если строки не найдены, определяем альтернативную логику
    ДатаС = '00010101'; // Пустая дата или ДатаНачала из документа
    // Можно также вывести предупреждение пользователю
    Сообщить("В документе не найдены строки с состоянием 'Отпуск по беременности и родам'!");
КонецЕсли;

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

Шаг 2: Использование запросов для получения данных

Для повышения надежности и производительности, особенно при работе с большими документами, рекомендуется использовать запросы. Рассмотрим пример формирования условий заполнения, который упоминался в обсуждении:


| ВЫБОР 
|   КОГДА НеявкиИБолезниРаботники.ПричинаОтсутствия = ЗНАЧЕНИЕ(Перечисление.СостоянияРаботникаОрганизации.ОтпускПоБеременностиИРодам) 
|   ТОГДА НеявкиИБолезниРаботники.ДатаНачала 
|   ИНАЧЕ NULL 
| КОНЕЦ КАК ДатаС

При использовании запроса мы можем сразу сгруппировать данные или выбрать только те строки, которые соответствуют РАЗРЕШЕННЫЕ. Это автоматически решает проблему с правами доступа RLS, так как запрос просто не вернет те строки, на которые у пользователя нет прав, и мы снова сможем обработать пустой результат через проверку РезультатЗапроса.Пустой().

Шаг 3: Как попасть в отладку внешней печатной формы

Часто разработчики жалуются, что не могут «поймать» ошибку в отладчике, так как форма запускается через механизм дополнительных обработок. Разберем по шагам, как правильно отладить внешнюю печатную форму:

  1. Сохраните внешнюю печатную форму из справочника «Дополнительные отчеты и обработки» на свой компьютер как файл .epf.
  2. Откройте этот файл в конфигураторе.
  3. Установите точку останова в процедуре Печать (в модуле объекта).
  4. В режиме «1С:Предприятие» откройте этот файл через меню Файл — Открыть.
  5. Если форма написана по стандарту, она может потребовать передачу параметра (ссылки на документ). Чтобы упростить процесс, можно временно добавить в форму кнопку, которая будет вызывать процедуру Печать, передавая в нее ссылку на конкретный тестовый документ.
  6. Запустите выполнение. Программа остановится на вашей точке останова, и вы сможете просмотреть содержимое переменной ТаблРаботники и результат метода НайтиСтроки().

Рекомендации по улучшению кода печатных форм

Проанализировав ситуацию, мы можем выделить несколько правил «хорошего тона» при разработке печатных форм в 1С:

Таким образом, мы выяснили, что корень проблемы — не в «глюке» программы, а в недостаточной проверке входных данных в алгоритме. Исправив программный код и добавив проверку количества строк в массиве, мы обеспечим стабильную работу печатной формы для всех пользователей, независимо от их прав доступа и особенностей заполнения конкретных документов.

← На главную