Почему не записываются или не видны данные в регистре сведений при проведении документа?

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

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

Причина 1. Транзакционная изоляция данных и кэширование динамических списков

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

Рассмотрим подробнее, как это влияет на видимость записей:

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

Причина 2. Ошибки проектирования кода работы с Набором записей

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


Если НовыйНаборЗаписей.Количество() = 0 Тогда
    // Заполнение и добавление новых записей...
КонецЕсли;
Иначе
    НовыйНаборЗаписей.Прочитать();
    НовыйНаборЗаписей.Очистить();
    // Попытка перезаписи...
КонецЕсли;

Разберем по шагам, почему этот код работает не так, как ожидается:

Правильный шаблон программной записи в независимый регистр сведений

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


// 1. Создаем объект набора записей
НовыйНаборЗаписей = РегистрыСведений.ЗначенияПоказателейСхемМотивации.СоздатьНаборЗаписей();

// 2. Устанавливаем жесткий отбор по измерению-ссылке
НовыйНаборЗаписей.Отбор.pzСсылкаТабельПремий.Установить(Ссылка);

// 3. Заполняем набор в цикле по данным табличной части документа
Для Каждого СтрокаТЧ Из ТабельСотрудников Цикл 
    
    // Метод Добавить() создает новую строку в наборе записей
    НоваяЗапись = НовыйНаборЗаписей.Добавить();
    
    // Заполняем ключевые измерения и ресурсы
    НоваяЗапись.ПериодДействия = Дата;
    НоваяЗапись.Организация = Организация;
    НоваяЗапись.Подразделение = Подразделение;
    НоваяЗапись.Показатель = Показатель;
    
    // Поле отбора заполняется автоматически, но для надежности укажем его явно
    НоваяЗапись.pzСсылкаТабельПремий = Ссылка;
    
    // Расчет числового показателя
    Колво = 0;
    Для Сч = 1 По 31 Цикл
        Если СтрокаТЧ["Начислить" + Строка(Сч)] = Истина Тогда
            Колво = Колво + 1;
        КонецЕсли;
    КонецЦикла;
    
    НоваяЗапись.Сотрудник = СтрокаТЧ.Сотрудник;
    НоваяЗапись.Значение = Колво;
    
КонецЦикла;

// 4. Записываем весь набор с замещением (старые записи по этому документу затрутся)
НовыйНаборЗаписей.Записать(Истина);

Скрытая угроза: проблема «битых» ссылок в независимых регистрах

Если вы проектируете архитектуру базы данных и решили использовать независимый регистр сведений для хранения данных, связанных с документами (например, через измерение типа ДокументСсылка.ТабельУчетаРабочегоВремени), вы сталкиваетесь с серьезным архитектурным риском.

Поскольку регистр является независимым, платформа 1С на системном уровне не отслеживает связи между ним и документами-регистраторами. Это порождает следующие проблемы:

Как решить проблему «битых» ссылок?

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

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

Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    // Если документ помечается на удаление или распроводится - очищаем записи в РС
    Если ПометкаУдаления Или РежимЗаписи = РежимЗаписиДокумента.ОтменаПроведения Тогда
        НаборЗаписей = РегистрыСведений.ЗначенияПоказателейСхемМотивации.СоздатьНаборЗаписей();
        НаборЗаписей.Отбор.pzСсылкаТабельПремий.Установить(Ссылка);
        
        // Записываем пустой набор, тем самым удаляя старые записи из базы
        НаборЗаписей.Записать(Истина);
    КонецЕсли;
    
КонецПроцедуры

Процедура ПередУдалением(Отказ)
    
    // При физическом удалении документа обязательно очищаем записи в РС
    НаборЗаписей = РегистрыСведений.ЗначенияПоказателейСхемМотивации.СоздатьНаборЗаписей();
    НаборЗаписей.Отбор.pzСсылкаТабельПремий.Установить(Ссылка);
    НаборЗаписей.Записать(Истина);
    
КонецПроцедуры

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

← На главную