При программном создании и заполнении документов в 1С:Бухгалтерии 3.0 часто возникает проблема, когда автоматически вычисляемые поля табличных частей, такие как
Сумма
СчетаУчета
СчетаУчетаНДС
Прежде чем мы перейдем к конкретным решениям, давайте уясним несколько ключевых моментов. Конфигурация "Бухгалтерия предприятия 3.0" активно использует управляемые формы и разветвленную архитектуру общих модулей для реализации бизнес-логики. Многие расчеты и заполнения, которые пользователь видит "автоматически", на самом деле происходят в специальных процедурах и функциях, расположенных как на клиенте (в модулях форм), так и на сервере (в общих модулях).
При программном создании документа мы работаем напрямую с объектом документа на сервере. Это означает, что клиентские обработчики событий формы, такие как
ПриИзменении
Номенклатура
Количество
СчетаУчета)Одной из наиболее частых проблем является незаполнение счетов учета в табличных частях документов. Это критически важно для корректного бухгалтерского учета. К счастью, в БП 3.0 существует мощный и универсальный механизм для этого, реализованный в общем модуле
СчетаУчетаВДокументах
Мы будем использовать экспортные процедуры этого общего модуля, чтобы инициировать заполнение счетов учета для нашего программно созданного документа. Модуль
СчетаУчетаВДокументах
Наиболее подходящей процедурой для наших целей будет
СчетаУчетаВДокументах.Заполнить(Объект, Отбор)
Рассмотрим по шагам, как это сделать:
СчетаУчетаВДокументах.Заполнить()
Вот пример серверного кода, демонстрирующий этот подход:
// Предположим, у нас есть ссылка на документ или мы только что создали новый объект
ДокОбъект = СсылкаНаДокумент.ПолучитьОбъект();
// --- Здесь должен быть ваш код по заполнению табличной части документа. ---
// Например, добавление строк и заполнение Номенклатуры, Количества, Цены и т.д.
//
// Пример: Добавляем строку в табличную часть "Товары"
НоваяСтрока = ДокОбъект.Товары.Добавить();
НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию("ПримерНоменклатуры");
НоваяСтрока.Количество = 10;
НоваяСтрока.Цена = 100;
НоваяСтрока.СтавкаНДС = Перечисления.СтавкиНДС.НДС20; // Обязательно для корректного расчета НДС
// --- Конец примера заполнения табличной части ---
// Создаем структуру отбора, чтобы заполнить счета только там, где они не указаны.
// Это полезно, если документ уже частично заполнен.
Отбор = Новый Структура;
Отбор.Вставить("НеЗаполненныеРеквизиты", Истина); // Заполнять только незаполненные счета
// Можно также указать конкретные табличные части, если это необходимо
// Отбор.Вставить("ИмяТабличнойЧасти", "Товары");
// Вызываем универсальную процедуру для заполнения счетов учета.
// Эта процедура анализирует тип документа, хозяйственную операцию и заполняет
// соответствующие счета (СчетУчета, СчетУчетаНДС, СчетДоходов, СчетРасходов и т.д.)
СчетаУчетаВДокументах.Заполнить(ДокОбъект, Отбор);
// После заполнения счетов обязательно записываем измененный документ.
// Если документ должен сразу быть проведенным, указываем РежимЗаписиДокумента.Проведение.
// Это также может вызвать дополнительные проверки и расчеты, специфичные для проведения.
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);
Также важно отметить, что в модуле
СчетаУчетаВДокументах
ЗаполнитьРеквизитыПриИзменении()
ЗаполнитьПередЗаписью()
Заполнить()
Использование этого общего модуля является предпочтительным и наиболее правильным подходом, поскольку он гарантирует, что мы используем штатный механизм конфигурации. Это значительно снижает риск ошибок и обеспечивает совместимость с будущими обновлениями конфигурации, так как логика определения счетов централизована и поддерживается разработчиками 1С.
Сумма, НДС)Пересчет сумм, НДС, итогов по документу и других зависимых полей — вторая распространенная проблема. Эти поля часто рассчитываются динамически на основе
Количества
Цены
СтавкиНДС
Здесь мы можем выделить два основных сценария работы, в зависимости от того, работаем ли мы с открытой формой документа (клиентский код) или полностью на сервере (фоновая обработка, регламентное задание):
Если ваша обработка работает с уже открытой формой документа, и вы программно изменяете данные в ее табличной части, то для имитации пользовательского ввода и запуска всех зависимых расчетов мы можем использовать общий модуль
ОбработкаТабличнойЧастиКлиент
Метод
ОбработкаТабличнойЧастиКлиент.ОбработатьСтрокуТЧ(ТекДанные, СтруктураДействий, ДополнительныеПараметры)
Разберем, как мы можем его применить:
СтруктураДействий
ОбработатьСтрокуТЧ
Вот пример клиентского кода для использования этого механизма:
// Предположим, мы находимся в модуле формы документа и программно изменили строку
// В этом примере, Элементы.Товары - это элемент формы (таблица)
// Мы хотим пересчитать текущую строку, в которой изменили, например, количество или цену
// Получаем текущие данные строки табличной части.
// Если строка только что добавлена или изменена, необходимо получить к ней доступ.
// Например, если мы добавили новую строку:
// НоваяСтрокаТЧ = Элементы.Товары.ТекущиеДанные;
// или перебираем строки:
// Для Каждого СтрокаТЧ Из Элементы.Товары.ДоступныеПоля Тогда ... КонецДля;
// В данном примере будем считать, что СтрокаТабличнойЧасти это данные строки,
// которая была изменена и требует пересчета.
// Допустим, мы изменили какие-то поля в "СтрокаТабличнойЧасти"
// СтрокаТабличнойЧасти.Количество = 5;
// СтрокаТабличнойЧасти.Цена = 250;
// Создаем и настраиваем структуру действий, которые нужно выполнить.
// Эти параметры зависят от конкретной логики пересчета в документе.
// Чаще всего это РасчитатьСумму, РасчитатьСуммуНДС и т.п.
СтруктураДействий = Новый Структура;
СтруктураДействий.Вставить("РассчитатьСумму", Истина); // Пересчитать сумму по строке
СтруктураДействий.Вставить("РассчитатьСуммуНДС", Истина); // Пересчитать сумму НДС по строке
СтруктураДействий.Вставить("РассчитатьСуммуВсего", Истина); // Возможно, общую сумму строки
СтруктураДействий.Вставить("ПересчитатьИтоги", Истина); // Общие итоги по документу, если необходимо
// Вызываем обработчик для текущей строки.
// ТекДанные - это данные строки табличной части (тип ДанныеФормыЭлементКоллекции).
// Неопределено - для ДополнительныеПараметры, если они не требуются.
ОбработкаТабличнойЧастиКлиент.ОбработатьСтрокуТЧ(СтрокаТабличнойЧасти, СтруктураДействий, Неопределено);
// После выполнения этих действий форма должна обновить данные и пересчитать итоги.
Важно понимать, что параметры
СтруктураДействий
ПриИзменении
Количество
Цена
Номенклатура
ОбработатьСтрокуТЧ
Когда мы работаем полностью на сервере (например, в фоновой обработке, регламентном задании или из модуля менеджера объекта), клиентские модули и элементы формы нам недоступны. В этом случае подходы к пересчету сумм будут иными:
Сумма = Количество * Цена
Количества
Цены
// ... в цикле обхода строк табличной части ...
НоваяСтрока = ДокОбъект.Товары.Добавить();
НоваяСтрока.Номенклатура = Выборка.Номенклатура;
НоваяСтрока.Количество = Выборка.Количество;
НоваяСтрока.Цена = Выборка.Цена;
НоваяСтрока.СтавкаНДС = Перечисления.СтавкиНДС.НДС20; // Не забываем про ставку НДС
// Прямой расчет суммы
НоваяСтрока.Сумма = НоваяСтрока.Количество * НоваяСтрока.Цена;
// Для НДС тоже может быть прямой расчет, если логика простая,
// например, если НДС = Сумма * СтавкаНДС / 100
Если НоваяСтрока.СтавкаНДС = Перечисления.СтавкиНДС.НДС20 Тогда
НоваяСтрока.СуммаНДС = Окр(НоваяСтрока.Сумма * 20 / 120, 2); // Пример для НДС "в том числе"
ИначеЕсли НоваяСтрока.СтавкаНДС = Перечисления.СтавкиНДС.БезНДС Тогда
НоваяСтрока.СуммаНДС = 0;
КонецЕсли;
// ... далее заполнение других полей и вызов СчетаУчетаВДокументах.Заполнить() ...
Мы проанализируем модуль формы документа (например,
МодульОбъекта
МодульМенеджера
Документы.РеализацияТоваровУслуг.РассчитатьСуммы
Например, для пересчета НДС в реализации может существовать серверная функция, которую вызывают из формы. Ваша задача — найти ее, изучить ее параметры и вызвать в своем серверном коде, передав объект документа и текущую строку табличной части.
Процесс поиска выглядит так:
ПриИзменении
Количество
Цена
СтавкаНДС
&НаСервере
&НаСервереБезКонтекста
Этот подход требует более глубокого изучения типового кода, но гарантирует, что мы используем ту же логику, что и 1С, что очень важно для поддержания целостности данных.
В некоторых случаях, помимо заполнения отдельных строк и полей, документы могут иметь более высокоуровневые механизмы заполнения. Например, у многих документов существует экспортная процедура
Заполнить()
Хотя эта процедура не всегда решает проблему "автоматического" заполнения после прямого добавления строк, ее изучение может выявить вспомогательные методы, которые значительно упрощают задачу. Например, она может содержать вызовы к общим процедурам, которые как раз и выполняют пересчет сумм или заполнение счетов учета для всего документа.
Мы рекомендуем всегда анализировать модуль объекта и модуль менеджера документа на предмет наличия таких экспортных процедур. Возможно, они уже выполняют часть необходимой работы.
В заключение, программное заполнение табличных частей документов в 1С:Бухгалтерии 3.0 требует не простого добавления данных, но и понимания и вызова типовых механизмов конфигурации. Мы рассмотрели основные подходы: использование общего модуля
СчетаУчетаВДокументах
ОбработкаТабличнойЧастиКлиент.ОбработатьСтрокуТЧ