Как автозаполнять реквизиты одного справочника данными из другого в 1С 8.3: от простых костылей к правильной архитектуре

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

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

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

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

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

Чем это грозит на практике?

  1. Рассинхронизация данных. Если курсанту присвоят новое звание в справочнике Военнослужащие, в ранее созданных элементах справочника УчебнаяДеятельностьКурсантов останется старое звание. Данные перестанут быть актуальными.
  2. Избыточный объем базы данных. Повторяющиеся текстовые строки будут занимать лишнее место на диске СУБД, что со временем замедлит работу всей системы.
  3. Ошибки ручного ввода. При дублировании полей повышается вероятность опечаток со стороны пользователей.

Рассмотрим правильные и компромиссные варианты реализации этой задачи.

Способ 1. Использование ссылочного типа и путей к данным на форме (Без дублирования в БД)

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

Разберем процесс настройки по шагам:

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

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

Важное предупреждение о производительности: Использование обращений "через точку" в путях к данным на управляемой форме очень удобно, но имеет скрытый подводный камень. Каждый раз при отрисовке формы система будет выполнять неявные запросы (операции LEFT JOIN) к таблице СУБД Военнослужащие. На высоконагруженных системах с десятками тысяч записей это может привести к замедлению открытия карточек. Если критически важна скорость работы, лучше использовать динамическое считывание данных при открытии формы в одну транзакцию.

Способ 2. Программное заполнение реквизитов через событие «ПриИзменении» (Если копирование неизбежно)

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

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

В платформе 1С для этих целей существует мощный встроенный инструмент — процедура ЗаполнитьЗначенияСвойств(). Она автоматически сопоставляет имена реквизитов источника и приемника и переносит значения только по совпадающим идентификаторам полей.

Рассмотрим пример правильного кода, написанного в модуле управляемой формы справочника УчебнаяДеятельностьКурсанта:


&НаКлиенте
Процедура ВоеннослужащийПриИзменении(Элемент)
    // Передаем управление на сервер для безопасной работы с базой данных
    ЗаполнитьРеквизитыНаСервере();
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьРеквизитыНаСервере()
    Если ЗначениеЗаполнено(Объект.Военнослужащий) Тогда
        // Автоматически копируем Фамилию, Имя, Отчество, Группу, Звание, Должность
        ЗаполнитьЗначенияСвойств(Объект, Объект.Военнослужащий);
    Иначе
        // Очищаем реквизиты формы, если пользователь стер значение в поле "Военнослужащий"
        Объект.Фамилия = "";
        Объект.Имя = "";
        Объект.Отчество = "";
        Объект.Группа = "";
        Объект.Звание = "";
        Объект.Должность = "";
    КонецЕсли;
КонецПроцедуры

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

Способ 3. Использование механизма подчинения справочников («Владелец»)

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

Для этого выполним следующие действия:

  1. В конфигураторе откроем свойства справочника УчебнаяДеятельностьКурсанта.
  2. Перейдем на вкладку «Владельцы».
  3. В списке «Доступные владельцы» установим галочку напротив справочника Военнослужащие.

В результате этих действий в справочнике учебной деятельности автоматически появится стандартный реквизит Владелец. Это дает мощные преимущества:

Решение частой ошибки новичков: «Наименование не заполнено»

При настройке связи справочников начинающие разработчики часто сталкиваются с ошибкой платформы при попытке записи элемента: «Поле "Наименование" не заполнено!». Это происходит потому, что разработчик пытается переопределить стандартное поле наименования на форме под нужды вывода ФИО военнослужащего, меняя его свойство «ПутьКДанным».

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

Вариант А (Если текстовое наименование не нужно в учете):

В конфигураторе перейдите в свойства справочника УчебнаяДеятельностьКурсанта на вкладку «Данные» и установите параметр «Длина наименования» в значение 0. Платформа перестанет требовать заполнение этого поля, а представление элемента в интерфейсе программы будет формироваться автоматически по ссылке на владельца или ключевой реквизит.

Вариант Б (Автоматическое формирование наименования при записи):

Если вам все же нужно информативное наименование для списков и отчетов, скройте поле ввода наименования с формы элемента и перенесите логику его заполнения в программный модуль. Откройте Модуль объекта справочника УчебнаяДеятельностьКурсанта и пропишите обработчик события:


Процедура ПередЗаписью(Отказ)
    // Предотвращаем запись пустого или некорректного наименования
    Если ЗначениеЗаполнено(Военнослужащий) Тогда
        Наименование = Строка(Военнослужащий) + " - Учебная деятельность";
    Иначе
        Наименование = "Новая запись учебной деятельности";
    EndIf;
КонецПроцедуры

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

Регистр сведений как лучшая альтернатива справочнику

Проанализируем природу данных. Учебная деятельность курсанта (оценки, посещаемость, прохождение зачетов) — это не классический справочник сущностей, а поток событий, распределенных во времени. Использование справочников для хранения таких записей в 1С является устаревшей методикой (Legacy).

Правильный подход — создание Регистра сведений:

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

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

← На главную