Как программно изменить реквизит типа Булево в справочнике 1С и сохранить изменения?

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

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

Базовый алгоритм изменения реквизита

Для того чтобы изменить любое значение в базе данных программно, нам необходимо придерживаться стандартного цикла работы с объектами. Рассмотрим ситуацию, когда у нас уже есть выборка элементов справочника или конкретная ссылка. Разберем по шагам, как происходит инверсия значения реквизита (переключение с Истина на Ложь и наоборот).

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


Пока Выборка.Следующий() Цикл
    // 1. Получаем объект из ссылки для возможности редактирования
    ОбъектСправочника = Выборка.Ссылка.ПолучитьОбъект(); 
    
    // 2. Меняем значение булевского реквизита на противоположное
    ОбъектСправочника.ИспользоватьВПечати = Не ОбъектСправочника.ИспользоватьВПечати;
    
    // 3. Записываем изменения в базу данных
    ОбъектСправочника.Записать();
КонецЦикла;

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

Оптимизация производительности: использование транзакций

Если нам необходимо обработать большое количество записей (например, несколько тысяч элементов справочника Номенклатура), выполнение кода из примера выше может занять значительное время. Это происходит потому, что каждый метод Записать() инициирует отдельную транзакцию в СУБД, что влечет за собой серьезные накладные расходы на блокировки и запись логов транзакций.

Посмотрим, как можно ускорить процесс, объединив все операции в одну общую транзакцию. Рассмотрим оптимизированный вариант:


НачатьТранзакцию();
Попытка
    Пока Выборка.Следующий() Цикл
        ОбъектСправочника = Выборка.Ссылка.ПолучитьОбъект();
        ОбъектСправочника.Активен = Истина; // Явное присвоение значения
        ОбъектСправочника.Записать();
    КонецЦикла;
    
    ЗафиксироватьТранзакцию();
    Сообщить("Данные успешно обновлены.");
Исключение
    ОтменитьТранзакцию();
    Сообщить("Произошла ошибка при записи: " + ОписаниеОшибки());
КонецПопытки;

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

Использование режима обмена данными (DataExchange)

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

Разберем пример с подавлением проверок:


Объект = СсылкаНаЭлемент.ПолучитьОбъект();
Объект.НуженТендер = Ложь;

// Устанавливаем режим загрузки, чтобы пропустить прикладные проверки модуля
Объект.ОбменДанными.Загрузка = Истина;

Попытка
    Объект.Записать();
Исключение
    Инфо = ИнформацияОбОшибке();
    Сообщить("Не удалось записать объект: " + Инфо.Описание);
КонецПопытки;

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

Обработка блокировок и исключений

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

Для обеспечения надежности мы должны использовать блок Попытка...Исключение. Рассмотрим правильный подход:

  1. Сначала мы пытаемся получить объект и изменить его.
  2. Если объект заблокирован другим сеансом, система выдаст ошибку.
  3. Мы перехватываем ошибку и выводим пользователю понятное сообщение вместо аварийного завершения программы.

Пример кода с контролем блокировки:


Объект = Ссылка.ПолучитьОбъект();
Если Объект = Неопределено Тогда
    Сообщить("Объект был удален или недоступен.");
    Возврат;
КонецЕсли;

Попытка
    // Попробуем заблокировать объект перед записью
    Объект.Заблокировать();
    Объект.ФлагОбработки = Истина;
    Объект.Записать();
Исключение
    Сообщить("Не удалось изменить элемент: " + Ссылка + ". Возможно, он занят другим пользователем.");
КонецПопытки;

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

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

Пошагово это выглядит так:

  1. Откройте раздел Администрирование — Обслуживание — Корректировка данных.
  2. Выберите обработку Групповое изменение реквизитов.
  3. Выберите нужный справочник и настройте фильтр (отбор) элементов.
  4. Найдите ваш реквизит типа Булево и установите новое значение (флажок).
  5. Нажмите кнопку «Изменить реквизиты».

Этот способ безопаснее для администраторов и пользователей, так как он использует стандартные механизмы Библиотеки Стандартных Подсистем (БСП).

Влияние на итоги и регистры

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

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

Резюме

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

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

← На главную