Почему не отображается измененное значение в элементе справочника ЗиКГУ 3.1 после программной записи?

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

В практике разработки на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда код выполняется без ошибок, данные в базе данных обновляются (что подтверждается консолью запросов), но пользователь в интерфейсе видит старые значения. Особенно остро эта проблема проявляется в сложных конфигурациях, таких как Зарплата и кадры государственного учреждения (ЗиКГУ) 3.1 или Зарплата и управление персоналом (ЗУП) 3.1.

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

Анализ проблемы: почему база «видит» изменения, а форма — нет?

Рассмотрим стандартную ситуацию. Разработчик пишет код для обновления реквизита СтатьяФинансирования в справочнике ШтатноеРасписание:


&НаСервере
Процедура ЗаписатьЗначениеНаСервере()
    // Получаем объект из ссылки
    Док = Объект.ЭлементСправочника.ПолучитьОбъект();
    // Находим нужное значение статьи
    Док.СтатьяФинансирования = Справочники.СтатьиФинансированияЗарплата.НайтиПоКоду("СГ"); 
    // Записываем объект в базу
    Док.Записать();
КонецПроцедуры

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

Причина 1: Дублирование данных в регистрах сведений (Архитектура ЗУП/ЗиКГУ)

В современных конфигурациях по учету кадров справочник ШтатноеРасписание часто является лишь «оболочкой». Если в настройках программы включено ведение истории изменений штатного расписания, основные данные (оклады, надбавки, статьи финансирования) хранятся не только в самом справочнике, но и в периодическом регистре сведений ИсторияИспользованияШтатногоРасписания.

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

Причина 2: Использование механизма ОбменДанными.Загрузка

Иногда программисты пытаются обойти проверки в модуле объекта, устанавливая флаг ОбменДанными.Загрузка = Истина. Рассмотрим пример:


Док = Объект.ЭлементСправочника.ПолучитьОбъект();
Док.ОбменДанными.Загрузка = Истина;
Док.СтатьяФинансирования = Справочники.СтатьиФинансированияЗарплата.НайтиПоКоду("СГ");
Док.Записать();

Важный момент: установка этого флага отключает большинство обработчиков событий ПередЗаписью и ПриЗаписи. Если в этих обработчиках прописана синхронизация данных справочника с теми самыми регистрами сведений, то при Загрузка = Истина синхронизация не произойдет. База данных окажется в рассогласованном состоянии: в справочнике одно значение, в регистре — другое.

Причина 3: Кэширование представлений и данных на платформе 8.3.22

Особое внимание стоит уделить версии платформы. В ветке 8.3.22 (например, релиз 1923) были зафиксированы ошибки, связанные с некорректным обновлением кэша представлений объектов на стороне клиента. Платформа кэширует текстовое представление ссылок и значения некоторых полей для ускорения работы интерфейса.

Если данные изменены программно на сервере, клиентское приложение может не узнать об этом и продолжать показывать старое значение из своего локального кэша. В этом случае даже интерактивное нажатие кнопки «Перечитать» может не дать эффекта, если платформа считает кэш актуальным.

Решение проблемы по шагам

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

Шаг 1. Обеспечение согласованности данных

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

Шаг 2. Оповещение системы об изменениях

Чтобы клиентские формы «узнали», что данные в базе изменились, необходимо использовать метод ОповеститьОбИзменении. Это заставляет платформу сбросить кэш для конкретной ссылки.


&НаКлиенте
Процедура ЗаписатьИОбновить()
    ЗаписатьЗначениеНаСервере();
    // Оповещаем все открытые формы о том, что объект изменился
    ОповеститьОбИзменении(Объект.ЭлементСправочника);
КонецПроцедуры

Шаг 3. Использование метода Прочитать() в форме

Если форма элемента уже открыта, и вы программно меняете данные «под ней» (например, из другой обработки), в самой форме полезно вызвать метод Прочитать(). Он принудительно перечитывает данные объекта из базы данных, минуя кэш.


// В контексте формы элемента
ЭтаФорма.Прочитать();

Шаг 4. Обновление платформы

Как показала практика решения подобных проблем на форумах, переход с проблемных релизов (типа 8.3.22.1923) на более стабильные (например, 8.3.23 и выше) часто устраняет странности с отображением данных. В новых версиях исправлены механизмы инвалидации кэша, что позволяет методу Прочитать() и команде «Перечитать» работать корректно в 100% случаев.

Резюме

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

  1. Проверка регистров: Не перекрываются ли данные справочника данными из регистров сведений в процедурах ПриЧтенииНаСервере или ПриСозданииНаСервере.
  2. Проверка кэша: Использовать ОповеститьОбИзменении() на клиенте после записи на сервере.
  3. Проверка платформы: Если поведение системы выглядит нелогичным (данные в базе есть, а Прочитать() не помогает), стоит рассмотреть вопрос обновления платформы до актуального релиза.

Соблюдение этих правил поможет избежать «мистических» ошибок при программном управлении данными в сложных корпоративных системах на базе 1С.

← На главную