При работе в конфигурации Управление производственным предприятием (УПП) 1.3 или в отраслевых решениях на ее базе (например, ЖКХ от Рарус) часто возникает потребность видеть актуальные закупочные цены непосредственно в момент формирования внутреннего заказа. Это позволяет ответственному лицу сразу оценивать бюджет заказа. Рассмотрим подробно, как реализовать этот функционал технически, какие источники данных использовать и какие нюансы следует учесть при написании кода.
Прежде чем приступать к программированию, нам необходимо определиться, какую именно цену мы хотим видеть. В системе 1С существует несколько регистров, из которых можно получить информацию:
УстановкаЦенНоменклатуры, то этот источник будет самым надежным. Мы сможем получить «срез последних» по конкретному типу цен.Проанализируем ситуацию: для внутреннего заказа чаще всего требуется справочная цена последней закупки, поэтому мы сосредоточимся на получении данных из регистра цен или последних закупок.
Для начала нам нужно решить: будем ли мы сохранять цену в документе или просто показывать ее для справки. Разберем вариант с добавлением реквизита в табличную часть Товары, так как это позволит в дальнейшем использовать эти данные в печатных формах или отчетах.
ВнутреннийЗаказ.Товары добавим новый реквизит ЦенаЗакупки с типом Число (15, 2).Товары.Теперь нам нужно сделать так, чтобы при выборе товара в документе цена подтягивалась автоматически. Основная работа будет происходить в модуле формы документа. Найдем обработчик события ТоварыНоменклатураПриИзменении.
Разберем пример кода, который использует типовые механизмы УПП для получения цены. В УПП есть мощный встроенный модуль Ценообразование, функции которого учитывают валюту, единицы измерения и дату документа.
Процедура ТоварыНоменклатураПриИзменении(Элемент)
СтрокаТабличнойЧасти = ЭлементыФормы.Товары.ТекущаяСтрока;
// Если номенклатура не заполнена, очищаем цену и выходим
Если Не ЗначениеЗаполнено(СтрокаТабличнойЧасти.Номенклатура) Тогда
СтрокаТабличнойЧасти.ЦенаЗакупки = 0;
Возврат;
КонецЕсли;
// Определяем параметры для получения цены
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить("Номенклатура", СтрокаТабличнойЧасти.Номенклатура);
СтруктураПараметров.Вставить("Дата", Дата);
СтруктураПараметров.Вставить("ТипЦен", Справочники.ТипыЦенНоменклатуры.НайтиПоНаименованию("Закупочная"));
// Вызываем типовую функцию УПП
ТаблицаЦен = Ценообразование.ПолучитьЦеныНоменклатуры(Дата, СтруктураПараметров);
Если ТаблицаЦен.Количество() > 0 Тогда
СтрокаЦены = ТаблицаЦен[0];
// Учитываем единицы измерения документа
Коэффициент = ?(СтрокаТабличнойЧасти.ЕдиницаИзмерения.Коэффициент = 0, 1, СтрокаТабличнойЧасти.ЕдиницаИзмерения.Коэффициент);
СтрокаТабличнойЧасти.ЦенаЗакупки = СтрокаЦены.Цена * Коэффициент;
Иначе
СтрокаТабличнойЧасти.ЦенаЗакупки = 0;
КонецЕсли;
КонецПроцедуры
Если в системе не ведется регистр цен, выясним причину и попробуем получить данные напрямую из регистра Закупки. Для этого нам потребуется написать небольшой запрос к базе данных, который найдет последнее поступление по данной позиции номенклатуры.
Функция ПолучитьПоследнююЦенуЗакупки(ВыбНоменклатура) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Закупки.Цена КАК Цена,
| Закупки.Регистратор.Дата КАК ДатаПоступления
|ИЗ
| РегистрНакопления.Закупки КАК Закупки
|ГДЕ
| Закупки.Номенклатура = &Номенклатура
|
|УПОРЯДОЧИТЬ ПО
| ДатаПоступления УБЫВАЙ";
Запрос.УстановитьПараметр("Номенклатура", ВыбНоменклатура);
РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
Возврат Выборка.Цена;
КонецЕсли;
Возврат 0;
КонецФункции
Этот метод можно вызвать в том же обработчике ПриИзменении номенклатуры. Однако помните, что прямой запрос в цикле или при каждом изменении строки может незначительно замедлить работу, если база данных очень большая.
Важно помнить, что в документе ВнутреннийЗаказ товар может быть указан в одних единицах (например, штуки), а в поступлении или прайсе — в других (например, коробки). Всегда используйте Коэффициент из справочника ЕдиницыИзмерения для корректного пересчета.
Также проанализируем ситуацию с валютой. Если цена закупки хранится в долларах, а внутренний заказ оформляется в рублях, необходимо использовать функции модуля РаботаСКурсамиВалют, чтобы привести значения к единому знаменателю на дату документа.
Закупочные цены часто являются конфиденциальной информацией. Если вы добавляете такую колонку, обязательно проверьте права текущего пользователя. Мы рекомендуем использовать проверку ролей:
Если НЕ РольДоступна("ПолныеПрава") И НЕ РольДоступна("ПросмотрЗакупочныхЦен") Тогда
ЭлементыФормы.Товары.Колонки.ЦенаЗакупки.Видимость = Ложь;
КонецЕсли;
Таким образом, мы обеспечим сохранность коммерческой тайны и предоставим информацию только тем сотрудникам, которым она действительно необходима для работы.
Если вы не хотите добавлять новый реквизит в структуру метаданных документа (чтобы не увеличивать размер базы и не усложнять обновление конфигурации), можно воспользоваться событием ПриВыводеСтроки. В этом случае колонка добавляется только на форму как декоративный элемент. Система будет динамически подтягивать цену при прокрутке списка. Однако будьте осторожны: если в документе сотни строк, постоянные запросы к базе при отрисовке интерфейса могут привести к «фризам» (зависаниям) формы.
Резюмируя, наиболее правильным подходом для УПП 1.3 будет добавление реквизита в табличную часть и его заполнение через типовой механизм Ценообразование в момент выбора номенклатуры. Это обеспечит баланс между производительностью и точностью данных.