Разработка систем кадрового учета в среде «1С:Предприятие» — одна из классических задач, с которой сталкивается любой начинающий программист. На первый взгляд задача кажется простой: достаточно создать список организаций, список людей и как-то зафиксировать, кто где работает. Однако дьявол кроется в деталях архитектуры баз данных. Неверный шаг на этапе проектирования структуры данных может привести к тому, что система окажется нежизнеспособной в реальных условиях эксплуатации.
В рамках этой статьи мы подробно разберем, как спроектировать и реализовать надежный кадровый механизм в пустой конфигурации с нуля. Мы проанализируем распространенные ошибки новичков, детально рассмотрим правильную архитектуру решения, настроим необходимые объекты метаданных, напишем программный код проведения документов и разработаем гибкий отчет на Системе компоновки данных (СКД).
Очень часто у начинающих разработчиков возникает соблазн решить задачу самым простым путем. Например, создать справочник ФизическиеЛица и добавить в него реквизит Организация с типом ссылки на справочник Организации. На первый взгляд это кажется логичным: открываем карточку человека и сразу видим, в какой компании он работает. Нам даже предложили готовый поисковый запрос для такой структуры:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ФизическиеЛица.Ссылка КАК Ссылка
|ИЗ
| Справочник.ФизическиеЛица КАК ФизическиеЛица
|ГДЕ
| ФизическиеЛица.Организация = &Организация";
Давайте проанализируем эту ситуацию и выясним причину, почему такой подход категорически неприемлем в реальном учете:
Организация в его карточке. В этот момент вся история его предыдущей работы в системе сотрется навсегда. Мы не сможем узнать, где он работал месяц или год назад.Для создания правильной архитектуры нам понадобятся специализированные объекты: справочники для хранения базовой информации, перечисление для фиксации видов событий, периодический регистр сведений для хранения истории и документы для отражения хозяйственных операций.
Запустим конфигуратор и разберем по шагам процесс создания структуры метаданных.
Во-первых, создадим справочник Организации. Этот справочник будет содержать список юридических лиц. Для нашей задачи в нем достаточно оставить стандартные реквизиты: Код и Наименование.
Во-вторых, добавим справочник ФизическиеЛица. Он предназначен для хранения персональных сведений о людях (ФИО, паспортные данные, ИНН). Обратите внимание: мы не добавляем внутрь этого справочника реквизит Организация.
В-третьих, создадим перечисление СостоянияРаботников. Этот объект поможет нам классифицировать кадровые события. Перейдем в ветку «Перечисления», добавим новое перечисление и на вкладке «Данные» введем два значения:
ПринятУволенДля того чтобы система помнила всю историю взаимоотношений сотрудников и работодателей, мы применим специальную таблицу — регистр сведений. Создадим регистр сведений РаботникиОрганизаций. Настроим его свойства следующим образом:
В пределах дня. Это позволит нам фиксировать кадровые изменения посуточно. Если требуется более точный учет (вплоть до минут или секунд), можно выбрать В пределах секунды.Подчинен регистратору. Это ключевой момент: записи в этот регистр смогут вносить только документы при проведении. Вручную пользователь ничего изменить не сможет, что гарантирует целостность данных.Теперь перейдем на вкладку «Данные» и настроим структуру полей регистра:
Организация (Тип: СправочникСсылка.Организации). Поставим свойство «Ведущее», чтобы при удалении организации автоматически очищались связанные записи в регистре.ФизическоеЛицо (Тип: СправочникСсылка.ФизическиеЛица). Тоже установим свойство «Ведущее».Состояние (Тип: ПеречислениеСсылка.СостоянияРаботников). Здесь будет храниться актуальный статус сотрудника в организации на дату записи.Регистрировать прием и увольнение сотрудников мы будем с помощью двух отдельных документов. Создадим их.
Создаем новый документ ПриемНаРаботу. На вкладке «Данные» добавим следующие реквизиты:
Организация (Тип: СправочникСсылка.Организации)ФизическоеЛицо (Тип: СправочникСсылка.ФизическиеЛица)Переходим на вкладку «Движения». В дереве регистров находим наш регистр сведений РаботникиОрганизаций и ставим напротив него галочку. Нажимаем кнопку «Конструктор движений». В открывшемся окне проверяем, что выбран тип движения «Запись», и сопоставляем поля:
Период = Дата (дата документа)Организация = ОрганизацияФизическоеЛицо = ФизическоеЛицоСостояние = Перечисления.СостоянияРаботников.ПринятПосле нажатия кнопки «ОК» система автоматически сгенерирует следующий код в модуле документа:
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
//{{КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРА
// Данный фрагмент построен конструктором.
// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!
// запись движения по регистру РаботникиОрганизаций
Движения.РаботникиОрганизаций.Записывать = Истина;
Движение = Движения.РаботникиОрганизаций.Добавить();
Движение.Период = Дата;
Движение.Организация = Организация;
Движение.ФизическоеЛицо = ФизическоеЛицо;
Движение.Состояние = Перечисления.СостоянияРаботников.Принят;
//}}КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРА
КонецПроцедуры
Создаем документ Увольнение. Реквизиты будут точно такими же: Организация и ФизическоеЛицо. Переходим на вкладку «Движения», отмечаем регистр РаботникиОрганизаций и с помощью конструктора движений формируем код проведения. Единственное отличие — в поле состояния мы записываем статус увольнения:
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
Движения.РаботникиОрганизаций.Записывать = Истина;
Движение = Движения.РаботникиОрганизаций.Добавить();
Движение.Период = Дата;
Движение.Организация = Организация;
Движение.ФизическоеЛицо = ФизическоеЛицо;
Движение.Состояние = Перечисления.СостоянияРаботников.Уволен;
КонецПроцедуры
Теперь при проведении этих документов система будет автоматически формировать записи в периодическом регистре сведений, последовательно отражая историю работы каждого человека.
Для получения списка работающих сотрудников на любую выбранную дату мы воспользуемся мощным встроенным инструментом — Системой компоновки данных (СКД). Она позволит нам избежать написания сложного программного кода для вывода отчета на экран.
Создаем новый объект Отчет «СписокРаботников». Нажимаем кнопку «Открыть схему компоновки данных» и соглашаемся на создание схемы по умолчанию.
Разберем по шагам настройку схемы компоновки:
РаботникиОрганизаций. Нам нужна не основная физическая таблица регистра, а его виртуальная таблица СрезПоследних. Она автоматически вычисляет последние актуальные записи на любой указанный момент времени.
Перетаскиваем таблицу РаботникиОрганизаций.СрезПоследних в поле «Таблицы».
ОрганизацияФизическоеЛицоСостояниеРаботникиОрганизацийСрезПоследних.Состояние = ЗНАЧЕНИЕ(Перечисление.СостоянияРаботников.Принят)
В результате автоматически сформируется следующий текст запроса:
ВЫБРАТЬ
РаботникиОрганизацийСрезПоследних.Организация КАК Организация,
РаботникиОрганизацийСрезПоследних.ФизическоеЛицо КАК ФизическоеЛицо
ИЗ
РегистрСведений.РаботникиОрганизаций.СрезПоследних(&Период, ) КАК РаботникиОрганизацийСрезПоследних
ГДЕ
РаботникиОрганизацийСрезПоследних.Состояние = ЗНАЧЕНИЕ(Перечисление.СостоянияРаботников.Принят)
Обратите внимание на параметр &Период в виртуальной таблице. Платформа 1С автоматически создаст его в настройках отчета, и именно он будет отвечать за выбор произвольной даты.
Теперь перейдем на вкладку «Параметры» в СКД:
Период. Для удобства пользователя изменим его заголовок на «Дата отчета».Дата (можно с составом даты «Дата» без указания времени).Перейдем на вкладку «Настройки» для создания структуры вывода отчета:
Организация. Это сгруппирует наших сотрудников по компаниям.Организация добавим подчиненную группировку. Поле группировки указывать не нужно — выберем «Детальные записи». Это выведет список людей в рамках каждой организации.ФизическоеЛицо.Давайте запустим систему в режиме пользователя и проверим, как работает наш механизм:
Организации: добавим «ООО Ромашка» и «ИП Иванов».ФизическиеЛица: внесем записи «Петров Петр Петрович» и «Сидоров Сидор Сидорович».ПриемНаРаботу от 01.01.2023. Примем Петрова в «ООО Ромашка». Проведем документ.ПриемНаРаботу от 15.01.2023. Примем Сидорова в «ООО Ромашка». Проведем документ.Увольнение от 01.02.2023. Уволим Петрова из «ООО Ромашка». Проведем документ.Теперь откроем наш отчет «Список работников» и проверим вывод данных на разные даты:
Таким образом, мы успешно решили поставленную задачу. Спроектированная нами архитектура полностью соответствует стандартам разработки программных продуктов на платформе «1С:Предприятие». Она надежна, сохраняет полную историю изменений во времени, легко масштабируется (например, при необходимости добавить учет должностей или окладов в тот же регистр сведений) и позволяет оперативно получать точную отчетность на любой момент времени.