Как реализовать автоматическую подстановку цен и расчет площади в 1С 8.3

Программист 1С v8.3 (Управляемые формы) Управленческий учет Сфера услуг, туризм и социальный сектор
← На главную

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

Архитектура решения: Справочники и Регистры

Прежде чем приступать к кодингу, проанализируем структуру метаданных. Чтобы система работала корректно, нам понадобятся следующие объекты:

  1. Справочник Номенклатура (или Материалы): Здесь мы храним перечень типов ковров (шерсть, синтетика, шелк).
  2. Регистр сведений ЦеныМатериалов: Это периодический регистр, где ресурсом является Цена, а измерением — Материал. Периодичность позволит нам изменять цены со временем, сохраняя историю.
  3. Документ Договор (или Заказ): Основной объект, где происходят расчеты.

В документе нам необходимы следующие реквизиты: Длина (Число), Ширина (Число), Площадь (Число), Материал (Ссылка на справочник), Цена (Число) и Сумма (Число).

Автоматический расчет площади при изменении размеров

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

Откроем форму документа и для полей Длина и Ширина создадим событие ПриИзменении. Пропишем в них общую процедуру пересчета:


&НаКлиенте
Процедура ДлинаПриИзменении(Элемент)
    РассчитатьПлощадьИСтоимость();
КонецПроцедуры

&НаКлиенте
Процедура ШиринаПриИзменении(Элемент)
    РассчитатьПлощадьИСтоимость();
КонецПроцедуры

&НаКлиенте
Процедура РассчитатьПлощадьИСтоимость()
    Объект.Площадь = Объект.Длина * Объект.Ширина;
    // Сразу вызываем расчет суммы, так как площадь изменилась
    РассчитатьСуммуЗаказа();
КонецПроцедуры

Важный момент: Мы выносим логику в отдельную процедуру РассчитатьПлощадьИСтоимость, чтобы не дублировать код в обоих обработчиках. Это упрощает поддержку системы.

Получение актуальной цены из регистра сведений

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

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


&НаКлиенте
Процедура МатериалПриИзменении(Элемент)
    Объект.Цена = ПолучитьЦенуНаСервере(Объект.Материал, Объект.Дата);
    РассчитатьСуммуЗаказа();
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьЦенуНаСервере(ВыбранныйМатериал, ДатаДокумента)
    Отбор = Новый Структура("Материал", ВыбранныйМатериал);
    // Используем метод СрезПоследних для получения актуальной цены на дату документа
    ЗначенияРесурсов = РегистрыСведений.ЦеныМатериалов.СрезПоследних(ДатаДокумента, Отбор);
    
    Если ЗначенияРесурсов.Количество() > 0 Тогда
        Возврат ЗначенияРесурсов[0].Цена;
    Иначе
        Возврат 0;
    КонецЕсли;
КонецФункции

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

Финальный расчет итоговой суммы

Когда у нас есть и площадь, и цена, мы можем вычислить итоговую стоимость заказа. Разберем процедуру РассчитатьСуммуЗаказа, которую мы вызывали ранее:


&НаКлиенте
Процедура РассчитатьСуммуЗаказа()
    // Основная формула: Сумма = Количество (в нашем случае Площадь) * Цена
    Объект.Сумма = Объект.Площадь * Объект.Цена;
КонецПроцедуры

Теперь система работает как единое целое: меняем длину — меняется площадь и сумма; меняем материал — обновляется цена и сумма. Это и есть полноценная автоматизация.

Обработка сложных случаев: нестандартные формы ковров

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

Рекомендуется добавить в документ реквизит ФормаКовра (Перечисление: Прямоугольный, Круглый). Проанализируем, как изменится код расчета площади:


&НаКлиенте
Процедура РассчитатьПлощадьИСтоимость()
    Если Объект.ФормаКовра = ПредопределенноеЗначение("Перечисление.ФормыКовров.Круглый") Тогда
        // Площадь круга S = pi * r^2. Допустим, Длина - это диаметр.
        Радиус = Объект.Длина / 2;
        Объект.Площадь = 3.14 * (Радиус * Радиус);
    Иначе
        Объект.Площадь = Объект.Длина * Объект.Ширина;
    КонецЕсли;
    
    РассчитатьСуммуЗаказа();
КонецПроцедуры

Создание оплаты на основании договора

Чтобы автоматизировать процесс создания документа «Оплата», воспользуемся механизмом «Заполнение на основании». В модуле объекта документа Оплата необходимо описать процедуру ОбработкаЗаполнения.

Рассмотрим пример кода, который перенесет данные из заказа в оплату:


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
    Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ДоговорХимчистки") Тогда
        // Копируем данные из документа-основания
        ЭтотОбъект.Клиент = ДанныеЗаполнения.Клиент;
        ЭтотОбъект.СуммаДокумента = ДанныеЗаполнения.Сумма;
        ЭтотОбъект.Основание = ДанныеЗаполнения.Ссылка;
    КонецЕсли;
КонецПроцедуры

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

Практические советы по развитию системы

Для создания действительно профессионального решения для химчистки, мы рекомендуем учесть следующие нюансы:

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

← На главную