Как программно перезаполнить цены в документах Реализация товаров и услуг в 1С:Бухгалтерия 2.0

Программист 1С v8.3 (Обычные формы) 1C:Бухгалтерия
← На главную

При автоматизации работы в 1С:Бухгалтерия предприятия 2.0 (БП 2.0) часто возникает задача массового обновления данных в уже созданных документах. Одной из наиболее востребованных операций является перезаполнение цен в документах РеализацияТоваровУслуг за определенный период (например, при изменении прайс-листа или исправлении ошибок ввода). Разберем по шагам, как правильно реализовать эту задачу с помощью внешней обработки, и проанализируем типичные ошибки, с которыми сталкиваются разработчики.

Разбор основной проблемы: Ссылка против Объекта

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

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

Для внесения изменений необходимо получить Объект документа. Рассмотрим, как это выглядит в коде:


// ОШИБОЧНЫЙ ПУТЬ
Выборка = Документы.РеализацияТоваровУслуг.Выбрать(ДатаНач, ДатаКон);
Пока Выборка.Следующий() Цикл
    // Выборка.Ссылка.Товары[0].Цена = 100; // Ошибка: Поле недоступно для записи!
КонецЦикла;

// ПРАВИЛЬНЫЙ ПУТЬ
Выборка = Документы.РеализацияТоваровУслуг.Выбрать(ДатаНач, ДатаКон);
Пока Выборка.Следующий() Цикл
    ДокОбъект = Выборка.ПолучитьОбъект(); // Получаем объект для редактирования
    // Теперь можно менять данные
    // ...
    ДокОбъект.Записать(РежимЗаписиДокумента.Запись); 
КонецЦикла;

Использование типовых механизмов ценообразования

В конфигурации БП 2.0 логика работы с ценами и налогами сосредоточена в специализированных общих модулях. Вместо того чтобы вручную копировать код из модулей формы документа (например, из процедуры ТоварыНоменклатураПриИзменении), правильнее и эффективнее использовать экспортные процедуры общих модулей. Это гарантирует, что все связанные расчеты (НДС, суммы, скидки) будут выполнены корректно согласно учетной политике.

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

  1. Ценообразование.ПолучитьЦенуНоменклатуры() — позволяет получить актуальную цену из регистров сведений на определенную дату с учетом типа цен, валюты и единицы измерения.
  2. ОбработкаТабличныхЧастей.ЗаполнитьЕдиницуЦенуПродажиТабЧасти() — заполняет цену и единицу измерения в строке табличной части.
  3. ОбработкаТабличныхЧастей.РассчитатьСуммуТабЧасти() — пересчитывает сумму строки (Количество * Цена).
  4. ОбработкаТабличныхЧастей.РассчитатьСуммуНДСТабЧасти() — рассчитывает налог исходя из суммы и настроек документа (НДС сверху или в сумме).

Алгоритм реализации внешней обработки

Рассмотрим подробнее процесс написания кода для циклического обновления цен. Нам необходимо не просто заменить число в колонке Цена, но и обеспечить целостность данных документа.

Шаг 1. Получение объекта документа. Как мы уже выяснили, работаем только через ПолучитьОбъект().

Шаг 2. Обход табличной части. Проходим циклом по строкам табличной части Товары.

Шаг 3. Получение новой цены. Используем функцию общего модуля, чтобы система сама нашла цену в зависимости от ТипЦен, указанного в шапке документа.

Шаг 4. Пересчет суммовых показателей. После изменения цены обязательно вызываем пересчет суммы и НДС. Если этого не сделать, в печатных формах и проводках останутся старые значения, хотя цена в строке будет новой.

Пример реализации логики:


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

Важные нюансы и меры предосторожности

При выполнении подобных массовых операций следует учитывать несколько критически важных моментов:

  1. Архивная копия. Перед запуском обработки, изменяющей данные в проведенных документах, обязательно создайте резервную копию базы данных. Как справедливо замечено в обсуждении, ошибки в логике могут привести к «порче» исторической отчетности.
  2. Закрытые периоды. Если вы изменяете цены в документах прошлого периода, по которому уже сдана декларация по НДС или налогу на прибыль, это приведет к расхождению данных в базе с данными отчетности. Рекомендуется проверять дату документа на предмет попадания в установленную «Дату запрета редактирования».
  3. Валютный учет. Если в документе используется валюта, отличная от валюты типа цен, типовые механизмы должны корректно выполнить пересчет по курсу на дату документа. Проверьте, чтобы в обработке правильно передавались параметры валют.
  4. Перепроведение. Изменение цены в Реализации товаров и услуг напрямую влияет на задолженность контрагента (регистр Хозрасчетный) и выручку. Простого сохранения объекта (Запись) недостаточно — документ должен быть перепроведен для актуализации бухгалтерских проводок.

Заключение

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

← На главную