Как автоматически заполнить табличную часть документа данными из справочника в 1С 7.7?

Программист 1С v7.7
← На главную

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

Основы перебора справочника и добавления строк

Для заполнения документа по нажатию кнопки (например, «Заполнить»), нам необходимо инициировать цикл по справочнику и перенести данные. При этом важно отфильтровать элементы, которые являются папками (группами), чтобы в документе не образовывались пустые или некорректные строки.

Рассмотрим базовый пример кода для 1С 7.7, где мы проверяем, является ли элемент группой, с помощью метода ЭтоГруппа():


Спр = СоздатьОбъект("Справочник.Сотрудники");
Спр.ВыбратьЭлементы();
Пока Спр.ПолучитьЭлемент() = 1 Цикл
    Если Спр.ЭтоГруппа() = 1 Тогда 
        Продолжить;
    КонецЕсли;
    
    НоваяСтрока();
    Сотрудник = Спр.ТекущийЭлемент();
    // Дальнейшее заполнение реквизитов строки...
КонецЦикла;

Важное замечание по оптимизации: Использование метода НоваяСтрока() в цикле напрямую обращается к объекту документа. Если сотрудников несколько сотен, это вызовет постоянную перерисовку формы и замедлит работу. Более оптимальный подход — использовать объект ТаблицаЗначений. Мы можем заполнить таблицу значений в памяти, а затем перенести её в документ одним вызовом метода Загрузить(). Это сработает практически мгновенно.

Еще более быстрым и правильным вариантом будет использование объекта «Запрос». Запрос отработает на уровне базы данных, позволит сразу отсечь группы условием (например, Условие(Сотрудник.ЭтоГруппа() = 0);) и автоматически получит значения периодических реквизитов на нужную дату.

Работа с периодическими реквизитами (Оклад)

Если мы переносим оклад сотрудника, нужно помнить, что в 1С 7.7 он часто является периодическим реквизитом. Чтобы получить правильное значение, мы должны обращаться к истории реквизита на конкретную дату (чаще всего — на дату документа ДатаДок).

Если получать оклад без указания даты, мы рискуем получить неверные данные, особенно если документ оформляется "задним числом" или расчет проводится за прошлый период.

Рассмотрим способы получения периодического значения:

  1. Явное получение на дату: Оклад = Спр.ТекущийЭлемент().Оклад.Получить(ДатаДок);
  2. Оптимизация цикла: перед циклом можно один раз вызвать метод ИспользоватьДату(ДатаДок). После этого обращение к периодическим реквизитам будет происходить напрямую (Спр.Оклад), и платформа автоматически вернет значение на установленную дату. Это значительно ускоряет работу кода.

Проверка принадлежности к группе (Уволенные, Декрет)

Допустим, нам необходимо обнулить оклад для сотрудников, находящихся в группах "Уволенные" или "Декрет". Для этого в 1С 7.7 существует метод ПринадлежитГруппе().

Частая ошибка начинающих разработчиков — передача строки в этот метод:


// НЕПРАВИЛЬНО:
Если Спр.ТекущийЭлемент().ПринадлежитГруппе("Уволенные") = 1 Тогда...

Метод ПринадлежитГруппе() принимает не строку с наименованием, а ссылку на объект (саму группу справочника). Чтобы код заработал, сначала нужно получить ссылку на группу. Можно использовать поиск:


СпрГрупп = СоздатьОбъект("Справочник.Сотрудники");
Если СпрГрупп.НайтиПоНаименованию("Уволенные") = 1 Тогда
    ГруппаУволенные = СпрГрупп.ТекущийЭлемент();
КонецЕсли;

Если Спр.ТекущийЭлемент().ПринадлежитГруппе(ГруппаУволенные) = 1 Тогда
    Оклад = 0;
КонецЕсли;

Архитектурные грабли: Поиск групп по наименованию (НайтиПоНаименованию) крайне ненадежен. Пользователи могут переименовать папку, добавить пробел или изменить регистр, после чего код сломается.

Проанализируем лучшие способы решения этой задачи:

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

Особенности для платформы 1С:Предприятие 8.x

Если вы переносите подобный функционал на новые версии платформы (1С 8.2, 8.3) с управляемыми формами, подходы кардинально меняются. На клиенте (в процедурах &НаКлиенте) нет прямого доступа к объектной модели базы данных. Построчное добавление элементов в табличную часть на клиенте вызывает контекстные вызовы сервера, что критически замедляет работу.

В «восьмерке» необходимо вызывать серверную процедуру, там выполнять запрос к справочнику, результат запроса выгружать в таблицу, а затем загружать её в табличную часть документа одной командой (Объект.ИмяТабличнойЧасти.Загрузить(РезультатЗапроса)). Кадровые статусы в современных конфигурациях всегда реализованы через регистры сведений, а не через папки справочника.

← На главную