Как обновить таблицу значений на форме после изменения элемента справочника в 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

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

В чем причина преждевременного обновления таблицы значений?

Проанализируем исходный фрагмент кода, приводящий к некорректной работе:


Элемент = ШК.ПолучитьЗначение(Позиция, "Штрихкод");
ОткрытьФорму(Элемент, Контекст);      

ПолучитьСписокШтрихКодов(); // Процедура перезаполнения таблицы значений

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

Причина поведения платформы: штатная процедура ОткрытьФорму() в 1С 7.7 работает асинхронно (неблокирующе). Она посылает системе команду открыть окно и незамедлительно передает управление следующей строке исходного кода. Поскольку пользователь еще физически не успел изменить и записать данные, процедура обновления считывает из базы старые значения.

Решение 1. Использование модального режима (ОткрытьФормуМодально)

Самый простой и быстрый способ решить проблему — приостановить выполнение программного кода в вызывающей форме до тех пор, пока пользователь не завершит работу с открываемым объектом. Для этого применим метод ОткрытьФормуМодально().

Посмотрим на пример базовой реализации:


Элемент = ШК.ПолучитьЗначение(Позиция, "Штрихкод");
ОткрытьФормуМодально(Элемент);      

ПолучитьСписокШтрихКодов();

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

Однако у простого вызова ОткрытьФормуМодально() есть нюанс: если пользователь просто открыл элемент и нажал «Отмена» (или закрыл крестиком без сохранения), процедура ПолучитьСписокШтрихКодов() все равно выполнит повторное чтение данных из базы вхолостую.

Разберем по шагам, как оптимизировать этот процесс с помощью передачи параметра-флага:

  1. В вызывающей форме объявим переменную-флаг со значением 0 и передадим ее вторым параметром в модальное окно.
  2. В модуле формы редактируемого справочника (в нашем примере — штрихкода) в предопределенной процедуре ПриЗаписи() изменим значение системного свойства Форма.Параметр на 1.
  3. После закрытия формы проверим значение флага: если он равен 1, производим обновление, если равен 0 — пропускаем лишнее чтение базы.

Код кнопки в вызывающей форме:


Элемент = ШК.ПолучитьЗначение(Позиция, "Штрихкод");
ФлагЗаписи = 0;
ОткрытьФормуМодально(Элемент, ФлагЗаписи);      

Если ФлагЗаписи = 1 Тогда
    ПолучитьСписокШтрихКодов();
КонецЕсли;

Код в модуле формы редактируемого элемента справочника:


Процедура ПриЗаписи()
    // Уведомляем вызывающую форму о том, что объект был успешно сохранен
    Форма.Параметр = 1;
КонецПроцедуры

Решение 2. Обновление в немодальном режиме через глобальный модуль

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

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

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

Код в глобальном модуле конфигурации:


Процедура глОбновитьТаблицуШтрихКодов(КонтФормы) Экспорт
    Если ТипЗначенияСтр(КонтФормы) = "ГрупповойКонтекст" Тогда
        // Вызываем штатную логику пересчета или наполнения ТЗ в переданном контексте
        КонтФормы.ПолучитьСписокШтрихКодов();
    КонецЕсли;
КонецПроцедуры

Код вызова в исходной форме (справочник ТМЦ):


Элемент = ШК.ПолучитьЗначение(Позиция, "Штрихкод");
// Передаем собственный групповой контекст в открываемую форму
ОткрытьФорму(Элемент, Контекст);

Код в форме подчиненного элемента справочника (Штрихкод):


Процедура ПриЗаписи()
    // Проверяем, передан ли контекст формы-владельца
    Если ТипЗначенияСтр(Форма.Параметр) = "ГрупповойКонтекст" Тогда
        глОбновитьТаблицуШтрихКодов(Форма.Параметр);
    КонецЕсли;
КонецПроцедуры

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

Использование внешних компонент

Если в вашей конфигурации используются внешние компоненты расширения платформы (такие как 1С++ или FormEx), задачу можно решить еще гибче:

  1. Компоненты позволяют вызывать пользовательские процедуры из контекста одной формы напрямую без добавления процедур в глобальный модуль.
  2. Появляется возможность организовать обмен пользовательскими событиями и сообщениями между окнами, что делает модули независимыми друг от друга.

Для типовых конфигураций без сторонних библиотек наиболее быстрым и надежным остается применение ОткрытьФормуМодально() с проверкой флага записи либо вынос процедуры обновления в глобальный модуль.

← На главную