Автоматический пересчет суммы в строках документа

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

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

Дело в том, что до сих пор мы использовали предопределенные формы объектов, которые система «1С:Предприятие» по умолчанию создавала для нас сама. Теперь же у нас возникла необходимость слегка изменить логику работы формы документа, поэтому нам нужно создать свою собственную форму документа ПриходнаяНакладная для того, чтобы в ней с помощью встроенного языка описать тот алгоритм, который нам нужен. И система будет использовать нашу форму вместо формы по умолчанию.

В режиме «Конфигуратор»

Форма документа

Вернемся в конфигуратор и откроем окно редактирования объекта конфигурации Документ ПриходнаяНакладная.

В этом окне нас интересует закладка Формы.

Как мы видим, ни одна из основных форм документа пока не задана. Для того чтобы создать форму документа, нажмем кнопку открытия со значком лупы в поле ввода или кнопку Добавить над списком форм (рис. ).

Система вызовет еще один полезный инструмент разработчика – конструктор формы.

Этот инструмент также построен по принципу «мастеров»: ввод данных в определенной последовательности и передвижение кнопками Далее и Назад.

Выберем тип формы Форма документа и нажмем кнопку Готово, согласившись тем самым со всем, что нам предложила система.

Обратите внимание, что в дереве объектов конфигурации у объекта конфигурации Документ ПриходнаяНакладная появилась форма ФормаДокумента , а на экране открылось окно редактора форм, содержащее эту форму.

Редактор форм объединяет несколько окон взаимосвязанных между собой редакторов. Мы не будем здесь разбирать подробно работу с редактором форм, а коснемся только тех моментов, которые нужны для выполнения простейших действий, связанных с нашей задачей.

Пока мы рассмотрим только окно формы документа в режиме просмотра, расположенное внизу, и окно редактора элементов формы, расположенное слева в верхней части окна редактора форм.

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

Элементы формы в верхнем левом окне редактора форм образуют иерархическую структуру, из которой следует, что чем выше в списке находится элемент, тем выше и левее на форме он будет располагаться.

Эта структура редактируется на закладке Элементы и позволяет управлять отображением и редактированием данных в форме.

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

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

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

Но разработчик может через палитру свойств изменить свойства элемента, которые повлияют на его отображение в форме. Он может также изменить структуру элементов формы – создать новое поле, группу полей, добавить табличную часть, связав эти элементы с данными формы.

Но пока нам ничего этого не нужно делать. Нас интересуют три элемента табличной части: МатериалыКоличество, МатериалыЦена и МатериалыСумма (см. рис. 4.20).

Мы хотим, чтобы каждый раз, когда меняется значение в поле Количество или в поле Цена, в поле Сумма автоматически устанавливалось значение, равное произведению значений полей Количество и Цена.

Очевидно, что для этого нужно написать на встроенном языке команду, похожую на Сумма = Количество*Цена, которая будет выполняться при изменении значения поля Количество или Цена. Но как «поймать» эти моменты изменения?

Обработчик события

Как мы уже видели, система сама умеет работать с теми объектами, которые описаны в дереве конфигурации: показывать их данные, добавлять новые элементы и пр. То есть у нее есть некие «стандартные представления» о том, как это все должно работать.

Но, как правило, разработчиков эти «стандартные представления» устраивают только в самых простых случаях. Реальные задачи гораздо разнообразнее. Поэтому у системы существуют события, которые связаны с самыми различными моментами ее «стандартного» функционирования. В том числе события, связанные с функ- ционированием форм и элементов, расположенных в этих формах.

Используя встроенный язык, разработчик может «вклиниться» в эти события и описать собственный алгоритм того, что должно происходить при наступлении этого события. Что мы сейчас и сделаем.

Дважды щелкнем на элементе формы Материалы Количество или правой кнопкой мыши откроем для него палитру свойств (пункт контекстного меню Свойства).

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

Очевидно, что нам нужно событие ПриИзменении, которое возникает после изменения значения поля. Найдем его в списке событий и нажмем кнопку открытия со значком лупы в поле ввода (рис. 4.21).

Система предложит окно для выбора типа обработчика события, который мы хотим создать (рис. 4.22).

Оставим без изменения вариант Создать на клиенте, предложенный по умолчанию.

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

Модуль – это «хранилище» для текста программы на встроенном языке. Модулей существует несколько, и каждый из них предназначен для описания алгоритмов, относящихся к тому или иному моменту работы программы. В данном случае это модуль формы, так как обработчики всех интерактивных событий, связанных с элементами формы, помещаются именно в модуль формы.

В модуль формы, в процедуру МатериалыКоличествоПриИзменении() мы и добавим следующий текст (листинг 1).

Листинг 4.1. Процедура «МатериалыКоличествоПриИзменении()»

СтрокаТабличнойЧасти = Элементы.Материалы.ТекущиеДанные;

СтрокаТабличнойЧасти.Сумма = СтрокаТабличнойЧасти.Количество * СтрокаТабличнойЧасти.Цена;

Объясним назначение этих строк.

В первой строке мы сначала создаем переменную СтрокаТаблич нойЧасти, в которую будет помещен объект, содержащий данные, находящиеся в строке табличной части, которую нам нужно пересчи тать.

Мягкая типизация данных встроенного языка позволяет сделать это, не объявляя переменную и ее тип заранее. Мы создаем переменную прямо по ходу работы, и ее тип определяется типом значения, которое она содержит.

Поскольку мы находимся в модуле формы, то в нем доступны все свойства и методы объекта встроенного языка УправляемаяФорма. Поэтому мы можем обращаться к ним напрямую. В данном случае после знака равенства мы обращаемся к коллекции элементов формы, используя одно из свойств объекта УправляемаяФорма – свойство Элементы.

Коллекция элементов формы является объектом встроенного языка ВсеЭлементыФормы, содержащим все элементы формы. То есть это программный аналог корня дерева элементов формы.

Каждый элемент формы можно получить, указав его имя в качестве свойства этого объекта, то есть через точку от него. В данном случае мы обращаемся к табличной части документа Материалы (Элементы.Материалы).

Табличная часть документа представляет собой объект встроенного языка ТаблицаФормы. Получить ту строку, в которой в настоящее время осуществляется редактирование, можно при помощи свойства программного объекта ТаблицаФормы – ТекущиеДанные (Элементы.Материалы.ТекущиеДанные).

Таким образом, в результате выполнения первой строки процедуры обработчика переменная СтрокаТабличнойЧасти будет содержать объект ДанныеФормыСтруктура. Этот объект содержит данные, находящиеся в текущей строке табличной части документа (Элементы.Материалы.ТекущиеДанные).

Получив этот объект, мы можем обратиться к данным конкретной колонки табличной части, указав имя колонки в качестве свойства объекта. Например, используя обращение СтрокаТаблич- нойЧасти.Количество, мы получаем число, которое находится в редактируемой строке в колонке Количество.

Таким образом, во второй строке процедуры обработчика вычисляется значение колонки Сумма как произведение значений колонок Количество и Цена.

В режиме «1С:Предприятие»

Теперь посмотрим, как это работает. Запустим «1С:Предприятие» в режиме отладки, откроем список документов Приходные накладные и откроем любой из двух созданных нами документов. Если теперь вы поменяете количество в любой строке документа, то сумма в строке будет пересчитана автоматически.

Общий модуль

Необходимо сделать это и для поля Цена. Процедура может понадобиться и в других документах.

Поэтому лучше будет поместить расчет суммы в некоторое «общедоступное» место - Общий модуль, чтобы разные документы, имеющие аналогичные реквизиты табличной части, могли использовать этот алгоритм.

Поэтому создадим общий модуль и перенесем в него нашу процедуру расчета суммы. А в документе просто оставим вызовы этой процедуры из общего модуля.

Добавим объект конфигурации Общий модуль.

Для этого раскроем ветвь Общие в дереве объектов конфигурации, нажав на + слева от нее. Затем выделим ветвь Общие модули и нажмем кнопку Добавить в командной панели окна конфигурации (рис.).

Откроется окно для ввода текста модуля и окно палитры его свойств. Дадим имя модулю – РаботаСДокументами и установим в его свойствах флажок Клиент (управляемое приложение), а флажок Сервер снимем. Это означает, что экземпляры этого модуля будут скомпилированы в контексте тонкого клиента и в контексте веб-клиента (рис. 4.25).

Внесем в модуль следующий текст (листинг 2).

листинг 2. Процедура «РассчитатьСумму()»

Процедура РассчитатьСумму(СтрокаТабличнойЧасти) Экспорт СтрокаТабличнойЧасти.Сумма =

СтрокаТабличнойЧасти.Количество * СтрокаТабличнойЧасти.Цена;

КонецПроцедуры

Прокомментируем этот код. В процедуру РассчитатьСумму() мы передаем переменную СтрокаТабличнойЧасти, которую мы опре- делили в обработчике события ПриИзменении поля Количество. Она содержит данные редактируемой строки табличной части документа ПриходнаяНакладная.

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

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

Теперь в модуле нашей формы изменим текст обработчика Материа- лыКоличествоПриИзменении (листинг 3).

листинг 3. Процедура «МатериалыКоличествоПриИзменении()»

&НаКлиенте

Процедура МатериалыКоличествоПриИзменении(Элемент)

СтрокаТабличнойЧасти = Элементы.Материалы.ТекущиеДанные;

РаботаСДокументами.РассчитатьСумму(СтрокаТабличнойЧасти);

КонецПроцедуры

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

Проверим, как это работает, и убедимся, что ничего не изменилось. Теперь осталось и для поля Цена установить такой же обработчик.

Так как однажды мы уже написали в модуле формы нужную нам процедуру, то мы просто могли бы сопоставить ее также и другому событию другого элемента управления, расположенного в форме. Однако стандарты разработки конфигураций фирмы «1С» не допускают такого решения.

Поэтому мы создадим обработчик события ПриИзменении для поля табличной части Материалы Цена так же, как мы делали это для поля Материалы Количество, и повторим в нем вызов процедуры РассчитатьСумму из общего модуля.

Запустим «1С:Предприятие» в режиме отладки и убедимся, что теперь сумма в строках табличной части документов ПриходнаяНакладная пересчитывается как при изменении количества, так и при изменении цены.

Наши рекомендации