При работе с типовыми конфигурациями «1С:Предприятие», в частности с «1С:Розница 2.2», пользователи и разработчики часто сталкиваются с необходимостью расширить стандартный набор полей объектов. Например, добавить для номенклатуры поле «Минимальный остаток» или «Количество в упаковке». Изменение конфигурации (снятие с поддержки) крайне нежелательно, так как это усложняет последующие обновления программы.
Для решения этой задачи в Библиотеке стандартных подсистем (БСП), на которой построена «1С:Розница», предусмотрен мощный механизм — Дополнительные реквизиты и сведения. В этой статье мы подробно разберем, как включить этот механизм в пользовательском интерфейсе, как правильно использовать эти данные в программных запросах без ошибок приведения типов, а также как применить расширения конфигурации для добавления свойств к документам.
Прежде чем приступать к программированию, необходимо активировать функциональную опцию в пользовательском режиме и создать нужное свойство. Выполним настройку по шагам:
Теперь в карточке любого товара на вкладке Дополнительно появится созданное нами поле, готовое к заполнению пользователями.
Довольно часто разработчики пытаются получить созданный числовой реквизит в запросах для построения отчетов (например, чтобы рассчитать количество целых упаковок, разделив остаток товара на значение свойства «Количество в упаковке»).
Рассмотрим типичную ошибку при попытке использовать конструкцию ВЫРАЗИТЬ в запросе:
ВЫРАЗИТЬ(ДополнительныеРеквизиты.Значение КАК Число(15,3)) КАК КоличествоВУпаковке
При выполнении такого запроса колонка с результатом часто оказывается пустой (содержит значение NULL). Проанализируем причины этой проблемы и выясним, как их устранить:
1. Несоответствие типов данных в базе. В табличной части ДополнительныеРеквизиты справочника номенклатуры поле Значение имеет составной тип данных. Если при создании реквизита в интерфейсе по ошибке был выбран тип «Дополнительное значение» вместо «Число», то система запишет в базу ссылку на элемент справочника ЗначенияСвойствОбъектов. Попытка выразить ссылку на справочник как число в SQL-запросе всегда возвращает NULL. Убедитесь, что тип реквизита — строго Число.
2. Особенности Левого соединения (LEFT JOIN). Если для товара не заполнен дополнительный реквизит, левое соединение вернет строку со значением NULL во всех полях присоединенной таблицы. Попытка совершить деление на NULL или использовать его в арифметике сделает итоговый результат неопределенным. Для обхода этой проблемы обязательно используйте функцию ЕСТЬNULL.
Разберем готовый и оптимизированный пример запроса. Мы соединим остатки товаров на складах с табличной частью дополнительных реквизитов напрямую, обращаясь к системному имени свойства. Это позволит избежать лишних вложенных запросов.
ВЫБРАТЬ РАЗРЕШЕННЫЕ
Остатки.Склад КАК Склад,
Остатки.Номенклатура КАК Номенклатура,
Остатки.КоличествоОстаток КАК КоличествоОстаток,
// Извлекаем числовое значение свойства, подставляя 1 в случае его отсутствия
ЕСТЬNULL(ВЫРАЗИТЬ(ДопРеквизиты.Значение КАК Число(15, 3)), 1) КАК КоличествоВУпаковке,
// Выполняем арифметическое действие
Остатки.КоличествоОстаток / ЕСТЬNULL(ВЫРАЗИТЬ(ДопРеквизиты.Значение КАК Число(15, 3)), 1) КАК КоличествоУпаковок
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, ) КАК Остатки
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура.ДополнительныеРеквизиты КАК ДопРеквизиты
ПО ДопРеквизиты.Ссылка = Остатки.Номенклатура
И ДопРеквизиты.Свойство.Имя = "КоличествоВУпаковке_ba7b538cef6445ffb09f0384a2b46264"
В этом запросе мы используем автоматическое уникальное имя свойства Свойство.Имя, которое генерируется БСП при создании реквизита. Использование функции ЕСТЬNULL(..., 1) гарантирует безопасность математических операций: даже если реквизит не заполнен или равен нулю, деление на ноль будет предотвращено путем подстановки единицы.
Полезный совет: Если вы разрабатываете отчет на базе Системы компоновки данных (СКД), вам не нужно вручную прописывать левые соединения к табличным частям. СКД умеет «разыменовывать» поля через точку. Достаточно использовать выражение вида Номенклатура.[Количество в упаковке] в настройках полей или вычисляемых полей. Платформа самостоятельно сформирует оптимальный SQL-запрос к СУБД с приведением типов.
Если вам требуется получить значение реквизита в модуле менеджера, модуле объекта или при формировании печатной формы, можно использовать обход табличной части объекта. Напишем универсальную функцию для безопасного извлечения числового значения:
Функция ПолучитьЗначениеЧисловогоДопРеквизита(СсылкаНаОбъект, ИмяРеквизита) Экспорт
// Ищем свойство в ПВХ по его системному имени
Свойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя", ИмяРеквизита);
Если Не ЗначениеЗаполнено(Свойство) Тогда
Возврат 1; // Возвращаем 1 по умолчанию, чтобы избежать деления на 0 в дальнейших расчетах
КонецЕсли;
// Находим строку с нужным свойством в табличной части объекта
ПараметрыОтбора = Новый Структура("Свойство", Свойство);
НайденныеСтроки = СсылкаНаОбъект.ДополнительныеРеквизиты.НайтиСтроки(ПараметрыОтбора);
Если НайденныеСтроки.Количество() > 0 Тогда
ЗначениеРеквизита = НайденныеСтроки[0].Значение;
Если ТипЗнч(ЗначениеРеквизита) = Тип("Число") Тогда
Возврат ?(ЗначениеРеквизита = 0, 1, ЗначениеРеквизита);
КонецЕсли;
КонецЕсли;
Возврат 1;
КонецФункции
Данная функция извлекает значение напрямую из памяти, если объект уже прочитан, что работает быстрее, чем выполнение тяжелого запроса к базе данных.
В типовой конфигурации «1С:Розница 2.2» (а также во многих отраслевых решениях, например, от компании «Рарус») разработчики заблокировали возможность создания дополнительных реквизитов и сведений для документов в пользовательском режиме. По умолчанию этот функционал доступен только для справочников. Однако мы можем легко обойти это ограничение с помощью расширений конфигурации, сохранив основную программу на полной поддержке.
Рассмотрим два возможных пути реализации этой задачи:
Если вам нужно добавить конкретное фиксированное поле в документ (например, «Дата отгрузки» во «Внутреннее перемещение»), выполните следующие действия:
ВнутреннееПеремещение), нажмите правой кнопкой мыши и выберите Добавить в расширение.ХХ_ДатаОтгрузки с типом Дата).Этот способ прост и надежен, данные будут физически храниться в таблице документа в СУБД, а конфигурация останется на поддержке.
Если вы хотите, чтобы пользователи могли самостоятельно через пользовательский интерфейс создавать любые свойства для документов (так же, как для номенклатуры), необходимо полноценно интегрировать документ с подсистемой БСП «Свойства» через расширение:
ДополнительныеРеквизиты. Структура колонок должна быть следующей:
Свойство — тип ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведенияЗначение — тип Характеристика.ДополнительныеРеквизитыИСведения (или составной тип, включающий справочники и примитивные типы данных вашей конфигурации)ТекстоваяСтрока — тип Строка (длина 150 или неограниченная)ВладелецДополнительныхРеквизитовИСведений (или аналогичный в вашей версии БСП) и добавьте ваш документ в список типов этого определяемого типа.ПриСозданииНаСервере с помощью аннотации &После:
&После("ПриСозданииНаСервере")
Процедура ХХ_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Подключаем автогенерацию элементов управления свойствами на форме
ПараметрыСвойств = УправлениеСвойствами.ПараметрыРедактированияСвойств();
УправлениеСвойствами.ПриСозданииНаСервере(ЭтотОбъект, ПараметрыСвойств);
КонецПроцедуры
После применения этого расширения в режиме «1С:Предприятие» в списке наборов дополнительных реквизитов появится ваш документ, и пользователи смогут создавать для него любые динамические свойства без изменения кода!
Использование дополнительных числовых реквизитов для хранения минимального остатка и последующего расчета закупок было чрезвычайно популярно в версиях «Розницы 2.2» и «2.3». Однако технологии не стоят на месте.
Если вы планируете переход на актуальную версию «1С:Розница 3.0» (которая разработана на единой архитектуре с «1С:УНФ»), обратите внимание, что там больше нет необходимости использовать «костыли» в виде дополнительных реквизитов для управления запасами. В версии 3.0 встроен мощный типовой функционал «Управление запасами». Вы можете непосредственно в карточке товара настраивать минимальный и максимальный остаток для каждого склада индивидуально, а встроенный помощник «Расчет потребностей» автоматически сформирует заказы поставщикам на основе этих данных.