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