Введение. Вместо предисловия
Всем привет! По просьбе некоторых пользователей ресурса, я решил опубликовать несколько практических примеров по доработке динамических списков в современных конфигурациях. В качестве базовой конфигурации я буду использовать 1С:Управление нашей фирмы 3.0.12.261 на 1C:Платформе 8.3.27.2074 на примере справочника "Номенклатура".

Рис.1. Список значений "Номенклатуры" с колонкой "штрихкод".
Доработка динамического списка задача на текущее время и так-то не слишком простая, но в данном мануале, я приведу четыре способа доработки.
Практические подходы
Рассмотрим типовой справочник "Номенклатура" конфигурации 1С:УНФ 3.0.12.261. В данной конфигурации типовое формирование динамического списка происходит "подменой запроса" через процедуру ПереопределитьТекстЗапросаСписокЗапасы формы списка запасы.
Основной список запроса переопределения выглядит вот так:
ТекстЗапроса = "ВЫБРАТЬ РАЗРЕШЕННЫЕ | СправочникНоменклатура.Ссылка КАК Ссылка, | СправочникНоменклатура.Ссылка КАК Номенклатура, | СправочникНоменклатура.ПометкаУдаления КАК ПометкаУдаления, | ЛОЖЬ КАК ПрямойАналог, | СправочникНоменклатура.Родитель КАК Родитель, | СправочникНоменклатура.ЭтоГруппа КАК ЭтоГруппа, | СправочникНоменклатура.Код КАК Код, | СправочникНоменклатура.Наименование КАК Наименование, | СправочникНоменклатура.Артикул КАК Артикул, | СправочникНоменклатура.ДатаИзменения КАК ДатаИзменения, | СправочникНоменклатура.МетодОценки КАК МетодОценки, | ВЫРАЗИТЬ(СправочникНоменклатура.НаименованиеПолное КАК СТРОКА(1000)) КАК НаименованиеПолное, | СправочникНоменклатура.НаправлениеДеятельности КАК НаправлениеДеятельности, | СправочникНоменклатура.КатегорияНоменклатуры КАК КатегорияНоменклатуры, | СправочникНоменклатура.Поставщик КАК Поставщик, | СправочникНоменклатура.Склад КАК Склад, | СправочникНоменклатура.СпособПополнения КАК СпособПополнения, | СправочникНоменклатура.СрокПополнения КАК СрокПополнения, | СправочникНоменклатура.ВидСтавкиНДС КАК ВидСтавкиНДС, | ЗНАЧЕНИЕ(Справочник.СтавкиНДС.ПустаяСсылка) КАК СтавкаНДСНоменклатуры, | СправочникНоменклатура.СчетУчетаЗапасов КАК СчетУчетаЗапасов, | СправочникНоменклатура.СчетУчетаЗатрат КАК СчетУчетаЗатрат, | СправочникНоменклатура.СчетУчетаНДСПоПриобретеннымЦенностям КАК СчетУчетаНДСПоПриобретеннымЦенностям, | СправочникНоменклатура.СчетУчетаНДСПоРеализации КАК СчетУчетаНДСПоРеализации, | СправочникНоменклатура.ТипНоменклатуры КАК ТипНоменклатуры, | СправочникНоменклатура.Ячейка КАК Ячейка, | СправочникНоменклатура.ЦеноваяГруппа КАК ЦеноваяГруппа, | СправочникНоменклатура.ИспользоватьХарактеристики КАК ИспользоватьХарактеристики, | СправочникНоменклатура.ИспользоватьПартии КАК ИспользуетсяРезервирование, | СправочникНоменклатура.ИспользоватьПартии КАК ИспользоватьПартии, | СправочникНоменклатура.ЭтоНабор КАК ЭтоНабор, | СправочникНоменклатура.Недействителен КАК Недействителен, | СправочникНоменклатура.СрокИсполненияЗаказа КАК СрокИсполненияЗаказа, | СправочникНоменклатура.НормаВремени КАК НормаВремени, | СправочникНоменклатура.ФиксированнаяСтоимость КАК ФиксированнаяСтоимость, | СправочникНоменклатура.СтранаПроисхождения КАК СтранаПроисхождения, | СправочникНоменклатура.ВидАлкогольнойПродукции КАК ВидАлкогольнойПродукции, | СправочникНоменклатура.ИмпортнаяАлкогольнаяПродукция КАК ИмпортнаяАлкогольнаяПродукция, | СправочникНоменклатура.ПроизводительИмпортерАлкогольнойПродукции КАК ПроизводительИмпортерАлкогольнойПродукции, | СправочникНоменклатура.Вес КАК Вес, | СправочникНоменклатура.Объем КАК Объем, | СправочникНоменклатура.ОбъемДАЛ КАК ОбъемДАЛ, | СправочникНоменклатура.ИспользоватьСерииНоменклатуры КАК ИспользоватьСерииНоменклатуры, | СправочникНоменклатура.ГарантийныйСрок КАК ГарантийныйСрок, | СправочникНоменклатура.ПодконтрольнаяПродукцияВЕТИС КАК ПодконтрольнаяПродукцияВЕТИС, | СправочникНоменклатура.ВыписыватьГарантийныйТалон КАК ВыписыватьГарантийныйТалон, | ВЫБОР | КОГДА НЕ СправочникНоменклатура.ЭтоНабор | И НЕ(СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Операция) | ИЛИ СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.ВидРабот)) | ТОГДА 0 | ИНАЧЕ -1 | КОНЕЦ КАК КартинкаОстатки, | СправочникНоменклатура.ПроверятьЗаполнениеПартий КАК ПроверятьЗаполнениеПартий, | СправочникНоменклатура.ПроверятьЗаполнениеХарактеристики КАК ПроверятьЗаполнениеХарактеристики, | 0 КАК КартинкаКорзина, | ПОДСТРОКА(СправочникНоменклатура.Комментарий, 1, 1000) КАК Комментарий, | &Период КАК Период, | &ВидЦен КАК ВидЦен, | ВЫБОР | КОГДА СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Запас) | ТОГДА 0 | КОГДА СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.ПодарочныйСертификат) | ТОГДА 4 | ИНАЧЕ 2 | КОНЕЦ + ВЫБОР | КОГДА СправочникНоменклатура.ИспользоватьХарактеристики | ТОГДА 1 | ИНАЧЕ 0 | КОНЕЦ + ВЫБОР | КОГДА СправочникНоменклатура.ПометкаУдаления | ТОГДА 6 | ИНАЧЕ 0 | КОНЕЦ + ВЫБОР | КОГДА СправочникНоменклатура.ЭтоНабор | ТОГДА 12 | ИНАЧЕ 0 | КОНЕЦ КАК ВариантКартинки, | СправочникНоменклатура.Родитель КАК Группа, | ВЫБОР | КОГДА НаличиеФайлов.ЕстьФайлы ЕСТЬ NULL | ТОГДА 0 | КОГДА НаличиеФайлов.ЕстьФайлы | ТОГДА 1 | ИНАЧЕ 0 | КОНЕЦ КАК ЕстьФайлы, | &ДопПоляШаблон КАК ДопПоляШаблон, | СправочникНоменклатура.Номинал КАК Номинал, | СправочникНоменклатура.Весовой КАК Весовой, | СправочникНоменклатура.ЗапретитьВводДробногоКоличества КАК ЗапретитьВводДробногоКоличества |ИЗ | Справочник.Номенклатура КАК СправочникНоменклатура | {ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НаличиеФайлов КАК НаличиеФайлов | ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами}";
В список я буду добавлять колонку "штрихкод" как самый простой пример для понимания работы. Переходим к методам разработки:
1. Виртуальные таблицы
Один из самых простых и медленных методов на больших справочниках - это формирование дополнительной виртуальной таблицы.
Первым шагом, что я должен сделать - это доработать сам запрос динамического списка - СписокЗапасы:
ВЫБРАТЬ
НоменклатураПереопределяемый.Ссылка КАК Ссылка,
НоменклатураПереопределяемый.Ссылка КАК Номенклатура,
НоменклатураПереопределяемый.ПометкаУдаления КАК ПометкаУдаления,
ЛОЖЬ КАК ПрямойАналог,
НоменклатураПереопределяемый.Код КАК Код,
НоменклатураПереопределяемый.Наименование КАК Наименование,
НоменклатураПереопределяемый.Артикул КАК Артикул,
НоменклатураПереопределяемый.ДатаИзменения КАК ДатаИзменения,
ЕСТЬNULL(НоменклатураПереопределяемый.ЕдиницаИзмерения, ЗНАЧЕНИЕ(Справочник.ЕдиницыИзмерения.ПустаяСсылка)) КАК ЕдиницаИзмерения,
1 КАК Коэффициент,
"" КАК Штрихкод,
НоменклатураПереопределяемый.МетодОценки КАК МетодОценки,
ВЫРАЗИТЬ(НоменклатураПереопределяемый.НаименованиеПолное КАК СТРОКА(1000)) КАК НаименованиеПолное,
НоменклатураПереопределяемый.НаправлениеДеятельности КАК НаправлениеДеятельности,
НоменклатураПереопределяемый.КатегорияНоменклатуры КАК КатегорияНоменклатуры,
НоменклатураПереопределяемый.Поставщик КАК Поставщик,
НоменклатураПереопределяемый.Склад КАК Склад,
НоменклатураПереопределяемый.СпособПополнения КАК СпособПополнения,
НоменклатураПереопределяемый.СрокПополнения КАК СрокПополнения,
НоменклатураПереопределяемый.ВидСтавкиНДС КАК ВидСтавкиНДС,
ЗНАЧЕНИЕ(Справочник.СтавкиНДС.ПустаяСсылка) КАК СтавкаНДСНоменклатуры,
НоменклатураПереопределяемый.СчетУчетаЗапасов КАК СчетУчетаЗапасов,
НоменклатураПереопределяемый.СчетУчетаЗатрат КАК СчетУчетаЗатрат,
НоменклатураПереопределяемый.СчетУчетаНДСПоПриобретеннымЦенностям КАК СчетУчетаНДСПоПриобретеннымЦенностям,
НоменклатураПереопределяемый.СчетУчетаНДСПоРеализации КАК СчетУчетаНДСПоРеализации,
НоменклатураПереопределяемый.ТипНоменклатуры КАК ТипНоменклатуры,
НоменклатураПереопределяемый.Ячейка КАК Ячейка,
НоменклатураПереопределяемый.ЦеноваяГруппа КАК ЦеноваяГруппа,
НоменклатураПереопределяемый.ИспользоватьХарактеристики КАК ИспользоватьХарактеристики,
НоменклатураПереопределяемый.ИспользоватьПартии КАК ИспользуетсяРезервирование,
НоменклатураПереопределяемый.ИспользоватьПартии КАК ИспользоватьПартии,
НоменклатураПереопределяемый.Недействителен КАК Недействителен,
НоменклатураПереопределяемый.СрокИсполненияЗаказа КАК СрокИсполненияЗаказа,
НоменклатураПереопределяемый.НормаВремени КАК НормаВремени,
НоменклатураПереопределяемый.ФиксированнаяСтоимость КАК ФиксированнаяСтоимость,
НоменклатураПереопределяемый.СтранаПроисхождения КАК СтранаПроисхождения,
НоменклатураПереопределяемый.ВидАлкогольнойПродукции КАК ВидАлкогольнойПродукции,
НоменклатураПереопределяемый.ИмпортнаяАлкогольнаяПродукция КАК ИмпортнаяАлкогольнаяПродукция,
НоменклатураПереопределяемый.ПроизводительИмпортерАлкогольнойПродукции КАК ПроизводительИмпортерАлкогольнойПродукции,
НоменклатураПереопределяемый.Вес КАК Вес,
НоменклатураПереопределяемый.Объем КАК Объем,
НоменклатураПереопределяемый.ОбъемДАЛ КАК ОбъемДАЛ,
ПОДСТРОКА(НоменклатураПереопределяемый.Комментарий, 1, 1000) КАК Комментарий,
ВЫБОР
КОГДА НоменклатураПереопределяемый.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Запас)
ТОГДА 0
ИНАЧЕ 2
КОНЕЦ + ВЫБОР
КОГДА НоменклатураПереопределяемый.ИспользоватьХарактеристики
ТОГДА 1
ИНАЧЕ 0
КОНЕЦ + ВЫБОР
КОГДА НоменклатураПереопределяемый.ПометкаУдаления
ТОГДА 4
ИНАЧЕ 0
КОНЕЦ + ВЫБОР
КОГДА НоменклатураПереопределяемый.ЭтоНабор
ТОГДА 8
ИНАЧЕ 0
КОНЕЦ КАК ВариантКартинки,
0 КАК Цена,
ЗНАЧЕНИЕ(Справочник.Валюты.ПустаяСсылка) КАК ВалютаЦены,
ВЫРАЗИТЬ("""" КАК СТРОКА(3)) КАК ВалютаЦеныПредставление,
ЕСТЬNULL(Остатки.Количество, 0) КАК КоличествоОстаток,
ЕСТЬNULL(Остатки.Резерв, 0) КАК Резерв,
НоменклатураПереопределяемый.ИспользоватьСерииНоменклатуры КАК ИспользоватьСерииНоменклатуры,
НоменклатураПереопределяемый.ГарантийныйСрок КАК ГарантийныйСрок,
НоменклатураПереопределяемый.ВыписыватьГарантийныйТалон КАК ВыписыватьГарантийныйТалон,
НоменклатураПереопределяемый.ЭтоНабор КАК ЭтоНабор,
0 КАК ЕстьФайлы,
0 КАК КартинкаОстатки,
0 КАК КартинкаКорзина,
НоменклатураПереопределяемый.ПроверятьЗаполнениеПартий КАК ПроверятьЗаполнениеПартий,
НоменклатураПереопределяемый.ПроверятьЗаполнениеХарактеристики КАК ПроверятьЗаполнениеХарактеристики,
НоменклатураПереопределяемый.Родитель КАК Группа,
НоменклатураПереопределяемый.Номинал КАК Номинал,
НоменклатураПереопределяемый.Весовой КАК Весовой,
НоменклатураПереопределяемый.ЗапретитьВводДробногоКоличества КАК ЗапретитьВводДробногоКоличества
ИЗ
Справочник.Номенклатура КАК НоменклатураПереопределяемый
ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
ОстаткиТоваров.Номенклатура КАК Номенклатура,
СУММА(ОстаткиТоваров.Количество) КАК Количество,
СУММА(ОстаткиТоваров.Резерв) КАК Резерв
ИЗ
РегистрСведений.ОстаткиТоваров КАК ОстаткиТоваров
СГРУППИРОВАТЬ ПО
ОстаткиТоваров.Номенклатура) КАК Остатки
ПО НоменклатураПереопределяемый.Ссылка = Остатки.НоменклатураЗдесь я просто добавил в выборку дополнительную "колонку" - штрихкод
Запрос 1С"" КАК Штрихкод,
Далее, я дорабатываю процедуру ПереопределитьТекстЗапросаСписокЗапасы
&НаСервере &Вместо("ПереопределитьТекстЗапросаСписокЗапасы") Процедура ШКН1_ПереопределитьТекстЗапросаСписокЗапасы() ОтборПоВидуЦенКонтрагентов = ТипЗнч(ОтборВидЦен) = Тип("СправочникСсылка.ВидыЦенКонтрагентов"); ВидЦенНесколькоВалютДляЦен = Ложь; ТекстЗапроса = "ВЫБРАТЬ | МАКСИМУМ(ШтрихкодыНоменклатуры.Штрихкод) КАК Штрихкод, | ШтрихкодыНоменклатуры.Номенклатура КАК Номенклатура |ПОМЕСТИТЬ ВТ_ШК1 |ИЗ | РегистрСведений.ШтрихкодыНоменклатуры КАК ШтрихкодыНоменклатуры | |СГРУППИРОВАТЬ ПО | ШтрихкодыНоменклатуры.Номенклатура | |ИНДЕКСИРОВАТЬ ПО | Номенклатура |; | |//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ РАЗРЕШЕННЫЕ | СправочникНоменклатура.Ссылка КАК Ссылка, | СправочникНоменклатура.Ссылка КАК Номенклатура, | СправочникНоменклатура.ПометкаУдаления КАК ПометкаУдаления, | ЛОЖЬ КАК ПрямойАналог, | СправочникНоменклатура.Родитель КАК Родитель, | СправочникНоменклатура.ЭтоГруппа КАК ЭтоГруппа, | СправочникНоменклатура.Код КАК Код, | СправочникНоменклатура.Наименование КАК Наименование, | СправочникНоменклатура.Артикул КАК Артикул, | СправочникНоменклатура.ДатаИзменения КАК ДатаИзменения, | СправочникНоменклатура.МетодОценки КАК МетодОценки, | ВЫРАЗИТЬ(СправочникНоменклатура.НаименованиеПолное КАК СТРОКА(1000)) КАК НаименованиеПолное, | СправочникНоменклатура.НаправлениеДеятельности КАК НаправлениеДеятельности, | СправочникНоменклатура.КатегорияНоменклатуры КАК КатегорияНоменклатуры, | СправочникНоменклатура.Поставщик КАК Поставщик, | СправочникНоменклатура.Склад КАК Склад, | СправочникНоменклатура.СпособПополнения КАК СпособПополнения, | СправочникНоменклатура.СрокПополнения КАК СрокПополнения, | СправочникНоменклатура.ВидСтавкиНДС КАК ВидСтавкиНДС, | ЗНАЧЕНИЕ(Справочник.СтавкиНДС.ПустаяСсылка) КАК СтавкаНДСНоменклатуры, | СправочникНоменклатура.СчетУчетаЗапасов КАК СчетУчетаЗапасов, | СправочникНоменклатура.СчетУчетаЗатрат КАК СчетУчетаЗатрат, | СправочникНоменклатура.СчетУчетаНДСПоПриобретеннымЦенностям КАК СчетУчетаНДСПоПриобретеннымЦенностям, | СправочникНоменклатура.СчетУчетаНДСПоРеализации КАК СчетУчетаНДСПоРеализации, | СправочникНоменклатура.ТипНоменклатуры КАК ТипНоменклатуры, | СправочникНоменклатура.Ячейка КАК Ячейка, | СправочникНоменклатура.ЦеноваяГруппа КАК ЦеноваяГруппа, | СправочникНоменклатура.ИспользоватьХарактеристики КАК ИспользоватьХарактеристики, | СправочникНоменклатура.ИспользоватьПартии КАК ИспользуетсяРезервирование, | СправочникНоменклатура.ИспользоватьПартии КАК ИспользоватьПартии, | СправочникНоменклатура.ЭтоНабор КАК ЭтоНабор, | СправочникНоменклатура.Недействителен КАК Недействителен, | СправочникНоменклатура.СрокИсполненияЗаказа КАК СрокИсполненияЗаказа, | СправочникНоменклатура.НормаВремени КАК НормаВремени, | СправочникНоменклатура.ФиксированнаяСтоимость КАК ФиксированнаяСтоимость, | СправочникНоменклатура.СтранаПроисхождения КАК СтранаПроисхождения, | СправочникНоменклатура.ВидАлкогольнойПродукции КАК ВидАлкогольнойПродукции, | СправочникНоменклатура.ИмпортнаяАлкогольнаяПродукция КАК ИмпортнаяАлкогольнаяПродукция, | СправочникНоменклатура.ПроизводительИмпортерАлкогольнойПродукции КАК ПроизводительИмпортерАлкогольнойПродукции, | СправочникНоменклатура.Вес КАК Вес, | СправочникНоменклатура.Объем КАК Объем, | СправочникНоменклатура.ОбъемДАЛ КАК ОбъемДАЛ, | СправочникНоменклатура.ИспользоватьСерииНоменклатуры КАК ИспользоватьСерииНоменклатуры, | СправочникНоменклатура.ГарантийныйСрок КАК ГарантийныйСрок, | СправочникНоменклатура.ПодконтрольнаяПродукцияВЕТИС КАК ПодконтрольнаяПродукцияВЕТИС, | СправочникНоменклатура.ВыписыватьГарантийныйТалон КАК ВыписыватьГарантийныйТалон, | ВЫБОР | КОГДА НЕ СправочникНоменклатура.ЭтоНабор | И НЕ(СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Операция) | ИЛИ СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.ВидРабот)) | ТОГДА 0 | ИНАЧЕ -1 | КОНЕЦ КАК КартинкаОстатки, | СправочникНоменклатура.ПроверятьЗаполнениеПартий КАК ПроверятьЗаполнениеПартий, | СправочникНоменклатура.ПроверятьЗаполнениеХарактеристики КАК ПроверятьЗаполнениеХарактеристики, | 0 КАК КартинкаКорзина, | ПОДСТРОКА(СправочникНоменклатура.Комментарий, 1, 1000) КАК Комментарий, | &Период КАК Период, | &ВидЦен КАК ВидЦен, | ВЫБОР | КОГДА СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Запас) | ТОГДА 0 | КОГДА СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.ПодарочныйСертификат) | ТОГДА 4 | ИНАЧЕ 2 | КОНЕЦ + ВЫБОР | КОГДА СправочникНоменклатура.ИспользоватьХарактеристики | ТОГДА 1 | ИНАЧЕ 0 | КОНЕЦ + ВЫБОР | КОГДА СправочникНоменклатура.ПометкаУдаления | ТОГДА 6 | ИНАЧЕ 0 | КОНЕЦ + ВЫБОР | КОГДА СправочникНоменклатура.ЭтоНабор | ТОГДА 12 | ИНАЧЕ 0 | КОНЕЦ КАК ВариантКартинки, | СправочникНоменклатура.Родитель КАК Группа, | ВЫБОР | КОГДА НаличиеФайлов.ЕстьФайлы ЕСТЬ NULL | ТОГДА 0 | КОГДА НаличиеФайлов.ЕстьФайлы | ТОГДА 1 | ИНАЧЕ 0 | КОНЕЦ КАК ЕстьФайлы, | &ДопПоляШаблон КАК ДопПоляШаблон, | СправочникНоменклатура.Номинал КАК Номинал, | СправочникНоменклатура.Весовой КАК Весовой, | СправочникНоменклатура.ЗапретитьВводДробногоКоличества КАК ЗапретитьВводДробногоКоличества, | ВТ_ШК1.Штрихкод КАК Штрихкод |ИЗ | Справочник.Номенклатура КАК СправочникНоменклатура | {ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НаличиеФайлов КАК НаличиеФайлов | ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами} | ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ШК1 КАК ВТ_ШК1 | ПО СправочникНоменклатура.Ссылка = ВТ_ШК1.Номенклатура"; ВТТаблицаОстатков = "ВЫБРАТЬ РАЗРЕШЕННЫЕ | ОстаткиТоваров.Номенклатура КАК Номенклатура, | СУММА(ОстаткиТоваров.Количество) КАК Количество, | СУММА(ОстаткиТоваров.Резерв) КАК Резерв |ПОМЕСТИТЬ ОстаткиТоваров |ИЗ | РегистрСведений.ОстаткиТоваров КАК ОстаткиТоваров |ГДЕ | (&ВсеСклады | ИЛИ ОстаткиТоваров.СтруктурнаяЕдиница В (&Склад)) | И (&ВсеОрганизации | ИЛИ ОстаткиТоваров.Организация В (&Организация)) | И (&БезОтбора | ИЛИ ОстаткиТоваров.Характеристика В (&Характеристика)) | |СГРУППИРОВАТЬ ПО | ОстаткиТоваров.Номенклатура |; | |//////////////////////////////////////////////////////////////////////////////// |"; Если ОтборПоЦенам И ЦенаВСписке = 0 Тогда //Медленный способ с двумя левыми соединениями ТекстЗамены = " | ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.ЕдиницаИзмерения, СправочникНоменклатура.ЕдиницаИзмерения) КАК ЕдиницаИзмерения, | ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.ЕдиницаИзмерения.Коэффициент, 1) КАК Коэффициент, | ЗНАЧЕНИЕ(Справочник.Валюты.ПустаяСсылка) КАК ВалютаЦены, | ВЫРАЗИТЬ("""" КАК СТРОКА(3)) КАК ВалютаЦеныПредставление, | ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.Цена, 0) КАК Цена"; Если ТипЗнч(ОтборВидЦен) <> Тип("СправочникСсылка.ВидыЦенКонтрагентов") Тогда ВидЦенНесколькоВалютДляЦен = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ОтборВидЦен, "НесколькоВалютДляЦен"); КонецЕсли; Если Не ОтборПоВидуЦенКонтрагентов И ВидЦенНесколькоВалютДляЦен Тогда ТекстЗамены = СтрЗаменить(ТекстЗамены, "ЗНАЧЕНИЕ(Справочник.Валюты.ПустаяСсылка) КАК ВалютаЦены, | ВЫРАЗИТЬ("""" КАК СТРОКА(3)) КАК ВалютаЦеныПредставление,", ""); ТекстЗамены = ТекстЗамены + " , | ВЫБОР КОГДА ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.ВалютаЦены, 0) <> 0 | ТОГДА ЦеныНоменклатурыСрезПоследних.ВалютаЦены | ИНАЧЕ ЦеныНоменклатурыСрезПоследних.ВидЦен.ВалютаЦены | КОНЕЦ КАК ВалютаЦены, | ВЫБОР КОГДА ЦеныНоменклатурыСрезПоследних.ВидЦен.НесколькоВалютДляЦен | ТОГДА ЦеныНоменклатурыСрезПоследних.ВалютаЦены.СимвольноеПредставление | ИНАЧЕ """" | КОНЕЦ КАК ВалютаЦеныПредставление | "; КонецЕсли; Если ПоказыватьОстатки Тогда ТекстЗамены = ТекстЗамены + ", | ЕСТЬNULL(ОстаткиТоваров.Количество, 0) КАК КоличествоОстаток, | ЕСТЬNULL(ОстаткиТоваров.Резерв, 0) КАК Резерв"; Иначе ТекстЗамены = ТекстЗамены + ", | 0 КАК КоличествоОстаток, | 0 КАК Резерв"; КонецЕсли; ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ДопПоляШаблон КАК ДопПоляШаблон", ТекстЗамены); Если ПоказыватьОстатки Или ОтборПоКоличеству Тогда ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами", "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&ДатаСреза, Актуальность И ВидЦен = &ВидЦен И Характеристика = ЗНАЧЕНИЕ(Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка)) КАК ЦеныНоменклатурыСрезПоследних | ПО ЦеныНоменклатурыСрезПоследних.Номенклатура = СправочникНоменклатура.Ссылка | ЛЕВОЕ СОЕДИНЕНИЕ ОстаткиТоваров КАК ОстаткиТоваров | ПО СправочникНоменклатура.Ссылка = ОстаткиТоваров.Номенклатура"); Иначе ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами", "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&ДатаСреза, Актуальность И ВидЦен = &ВидЦен И Характеристика = ЗНАЧЕНИЕ(Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка)) КАК ЦеныНоменклатурыСрезПоследних | ПО ЦеныНоменклатурыСрезПоследних.Номенклатура = СправочникНоменклатура.Ссылка"); КонецЕсли; Если ПоказыватьОстатки Тогда ТекстЗапроса = ВТТаблицаОстатков + ТекстЗапроса; КонецЕсли; ИначеЕсли ПоказыватьЦены И ЦенаВСписке = 0 Тогда //без отбора по количеству Если Не ПоказыватьОстатки Тогда ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ДопПоляШаблон КАК ДопПоляШаблон", "ЕСТЬNULL(СправочникНоменклатура.ЕдиницаИзмерения, ЗНАЧЕНИЕ(Справочник.ЕдиницыИзмерения.ПустаяСсылка)) КАК ЕдиницаИзмерения, | 1 КАК Коэффициент, | 0 КАК Цена, | ЗНАЧЕНИЕ(Справочник.Валюты.ПустаяСсылка) КАК ВалютаЦены, | ВЫРАЗИТЬ("""" КАК СТРОКА(3)) КАК ВалютаЦеныПредставление, | 0 КАК КоличествоОстаток, | 0 КАК Резерв"); Иначе ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ДопПоляШаблон КАК ДопПоляШаблон", "ЕСТЬNULL(СправочникНоменклатура.ЕдиницаИзмерения, ЗНАЧЕНИЕ(Справочник.ЕдиницыИзмерения.ПустаяСсылка)) КАК ЕдиницаИзмерения, | 1 КАК Коэффициент, | ЗНАЧЕНИЕ(Справочник.Валюты.ПустаяСсылка) КАК ВалютаЦены, | ВЫРАЗИТЬ("""" КАК СТРОКА(3)) КАК ВалютаЦеныПредставление, | 0 КАК Цена, | ЕСТЬNULL(ОстаткиТоваров.Количество, 0) КАК КоличествоОстаток, | ЕСТЬNULL(ОстаткиТоваров.Резерв, 0) КАК Резерв"); ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами", "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами |ЛЕВОЕ СОЕДИНЕНИЕ ОстаткиТоваров КАК ОстаткиТоваров | ПО СправочникНоменклатура.Ссылка = ОстаткиТоваров.Номенклатура"); ТекстЗапроса = ВТТаблицаОстатков + ТекстЗапроса; КонецЕсли; ИначеЕсли ОтборПоКоличеству Тогда //без отбора по ценам ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ДопПоляШаблон КАК ДопПоляШаблон", "ЕСТЬNULL(СправочникНоменклатура.ЕдиницаИзмерения, Значение(Справочник.ЕдиницыИзмерения.ПустаяСсылка)) КАК ЕдиницаИзмерения, | 1 КАК Коэффициент, | 0 КАК Цена, | ЗНАЧЕНИЕ(Справочник.Валюты.ПустаяСсылка) КАК ВалютаЦены, | ВЫРАЗИТЬ("""" КАК СТРОКА(3)) КАК ВалютаЦеныПредставление, | ЕСТЬNULL(ОстаткиТоваров.Количество, 0) КАК КоличествоОстаток, | ЕСТЬNULL(ОстаткиТоваров.Резерв, 0) КАК Резерв"); ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами", "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами | ЛЕВОЕ СОЕДИНЕНИЕ ОстаткиТоваров КАК ОстаткиТоваров | ПО СправочникНоменклатура.Ссылка = ОстаткиТоваров.Номенклатура"); ТекстЗапроса = ВТТаблицаОстатков + ТекстЗапроса; ИначеЕсли ПоказыватьОстатки Тогда ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ДопПоляШаблон КАК ДопПоляШаблон", " ЕСТЬNULL(ОстаткиТоваров.Количество, 0) КАК КоличествоОстаток, | ЕСТЬNULL(ОстаткиТоваров.Резерв, 0) КАК Резерв, | ЕСТЬNULL(СправочникНоменклатура.ЕдиницаИзмерения, Значение(Справочник.ЕдиницыИзмерения.ПустаяСсылка)) КАК ЕдиницаИзмерения, | 1 КАК Коэффициент, | ЗНАЧЕНИЕ(Справочник.Валюты.ПустаяСсылка) КАК ВалютаЦены, | ВЫРАЗИТЬ("""" КАК СТРОКА(3)) КАК ВалютаЦеныПредставление, | 0 КАК Цена"); ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами", "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами | ЛЕВОЕ СОЕДИНЕНИЕ ОстаткиТоваров КАК ОстаткиТоваров | ПО СправочникНоменклатура.Ссылка = ОстаткиТоваров.Номенклатура"); ТекстЗапроса = ВТТаблицаОстатков + ТекстЗапроса; Иначе ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ДопПоляШаблон КАК ДопПоляШаблон", "ЕСТЬNULL(СправочникНоменклатура.ЕдиницаИзмерения, Значение(Справочник.ЕдиницыИзмерения.ПустаяСсылка)) КАК ЕдиницаИзмерения, | 1 КАК Коэффициент, | 0 КАК Цена, | ВЫРАЗИТЬ("""" КАК СТРОКА(3)) КАК ВалютаЦеныПредставление, | ЗНАЧЕНИЕ(Справочник.Валюты.ПустаяСсылка) КАК ВалютаЦены, | 0 КАК КоличествоОстаток, | 0 КАК Резерв"); КонецЕсли; Если ОтборОстатки = 1 И ПоказыватьОстатки Тогда ТекстЗапроса = ТекстЗапроса +" |ГДЕ | НЕ СправочникНоменклатура.ЭтоГруппа | И (СправочникНоменклатура.ЭтоНабор | ИЛИ СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Услуга) | ИЛИ СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Работа) | ИЛИ СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Операция) | ИЛИ (СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.ПодарочныйСертификат) | ИЛИ СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Запас)) | И (ЕСТЬNULL(ОстаткиТоваров.Количество, 0) > 0 | ИЛИ ЕСТЬNULL(ОстаткиТоваров.Резерв, 0) > 0)) |{ГДЕ | (СправочникНоменклатура.Ссылка В | (ВЫБРАТЬ РАЗЛИЧНЫЕ | СоставСегментаНоменклатуры.Номенклатура | ИЗ | РегистрСведений.СоставСегментаНоменклатуры КАК СоставСегментаНоменклатуры | ГДЕ | СоставСегментаНоменклатуры.Сегмент = &СегментНоменклатуры))}"; Если СписокОтбораХарактеристики.Количество() Тогда ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ЛЕВОЕ СОЕДИНЕНИЕ ОстаткиТоваров КАК ОстаткиТоваров", "Полное СОЕДИНЕНИЕ ОстаткиТоваров КАК ОстаткиТоваров") КонецЕсли; Иначе ТекстЗапроса = ТекстЗапроса +" |ГДЕ | НЕ СправочникНоменклатура.ЭтоГруппа |{ГДЕ | (СправочникНоменклатура.Ссылка В | (ВЫБРАТЬ РАЗЛИЧНЫЕ | СоставСегментаНоменклатуры.Номенклатура | ИЗ | РегистрСведений.СоставСегментаНоменклатуры КАК СоставСегментаНоменклатуры | ГДЕ | СоставСегментаНоменклатуры.Сегмент = &СегментНоменклатуры))}"; КонецЕсли; Если ОтборПоЦенам И ОтборПоВидуЦенКонтрагентов Тогда ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ЦеныНоменклатуры.СрезПоследних", "ЦеныНоменклатурыКонтрагентов.СрезПоследних"); ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ЦеныНоменклатурыСрезПоследних", "ЦеныНоменклатурыКонтрагентовСрезПоследних"); ТекстЗапроса = СтрЗаменить(ТекстЗапроса, " ВидЦен", " ВидЦенКонтрагента"); КонецЕсли; Если ЭтоПодбор Или РежимВыбора Тогда Если ЗначениеЗаполнено(ПериодЦен) И Не НачалоДня(ПериодЦен) = НачалоДня(ТекущаяДатаСеанса()) Тогда // Оставляем как есть Иначе ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ДатаСреза", ""); КонецЕсли; Иначе ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ДатаСреза", ""); КонецЕсли; ПараметрыСписка = ОбщегоНазначения.СтруктураСвойствДинамическогоСписка(); ПараметрыСписка.ТекстЗапроса = ТекстЗапроса; ОбщегоНазначения.УстановитьСвойстваДинамическогоСписка(Элементы.СписокЗапасы, ПараметрыСписка); КонецПроцедуры
Метод заключается в том, что я просто добавил дополнительную виртуальную таблицу и сделал соединение с основной. Добился результата как на рисунке 1.
"ВЫБРАТЬ | МАКСИМУМ(ШтрихкодыНоменклатуры.Штрихкод) КАК Штрихкод, | ШтрихкодыНоменклатуры.Номенклатура КАК Номенклатура |ПОМЕСТИТЬ ВТ_ШК1 |ИЗ | РегистрСведений.ШтрихкодыНоменклатуры КАК ШтрихкодыНоменклатуры | |СГРУППИРОВАТЬ ПО | ШтрихкодыНоменклатуры.Номенклатура | |ИНДЕКСИРОВАТЬ ПО | Номенклатура
Данный подход достаточно медленный, особенно если у вас огромный справочник номенклатуры и огромная таблица штрихкодов. Применять данный метод я бы сейчас наверное не стал, но хотя он является самым простым из всех. Идем далее....
2. Вложенные запросы
Возможно метод работы со вложенными запросами один из самых распространенных и я рекомендую его к использованию в 90% случаев. По скорости он достаточно приемлем. Хотя, по-моему мнению, в использовании методов "вложенных запросов" - в них достаточно легко запутаться.
Измененный текст запроса процедуры ПереопределитьТекстЗапросаСписокЗапасы выглядит вот так:
&НаСервере &Вместо("ПереопределитьТекстЗапросаСписокЗапасы") Процедура ШКН1_ПереопределитьТекстЗапросаСписокЗапасы() ОтборПоВидуЦенКонтрагентов = ТипЗнч(ОтборВидЦен) = Тип("СправочникСсылка.ВидыЦенКонтрагентов"); ВидЦенНесколькоВалютДляЦен = Ложь; ТекстЗапроса = "ВЫБРАТЬ РАЗРЕШЕННЫЕ | СправочникНоменклатура.Ссылка КАК Ссылка, | СправочникНоменклатура.Ссылка КАК Номенклатура, | СправочникНоменклатура.ПометкаУдаления КАК ПометкаУдаления, | ЛОЖЬ КАК ПрямойАналог, | СправочникНоменклатура.Родитель КАК Родитель, | СправочникНоменклатура.ЭтоГруппа КАК ЭтоГруппа, | СправочникНоменклатура.Код КАК Код, | СправочникНоменклатура.Наименование КАК Наименование, | СправочникНоменклатура.Артикул КАК Артикул, | СправочникНоменклатура.ДатаИзменения КАК ДатаИзменения, | СправочникНоменклатура.МетодОценки КАК МетодОценки, | ВЫРАЗИТЬ(СправочникНоменклатура.НаименованиеПолное КАК СТРОКА(1000)) КАК НаименованиеПолное, | СправочникНоменклатура.НаправлениеДеятельности КАК НаправлениеДеятельности, | СправочникНоменклатура.КатегорияНоменклатуры КАК КатегорияНоменклатуры, | СправочникНоменклатура.Поставщик КАК Поставщик, | СправочникНоменклатура.Склад КАК Склад, | СправочникНоменклатура.СпособПополнения КАК СпособПополнения, | СправочникНоменклатура.СрокПополнения КАК СрокПополнения, | СправочникНоменклатура.ВидСтавкиНДС КАК ВидСтавкиНДС, | ЗНАЧЕНИЕ(Справочник.СтавкиНДС.ПустаяСсылка) КАК СтавкаНДСНоменклатуры, | СправочникНоменклатура.СчетУчетаЗапасов КАК СчетУчетаЗапасов, | СправочникНоменклатура.СчетУчетаЗатрат КАК СчетУчетаЗатрат, | СправочникНоменклатура.СчетУчетаНДСПоПриобретеннымЦенностям КАК СчетУчетаНДСПоПриобретеннымЦенностям, | СправочникНоменклатура.СчетУчетаНДСПоРеализации КАК СчетУчетаНДСПоРеализации, | СправочникНоменклатура.ТипНоменклатуры КАК ТипНоменклатуры, | СправочникНоменклатура.Ячейка КАК Ячейка, | СправочникНоменклатура.ЦеноваяГруппа КАК ЦеноваяГруппа, | СправочникНоменклатура.ИспользоватьХарактеристики КАК ИспользоватьХарактеристики, | СправочникНоменклатура.ИспользоватьПартии КАК ИспользуетсяРезервирование, | СправочникНоменклатура.ИспользоватьПартии КАК ИспользоватьПартии, | СправочникНоменклатура.ЭтоНабор КАК ЭтоНабор, | СправочникНоменклатура.Недействителен КАК Недействителен, | СправочникНоменклатура.СрокИсполненияЗаказа КАК СрокИсполненияЗаказа, | СправочникНоменклатура.НормаВремени КАК НормаВремени, | СправочникНоменклатура.ФиксированнаяСтоимость КАК ФиксированнаяСтоимость, | СправочникНоменклатура.СтранаПроисхождения КАК СтранаПроисхождения, | СправочникНоменклатура.ВидАлкогольнойПродукции КАК ВидАлкогольнойПродукции, | СправочникНоменклатура.ИмпортнаяАлкогольнаяПродукция КАК ИмпортнаяАлкогольнаяПродукция, | СправочникНоменклатура.ПроизводительИмпортерАлкогольнойПродукции КАК ПроизводительИмпортерАлкогольнойПродукции, | СправочникНоменклатура.Вес КАК Вес, | СправочникНоменклатура.Объем КАК Объем, | СправочникНоменклатура.ОбъемДАЛ КАК ОбъемДАЛ, | СправочникНоменклатура.ИспользоватьСерииНоменклатуры КАК ИспользоватьСерииНоменклатуры, | СправочникНоменклатура.ГарантийныйСрок КАК ГарантийныйСрок, | СправочникНоменклатура.ПодконтрольнаяПродукцияВЕТИС КАК ПодконтрольнаяПродукцияВЕТИС, | СправочникНоменклатура.ВыписыватьГарантийныйТалон КАК ВыписыватьГарантийныйТалон, | ВЫБОР | КОГДА НЕ СправочникНоменклатура.ЭтоНабор | И НЕ(СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Операция) | ИЛИ СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.ВидРабот)) | ТОГДА 0 | ИНАЧЕ -1 | КОНЕЦ КАК КартинкаОстатки, | СправочникНоменклатура.ПроверятьЗаполнениеПартий КАК ПроверятьЗаполнениеПартий, | СправочникНоменклатура.ПроверятьЗаполнениеХарактеристики КАК ПроверятьЗаполнениеХарактеристики, | 0 КАК КартинкаКорзина, | ПОДСТРОКА(СправочникНоменклатура.Комментарий, 1, 1000) КАК Комментарий, | &Период КАК Период, | &ВидЦен КАК ВидЦен, | ВЫБОР | КОГДА СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Запас) | ТОГДА 0 | КОГДА СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.ПодарочныйСертификат) | ТОГДА 4 | ИНАЧЕ 2 | КОНЕЦ + ВЫБОР | КОГДА СправочникНоменклатура.ИспользоватьХарактеристики | ТОГДА 1 | ИНАЧЕ 0 | КОНЕЦ + ВЫБОР | КОГДА СправочникНоменклатура.ПометкаУдаления | ТОГДА 6 | ИНАЧЕ 0 | КОНЕЦ + ВЫБОР | КОГДА СправочникНоменклатура.ЭтоНабор | ТОГДА 12 | ИНАЧЕ 0 | КОНЕЦ КАК ВариантКартинки, | СправочникНоменклатура.Родитель КАК Группа, | ВЫБОР | КОГДА НаличиеФайлов.ЕстьФайлы ЕСТЬ NULL | ТОГДА 0 | КОГДА НаличиеФайлов.ЕстьФайлы | ТОГДА 1 | ИНАЧЕ 0 | КОНЕЦ КАК ЕстьФайлы, | &ДопПоляШаблон КАК ДопПоляШаблон, | СправочникНоменклатура.Номинал КАК Номинал, | СправочникНоменклатура.Весовой КАК Весовой, | СправочникНоменклатура.ЗапретитьВводДробногоКоличества КАК ЗапретитьВводДробногоКоличества, | ВЛ_ШК.Штрихкод КАК Штрихкод |ИЗ | Справочник.Номенклатура КАК СправочникНоменклатура | {ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НаличиеФайлов КАК НаличиеФайлов | ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами} | ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ | МАКСИМУМ(ШтрихкодыНоменклатуры.Штрихкод) КАК Штрихкод, | ШтрихкодыНоменклатуры.Номенклатура КАК Номенклатура | ИЗ | РегистрСведений.ШтрихкодыНоменклатуры КАК ШтрихкодыНоменклатуры | | СГРУППИРОВАТЬ ПО | ШтрихкодыНоменклатуры.Номенклатура) КАК ВЛ_ШК | ПО СправочникНоменклатура.Ссылка = ВЛ_ШК.Номенклатура"; ВТТаблицаОстатков = "ВЫБРАТЬ РАЗРЕШЕННЫЕ | ОстаткиТоваров.Номенклатура КАК Номенклатура, | СУММА(ОстаткиТоваров.Количество) КАК Количество, | СУММА(ОстаткиТоваров.Резерв) КАК Резерв |ПОМЕСТИТЬ ОстаткиТоваров |ИЗ | РегистрСведений.ОстаткиТоваров КАК ОстаткиТоваров |ГДЕ | (&ВсеСклады | ИЛИ ОстаткиТоваров.СтруктурнаяЕдиница В (&Склад)) | И (&ВсеОрганизации | ИЛИ ОстаткиТоваров.Организация В (&Организация)) | И (&БезОтбора | ИЛИ ОстаткиТоваров.Характеристика В (&Характеристика)) | |СГРУППИРОВАТЬ ПО | ОстаткиТоваров.Номенклатура |; | |//////////////////////////////////////////////////////////////////////////////// |"; Если ОтборПоЦенам И ЦенаВСписке = 0 Тогда //Медленный способ с двумя левыми соединениями ТекстЗамены = " | ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.ЕдиницаИзмерения, СправочникНоменклатура.ЕдиницаИзмерения) КАК ЕдиницаИзмерения, | ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.ЕдиницаИзмерения.Коэффициент, 1) КАК Коэффициент, | ЗНАЧЕНИЕ(Справочник.Валюты.ПустаяСсылка) КАК ВалютаЦены, | ВЫРАЗИТЬ("""" КАК СТРОКА(3)) КАК ВалютаЦеныПредставление, | ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.Цена, 0) КАК Цена"; Если ТипЗнч(ОтборВидЦен) <> Тип("СправочникСсылка.ВидыЦенКонтрагентов") Тогда ВидЦенНесколькоВалютДляЦен = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ОтборВидЦен, "НесколькоВалютДляЦен"); КонецЕсли; Если Не ОтборПоВидуЦенКонтрагентов И ВидЦенНесколькоВалютДляЦен Тогда ТекстЗамены = СтрЗаменить(ТекстЗамены, "ЗНАЧЕНИЕ(Справочник.Валюты.ПустаяСсылка) КАК ВалютаЦены, | ВЫРАЗИТЬ("""" КАК СТРОКА(3)) КАК ВалютаЦеныПредставление,", ""); ТекстЗамены = ТекстЗамены + " , | ВЫБОР КОГДА ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.ВалютаЦены, 0) <> 0 | ТОГДА ЦеныНоменклатурыСрезПоследних.ВалютаЦены | ИНАЧЕ ЦеныНоменклатурыСрезПоследних.ВидЦен.ВалютаЦены | КОНЕЦ КАК ВалютаЦены, | ВЫБОР КОГДА ЦеныНоменклатурыСрезПоследних.ВидЦен.НесколькоВалютДляЦен | ТОГДА ЦеныНоменклатурыСрезПоследних.ВалютаЦены.СимвольноеПредставление | ИНАЧЕ """" | КОНЕЦ КАК ВалютаЦеныПредставление | "; КонецЕсли; Если ПоказыватьОстатки Тогда ТекстЗамены = ТекстЗамены + ", | ЕСТЬNULL(ОстаткиТоваров.Количество, 0) КАК КоличествоОстаток, | ЕСТЬNULL(ОстаткиТоваров.Резерв, 0) КАК Резерв"; Иначе ТекстЗамены = ТекстЗамены + ", | 0 КАК КоличествоОстаток, | 0 КАК Резерв"; КонецЕсли; ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ДопПоляШаблон КАК ДопПоляШаблон", ТекстЗамены); Если ПоказыватьОстатки Или ОтборПоКоличеству Тогда ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами", "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&ДатаСреза, Актуальность И ВидЦен = &ВидЦен И Характеристика = ЗНАЧЕНИЕ(Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка)) КАК ЦеныНоменклатурыСрезПоследних | ПО ЦеныНоменклатурыСрезПоследних.Номенклатура = СправочникНоменклатура.Ссылка | ЛЕВОЕ СОЕДИНЕНИЕ ОстаткиТоваров КАК ОстаткиТоваров | ПО СправочникНоменклатура.Ссылка = ОстаткиТоваров.Номенклатура"); Иначе ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами", "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&ДатаСреза, Актуальность И ВидЦен = &ВидЦен И Характеристика = ЗНАЧЕНИЕ(Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка)) КАК ЦеныНоменклатурыСрезПоследних | ПО ЦеныНоменклатурыСрезПоследних.Номенклатура = СправочникНоменклатура.Ссылка"); КонецЕсли; Если ПоказыватьОстатки Тогда ТекстЗапроса = ВТТаблицаОстатков + ТекстЗапроса; КонецЕсли; ИначеЕсли ПоказыватьЦены И ЦенаВСписке = 0 Тогда //без отбора по количеству Если Не ПоказыватьОстатки Тогда ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ДопПоляШаблон КАК ДопПоляШаблон", "ЕСТЬNULL(СправочникНоменклатура.ЕдиницаИзмерения, ЗНАЧЕНИЕ(Справочник.ЕдиницыИзмерения.ПустаяСсылка)) КАК ЕдиницаИзмерения, | 1 КАК Коэффициент, | 0 КАК Цена, | ЗНАЧЕНИЕ(Справочник.Валюты.ПустаяСсылка) КАК ВалютаЦены, | ВЫРАЗИТЬ("""" КАК СТРОКА(3)) КАК ВалютаЦеныПредставление, | 0 КАК КоличествоОстаток, | 0 КАК Резерв"); Иначе ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ДопПоляШаблон КАК ДопПоляШаблон", "ЕСТЬNULL(СправочникНоменклатура.ЕдиницаИзмерения, ЗНАЧЕНИЕ(Справочник.ЕдиницыИзмерения.ПустаяСсылка)) КАК ЕдиницаИзмерения, | 1 КАК Коэффициент, | ЗНАЧЕНИЕ(Справочник.Валюты.ПустаяСсылка) КАК ВалютаЦены, | ВЫРАЗИТЬ("""" КАК СТРОКА(3)) КАК ВалютаЦеныПредставление, | 0 КАК Цена, | ЕСТЬNULL(ОстаткиТоваров.Количество, 0) КАК КоличествоОстаток, | ЕСТЬNULL(ОстаткиТоваров.Резерв, 0) КАК Резерв"); ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами", "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами |ЛЕВОЕ СОЕДИНЕНИЕ ОстаткиТоваров КАК ОстаткиТоваров | ПО СправочникНоменклатура.Ссылка = ОстаткиТоваров.Номенклатура"); ТекстЗапроса = ВТТаблицаОстатков + ТекстЗапроса; КонецЕсли; ИначеЕсли ОтборПоКоличеству Тогда //без отбора по ценам ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ДопПоляШаблон КАК ДопПоляШаблон", "ЕСТЬNULL(СправочникНоменклатура.ЕдиницаИзмерения, Значение(Справочник.ЕдиницыИзмерения.ПустаяСсылка)) КАК ЕдиницаИзмерения, | 1 КАК Коэффициент, | 0 КАК Цена, | ЗНАЧЕНИЕ(Справочник.Валюты.ПустаяСсылка) КАК ВалютаЦены, | ВЫРАЗИТЬ("""" КАК СТРОКА(3)) КАК ВалютаЦеныПредставление, | ЕСТЬNULL(ОстаткиТоваров.Количество, 0) КАК КоличествоОстаток, | ЕСТЬNULL(ОстаткиТоваров.Резерв, 0) КАК Резерв"); ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами", "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами | ЛЕВОЕ СОЕДИНЕНИЕ ОстаткиТоваров КАК ОстаткиТоваров | ПО СправочникНоменклатура.Ссылка = ОстаткиТоваров.Номенклатура"); ТекстЗапроса = ВТТаблицаОстатков + ТекстЗапроса; ИначеЕсли ПоказыватьОстатки Тогда ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ДопПоляШаблон КАК ДопПоляШаблон", " ЕСТЬNULL(ОстаткиТоваров.Количество, 0) КАК КоличествоОстаток, | ЕСТЬNULL(ОстаткиТоваров.Резерв, 0) КАК Резерв, | ЕСТЬNULL(СправочникНоменклатура.ЕдиницаИзмерения, Значение(Справочник.ЕдиницыИзмерения.ПустаяСсылка)) КАК ЕдиницаИзмерения, | 1 КАК Коэффициент, | ЗНАЧЕНИЕ(Справочник.Валюты.ПустаяСсылка) КАК ВалютаЦены, | ВЫРАЗИТЬ("""" КАК СТРОКА(3)) КАК ВалютаЦеныПредставление, | 0 КАК Цена"); ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами", "ПО СправочникНоменклатура.Ссылка = НаличиеФайлов.ОбъектСФайлами | ЛЕВОЕ СОЕДИНЕНИЕ ОстаткиТоваров КАК ОстаткиТоваров | ПО СправочникНоменклатура.Ссылка = ОстаткиТоваров.Номенклатура"); ТекстЗапроса = ВТТаблицаОстатков + ТекстЗапроса; Иначе ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ДопПоляШаблон КАК ДопПоляШаблон", "ЕСТЬNULL(СправочникНоменклатура.ЕдиницаИзмерения, Значение(Справочник.ЕдиницыИзмерения.ПустаяСсылка)) КАК ЕдиницаИзмерения, | 1 КАК Коэффициент, | 0 КАК Цена, | ВЫРАЗИТЬ("""" КАК СТРОКА(3)) КАК ВалютаЦеныПредставление, | ЗНАЧЕНИЕ(Справочник.Валюты.ПустаяСсылка) КАК ВалютаЦены, | 0 КАК КоличествоОстаток, | 0 КАК Резерв"); КонецЕсли; Если ОтборОстатки = 1 И ПоказыватьОстатки Тогда ТекстЗапроса = ТекстЗапроса +" |ГДЕ | НЕ СправочникНоменклатура.ЭтоГруппа | И (СправочникНоменклатура.ЭтоНабор | ИЛИ СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Услуга) | ИЛИ СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Работа) | ИЛИ СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Операция) | ИЛИ (СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.ПодарочныйСертификат) | ИЛИ СправочникНоменклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Запас)) | И (ЕСТЬNULL(ОстаткиТоваров.Количество, 0) > 0 | ИЛИ ЕСТЬNULL(ОстаткиТоваров.Резерв, 0) > 0)) |{ГДЕ | (СправочникНоменклатура.Ссылка В | (ВЫБРАТЬ РАЗЛИЧНЫЕ | СоставСегментаНоменклатуры.Номенклатура | ИЗ | РегистрСведений.СоставСегментаНоменклатуры КАК СоставСегментаНоменклатуры | ГДЕ | СоставСегментаНоменклатуры.Сегмент = &СегментНоменклатуры))}"; Если СписокОтбораХарактеристики.Количество() Тогда ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ЛЕВОЕ СОЕДИНЕНИЕ ОстаткиТоваров КАК ОстаткиТоваров", "Полное СОЕДИНЕНИЕ ОстаткиТоваров КАК ОстаткиТоваров") КонецЕсли; Иначе ТекстЗапроса = ТекстЗапроса +" |ГДЕ | НЕ СправочникНоменклатура.ЭтоГруппа |{ГДЕ | (СправочникНоменклатура.Ссылка В | (ВЫБРАТЬ РАЗЛИЧНЫЕ | СоставСегментаНоменклатуры.Номенклатура | ИЗ | РегистрСведений.СоставСегментаНоменклатуры КАК СоставСегментаНоменклатуры | ГДЕ | СоставСегментаНоменклатуры.Сегмент = &СегментНоменклатуры))}"; КонецЕсли; Если ОтборПоЦенам И ОтборПоВидуЦенКонтрагентов Тогда ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ЦеныНоменклатуры.СрезПоследних", "ЦеныНоменклатурыКонтрагентов.СрезПоследних"); ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ЦеныНоменклатурыСрезПоследних", "ЦеныНоменклатурыКонтрагентовСрезПоследних"); ТекстЗапроса = СтрЗаменить(ТекстЗапроса, " ВидЦен", " ВидЦенКонтрагента"); КонецЕсли; Если ЭтоПодбор Или РежимВыбора Тогда Если ЗначениеЗаполнено(ПериодЦен) И Не НачалоДня(ПериодЦен) = НачалоДня(ТекущаяДатаСеанса()) Тогда // Оставляем как есть Иначе ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ДатаСреза", ""); КонецЕсли; Иначе ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ДатаСреза", ""); КонецЕсли; ПараметрыСписка = ОбщегоНазначения.СтруктураСвойствДинамическогоСписка(); ПараметрыСписка.ТекстЗапроса = ТекстЗапроса; ОбщегоНазначения.УстановитьСвойстваДинамическогоСписка(Элементы.СписокЗапасы, ПараметрыСписка); КонецПроцедуры
3. Постобработка "ПриПолученииДанныхНаСервере"
Вероятно самый тормозной способ получения данных как на рисунке 1 - это постобработка динамического списка "ПриПолученииДанныхНаСервере". В рабочем контуре не рекомендую использовать ну или в крайнем случае... Способ достаточно "молодой" - ему где-то 5-6 лет думаю. Заключается в следующем:
На динамический список СписокЗаказы привязывается событие ПриПолученииДанныхНаСервере, выглядит это вот так:

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



