При кастомизации и доработке типовых конфигураций на платформе 1С:Предприятие 8.3 (таких как «Управление торговлей», «ERP Управление предприятием» или «Комплексная автоматизация») разработчики часто сталкиваются с неприятной проблемой. В конфигураторе открывается форма подбора товаров, в запрос динамического списка СписокНоменклатура (или аналогичного) добавляется новое поле (например, себестоимость товара), колонка перетаскивается на форму, но в режиме «1С:Предприятие» новая колонка упорно отказывается отображаться. Почему так происходит и как заставить платформу вывести добавленные данные? Разберем эту проблему подробно и по шагам.
В современных конфигурациях 1С, построенных на архитектуре Библиотеки стандартных подсистем (БСП), динамические списки в сложных формах (особенно в форме подбора товаров) практически никогда не работают на том статическом запросе, который написан в конфигураторе. Текст запроса собирается программно «на лету» в зависимости от различных факторов: включена ли работа с характеристиками, отображаются ли цены и остатки, выбран ли конкретный склад или соглашение.
Когда форма инициализируется на сервере, срабатывают процедуры общего назначения, которые полностью переписывают свойство ТекстЗапроса динамического списка. В результате ваш вручную отредактированный запрос заменяется автоматически сгенерированным кодом, в котором вашего поля просто не существует. Рассмотрим, как это выглядит в коде:
СвойстваСписка = ОбщегоНазначения.СтруктураСвойствДинамическогоСписка();
СвойстваСписка.ТекстЗапроса = ПолучитьТекстЗапросаДляПодбора(); // Здесь генерируется новый текст
ОбщегоНазначения.УстановитьСвойстваДинамическогоСписка(Элементы.СписокНоменклатура, СвойстваСписка);
Для того чтобы решить эту проблему, выполним следующие шаги:
ПриСозданииНаСервере.Элементы.СписокНоменклатура.ТекстЗапроса.ПодборТоваровСервер, ПодборТоваровПереопределяемый или ЗапасыСервер. Ищите функции с именами ИнициализироватьЗапросСписка или ТекстЗапросаСпискаФормыПодбора.&После или &Вместо) и добавим наше поле себестоимости в собираемый текст запроса.Форма подбора товаров в ERP-решениях 1С крайне сложна с точки зрения интерфейса. В зависимости от выбранного режима («Иерархия», «Плоский список», «По категориям») на форме могут отображаться абсолютно разные элементы таблиц, хотя все они могут быть связаны с одним динамическим списком или с разными списками-синонимами.
Например, разработчик мог перетащить добавленную колонку «Себестоимость» в таблицу СписокНоменклатура, предназначенную для плоского списка, а пользователь при открытии подбора видит иерархическое дерево или список характеристик. Проанализируем структуру формы подбора:
СписокХарактеристики. В этом случае себестоимость нужно добавлять и в его запрос тоже, причем связывая таблицы по полям Номенклатура и Характеристика.Платформа 1С сохраняет персональные настройки интерфейса для каждого пользователя (видимость колонок, их ширину, порядок). Если пользователь ранее уже открывал форму подбора, то система запомнила расположение колонок на тот момент.
Когда вы добавляете новое поле в конфигураторе, оно может автоматически скрываться для старых пользователей, так как приоритет имеют их сохраненные локальные настройки. Чтобы сбросить кэш настроек и отобразить колонку, выполним простые действия в пользовательском режиме:
Если данные по себестоимости привязаны к определенным функциональным опциям (ФО), платформа может автоматически отключать видимость колонки. Выясним, почему это происходит:
Функциональные опции.Посмотрим на практический пример того, как правильно модифицировать динамический список программно в расширении. Предположим, мы перехватываем процедуру формы ПриСозданииНаСервере:
&После("ПриСозданииНаСервере")
Процедура Расш1_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Проверим, содержит ли текущий текст запроса наше поле.
// Если запрос был переопределен БСП, нам нужно внедрить свое поле.
ТекстЗапроса = Список.ТекстЗапроса;
Если Не СтрНайти(ВРег(ТекстЗапроса), "СЕБЕСТОИМОСТЬ") > 0 Тогда
// Модифицируем текст запроса, добавляя левое соединение с регистром сведений/накопления себестоимости
НовыйТекстЗапроса = ВставитьСебестоимостьВЗапрос(ТекстЗапроса);
Список.ТекстЗапроса = НовыйТекстЗапроса;
КонецЕсли;
КонецПроцедуры
&НаСервере
Функция ВставитьСебестоимостьВЗапрос(Знач ИсходныйТекст)
// Шаблон вставки поля и соединения (пример упрощенный)
// Реализуйте замену строк в зависимости от структуры вашего базового запроса
СтрокаПолей = "ВЫБРАТЬ
| СправочникНоменклатура.Ссылка КАК Ссылка,
| ЕСТЬNULL(РегистрСебестоимость.Стоимость, 0) КАК Себестоимость,";
СтрокаСоединения = "ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.СебестоимостьТоваров.СрезПоследних КАК РегистрСебестоимость
| ПО СправочникНоменклатура.Ссылка = РегистрСебестоимость.Номенклатура";
// Производим замену стандартных фрагментов запроса на наши модифицированные версии
Результат = СтрЗаменить(ИсходныйТекст, "ВЫБРАТЬ", СтрокаПолей);
Результат = Результат + " " + СтрокаСоединения;
Возврат Результат;
КонецФункции
Используя приведенную схему анализа и доработки, вы легко определите, на каком этапе «теряется» колонка динамического списка, и сможете корректно вывести показатель себестоимости (или любые другие данные) в форму подбора товаров.