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