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

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

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

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

Выясняем причину возникновения ошибки

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


МассивФизическихЛиц = Новый Массив;
МассивФизическихЛиц.Добавить(СсылкаНаОбъект);
МассивКадровДанных = Новый Массив;
МассивКадровДанных.Добавить("ИНН");

СтрокаКадровДанных = КадровыйУчет.КадровыеДанныеФизическихЛиц(Ложь, МассивФизическихЛиц, МассивКадровДанных)[0];
ОбластьШапки.Параметры.ИНН = СтрокаКадровДанных.ИНН;

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

Почему таблица может быть пустой? Рассмотрим три основные причины:

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

Использование отладки для локализации проблемы

Чтобы точно понять, что происходит внутри кода, разберем по шагам процесс отладки. Это позволит нам увидеть содержимое переменных в режиме реального времени.

Для начала установим точку останова. В конфигураторе найдем строку кода, где происходит вызов функции, и нажмем F9 (напротив строки должна появиться красная точка). Далее выполним следующие действия:

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

Пишем «безопасный» код для получения данных

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


ТабличныйДокумент = Новый ТабличныйДокумент;
МакетОбработки = ПолучитьМакет("Договор");
ОбластьШапки = МакетОбработки.ПолучитьОбласть("Шапка");

// 1. Извлекаем ФизическоеЛицо из документа
// Предположим, СсылкаНаОбъект — это документ Прием на работу
ФизЛицоСсылка = СсылкаНаОбъект.ФизическоеЛицо;

МассивФизическихЛиц = Новый Массив;
МассивФизическихЛиц.Добавить(ФизЛицоСсылка);

МассивКадровДанных = Новый Массив;
МассивКадровДанных.Добавить("ИНН");

// 2. Получаем таблицу данных
ТаблицаДанных = КадровыйУчет.КадровыеДанныеФизическихЛиц(Ложь, МассивФизическихЛиц, МассивКадровДанных);

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

ТабличныйДокумент.Вывести(ОбластьШапки);

Альтернативные способы получения реквизитов

Если нам нужно получить только простые реквизиты, такие как ИНН или Страховой номер (СНИЛС), которые не требуют анализа истории изменений, мы можем воспользоваться более легким методом общего назначения. Проанализируем пример использования функции ЗначениеРеквизитаОбъекта:


// Получаем ИНН напрямую из справочника ФизическиеЛица
ИНН_Значение = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СсылкаНаОбъект.ФизическоеЛицо, "ИНН");

Если ЗначениеЗаполнено(ИНН_Значение) Тогда
    ОбластьШапки.Параметры.ИНН = ИНН_Значение;
Иначе
    ОбластьШапки.Параметры.ИНН = "__________"; // Прочерк для ручного заполнения
КонецЕсли;

Этот метод работает быстрее, так как не вызывает тяжелые механизмы формирования динамических запросов, заложенные в модуле КадровыйУчет.

Особенности функции КадровыеДанныеФизическихЛиц

Рассмотрим подробнее параметры функции КадровыйУчет.КадровыеДанныеФизическихЛиц. Важно понимать, что в ЗУП 3.1 данные могут зависеть от даты. Полный синтаксис функции выглядит так:

КадровыеДанныеФизическихЛиц(ТолькоТекущиеДанные, СписокФизлиц, СписокПолей, Дата, ПрочитатьДанныеСПериодом)

Посмотрим на пример правильного вызова с учетом даты документа:


Поля = "ИНН, ФИОПолные, ДатаРождения";
Данные = КадровыйУчет.КадровыеДанныеФизическихЛиц(Ложь, МассивФизЛиц, Поля, СсылкаНаОбъект.Дата);

Важный совет: В типовых конфигурациях ЗУП существует специализированная функция КадровыйУчет.ДанныеФизическихЛицДляПечати. Она возвращает уже отформатированные данные, например, паспортные данные одной строкой со всеми сериями и номерами, что избавляет разработчика от необходимости вручную собирать строку из разных реквизитов таблицы.

Резюме по решению проблемы

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

  1. Всегда проверяйте тип передаваемой ссылки. В кадровые функции передавайте ФизическоеЛицо, а не сам документ.
  2. Никогда не обращайтесь к индексу [0] без предварительной проверки Количество() > 0.
  3. Активно используйте Отладчик для проверки содержимого переменных и таблиц в сложных ситуациях.
  4. Передавайте дату документа в параметры функций получения данных, чтобы информация в печатной форме соответствовала историческому моменту совершения операции.

Применяя эти подходы, вы сделаете свои разработки в 1С более надежными и профессиональными, а пользователи не столкнутся с неприятными ошибками в процессе работы.

← На главную