Как узнать, какой реквизит объекта или формы был модифицирован в 1С?

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

В процессе разработки конфигураций на платформе 1С:Предприятие часто возникает ситуация, когда после выполнения определенного кода или пользовательского действия объект (или форма) получает признак модифицированности. Быстро определить, изменение какого именно реквизита привело к установке данного флага, — важная задача при поиске багов и оптимизации алгоритмов. Разберем доступные методы решения этой задачи: от пошаговой отладки до программных способов сравнения состояний объекта.

1. Быстрый поиск причины через отладчик платформы

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

  1. Откроем модуль, в котором выполняется подозреваемая процедура, и установим точку останова в самом начале алгоритма.
  2. Запустим конфигурацию в режиме отладки и вызовем исполнение процедуры.
  3. В окне Табло (или Выражения) добавим отслеживание свойства модифицированности формы: ЭтаФорма.Модифицированность или Модифицированность.
  4. Выполняем код пошагово (клавиша F10), обращая внимание на панель информации отладчика. Как только флаг Модифицированность изменит значение с Ложь на Истина, текущая выполнившаяся строка и будет являться причиной изменения данных.

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

2. Программное сравнение данных объекта с базой данных (через Ссылку)

Если объект уже существует в базе данных (имеет зафиксированную ссылку Объект.Ссылка), мы можем сравнить текущие значения реквизитов объекта в памяти со значениями, сохраненными в базе данных.

Рассмотрим вариант универсального обхода через метаданные объекта. Чтобы проверка была полной, проанализируем три категории данных: реквизиты, стандартные реквизиты и табличные части.


Функция ПолучитьСписокИзмененныхРеквизитов(Объект1С) Экспорт
    
    Перем ИзмененныеРеквизиты;
    ИзмененныеРеквизиты = Новый Массив;
    
    Если Не ЗначениеЗаполнено(Объект1С.Ссылка) Тогда
        Возврат ИзмененныеРеквизиты; // Новый объект, в БД данных нет
    КонецЕсли;
    
    МетаданныеОбъекта = Объект1С.Метаданные();
    
    // 1. Проверяем обычные реквизиты
    Для Каждого РеквизитИзМетаданных Из МетаданныеОбъекта.Реквизиты Цикл
        ИмяРеквизита = РеквизитИзМетаданных.Имя;
        Если Объект1С[ИмяРеквизита] <> Объект1С.Ссылка[ИмяРеквизита] Тогда
            ИзмененныеРеквизиты.Добавить(ИмяРеквизита);
        КонецЕсли;
    КонецЦикла;
    
    // 2. Проверяем стандартные реквизиты (Наименование, Код, Проведен и т.д.)
    Для Каждого СтандартныйРеквизит Из МетаданныеОбъекта.СтандартныеРеквизиты Цикл
        ИмяРеквизита = СтандартныйРеквизит.Имя;
        Попытка
            Если Объект1С[ИмяРеквизита] <> Объект1С.Ссылка[ИмяРеквизита] Тогда
                ИзмененныеРеквизиты.Добавить(ИмяРеквизита);
            КонецЕсли;
        Исключение
            // Некоторые стандартные реквизиты могут быть недоступны для прямого чтения
        КонецПопытки;
    КонецЦикла;
    
    Возврат ИзмененныеРеквизиты;

КонецФункции

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

3. Сравнение состояний через JSON-сериализацию

В случаях, когда объект еще не записан в базу данных (новый объект) или требуется зафиксировать срез состояний до и после выполнения конкретной процедуры на клиенте/сервере, применяется метод сериализации в формат JSON.

Разберем данный алгоритм по шагам:

  1. Перед выполнением алгоритма сериализуем объект или структуру его реквизитов в JSON-строку.
  2. Выполняем исследуемую процедуру.
  3. Сериализуем объект повторно во вторую JSON-строку.
  4. Сравниваем две строки или разбираем их обратно в соответствия и находим различающиеся ключи.

// Фиксация состояния ДО
ЗаписьJSON1 = Новый ЗаписьJSON;
ЗаписьJSON1.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON1, Объект);
СтрокаДо = ЗаписьJSON1.Закрыть();

// Выполнение исследуемого кода
ИзменитьДанныеОбъекта(Объект);

// Фиксация состояния ПОСЛЕ
ЗаписьJSON2 = Новый ЗаписьJSON;
ЗаписьJSON2.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON2, Объект);
СтрокаПосле = ЗаписьJSON2.Закрыть();

Если СтрокаДо <> СтрокаПосле Тогда
    Сообщить("Данные объекта были изменены!");
КонецЕсли;

4. Разграничение: Модифицированность формы и изменение данных

Важно понимать разницу между интерактивной модифицированностью формы и фактическим изменением данных объекта:

Чтобы отслеживать изменения на клиенте без постоянных вызовов сервера, разработчики сохраняют начальное состояние реквизитов формы в структуру при открытии (в обработчике ПриОткрытии) и сравнивают значения при необходимости или в обработчиках событий ПриИзменении элементов формы.

5. Встроенные платформенные механизмы и БСП

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

← На главную