Как программно установить значение периодического реквизита справочника в 1С 7.7?

Программист 1С v7.7 Налоговый учет
← На главную

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

Способ 1. Установка значения через объект справочника и метод ИспользоватьДату

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


ИзменямСправочник = СоздатьОбъект("Справочник.Номенклатура");
// Устанавливаем дату, на которую будет записано новое значение
ИзменямСправочник.ИспользоватьДату(ТекущаяДата(), 1); 
ИзменямСправочник.ВыбратьЭлементы();

Пока ИзменямСправочник.ПолучитьЭлемент() = 1 Цикл
    // Проверяем, не является ли элемент группой (папкой)
    Если ИзменямСправочник.ЭтоГруппа() = 1 Тогда
        Продолжить;
    КонецЕсли;

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

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

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

Способ 2. Использование метода Установить

Если нам не нужно менять весь объект справочника, а требуется только записать значение конкретного периодического реквизита на определенную дату, можно воспользоваться методом Установить(). Это более лаконичный способ, который работает напрямую с реквизитом.

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


Спр = СоздатьОбъект("Справочник.Номенклатура");
Спр.ВыбратьЭлементы();
Пока Спр.ПолучитьЭлемент() = 1 Цикл
    Если Спр.ЭтоГруппа() = 0 Тогда
        // Устанавливаем ставку НДС на начало 2019 года
        Спр.СтавкаНДС.Установить('01.01.2019', Перечисление.СтавкиНДС.СтавкаНДС20);
        // В этом случае метод Записать() для справочника вызывать НЕ НУЖНО
    КонецЕсли;
КонецЦикла;

Этот метод удобен тем, что он автоматически создает запись в истории значений на указанную дату. Если запись на эту дату уже существовала, она будет перезаписана новым значением.

Способ 3. Работа через специализированный объект Периодический

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

Проанализируем алгоритм работы с этим объектом:

  1. Создаем объект Периодический.
  2. Связываем его с конкретным реквизитом конкретного элемента справочника методом ИспользоватьОбъект.
  3. Устанавливаем дату и значение через соответствующие атрибуты объекта.
  4. Вызываем метод Записать() самого объекта Периодический.

Посмотрим на пример кода:


Спр = СоздатьОбъект("Справочник.Номенклатура");
ОбъектПериод = СоздатьОбъект("Периодический");

Спр.ВыбратьЭлементы();
Пока Спр.ПолучитьЭлемент() = 1 Цикл
    Если Спр.ЭтоГруппа() = 1 Тогда
        Продолжить;
    КонецЕсли;
    
    // Связываем объект с реквизитом "СтавкаНДС" текущего товара
    ОбъектПериод.ИспользоватьОбъект("СтавкаНДС", Спр.ТекущийЭлемент());
    
    // Задаем параметры новой записи истории
    ОбъектПериод.ДатаЗнач = '01.01.2019';
    ОбъектПериод.Значение = Перечисление.СтавкиНДС.СтавкаНДС20;
    
    // Записываем только значение реквизита, не трогая карточку товара
    ОбъектПериод.Записать();
КонецЦикла;

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

Важные рекомендации при массовом изменении данных

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

  1. Используйте транзакции. При циклическом изменении справочников в 1С 7.7 (особенно в сетевых версиях или на SQL) скорость работы может быть крайне низкой. Оберните ваш цикл в транзакцию — это ускорит процесс в десятки раз:
    
    НачатьТранзакцию();
    // Ваш цикл изменения справочника
    ЗафиксироватьТранзакцию();
    
  2. Проверка на группы. Всегда проверяйте ЭтоГруппа(). Попытка записать значение в периодический реквизит группы справочника может привести к ошибке исполнения, если для групп этот реквизит не предусмотрен метаданными.
  3. Контроль даты. Будьте внимательны с ТекущаяДата(). Если вы запускаете обработку по переходу на новую ставку НДС заранее (например, 25 декабря), а ставка должна начать действовать с 1 января, обязательно указывайте жесткую дату '01.01.2019', иначе история заполнится некорректно.
  4. Диагностика. Перед запуском на всей базе выполните код для одного-двух элементов и проверьте результат в карточке товара, нажав кнопку «История» рядом с нужным реквизитом. Убедитесь, что там появилась новая строка с правильной датой и значением.

Таким образом, мы рассмотрели три способа управления историей значений. Для простых разовых правок подойдет метод Установить, а для серьезных автоматизаций и массовых обновлений рекомендуем использовать объект Периодический в связке с транзакциями.

← На главную