Здравствуйте. Справочник номенклатура, в форму списка нужно подтянуть некоторые данные из последней реализации, в которой есть номенклатура. Составил запрос, но при открытии формы списка все зависает из за большого количества данных. Подскажите, пожалуйста, как можно оптимизировать запрос?
ВЫБРАТЬ
СпрНоменклатура.Ссылка КАК Ссылка,
СпрНоменклатура.Код КАК Код,
СпрНоменклатура.Наименование КАК Наименование,
СпрНоменклатура.Артикул КАК Артикул,
СпрНоменклатура.ВидНоменклатуры КАК ВидНоменклатуры,
СпрНоменклатура.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
СпрНоменклатура.СтавкаНДС КАК СтавкаНДС,
СпрНоменклатура.Родитель,
ВЫБОР
КОГДА СпрНоменклатура.ЕстьТоварыДругогоКачества
ТОГДА 4 + ВЫБОР
КОГДА СпрНоменклатура.ПометкаУдаления
ТОГДА 1
ИНАЧЕ 0
КОНЕЦ + ВЫБОР
КОГДА СпрНоменклатура.ИспользованиеХарактеристик = ЗНАЧЕНИЕ(Перечисление.ВариантыИспользованияХарактеристикНоменклатуры.НеИспользовать)
ТОГДА 0
ИНАЧЕ 2
КОНЕЦ
ИНАЧЕ ВЫБОР
КОГДА СпрНоменклатура.ПометкаУдаления
ТОГДА 1
ИНАЧЕ 0
КОНЕЦ + ВЫБОР
КОГДА СпрНоменклатура.ИспользованиеХарактеристик = ЗНАЧЕНИЕ(Перечисление.ВариантыИспользованияХарактеристикНоменклатуры.НеИспользовать)
ТОГДА 0
ИНАЧЕ 2
КОНЕЦ
КОНЕЦ КАК ИндексКартинки,
РеализацияТоваровУслугТовары.НомерУпаковки КАК НомерУпаковки
ИЗ
Справочник.Номенклатура КАК СпрНоменклатура
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
ПО (РеализацияТоваровУслугТовары.Номенклатура = СпрНоменклатура.Ссылка)
ГДЕ
НЕ СпрНоменклатура.ЭтоГруппа
{ГДЕ
(СпрНоменклатура.Ссылка В
(ВЫБРАТЬ
Сегменты.Номенклатура
ИЗ
РегистрСведений.НоменклатураСегмента КАК Сегменты
ГДЕ
Сегменты.Сегмент = &СегментНоменклатуры))}
И РеализацияТоваровУслугТовары.НомерУпаковки В
(ВЫБРАТЬ ПЕРВЫЕ 1
РеализацияТоваровУслугТовары.НомерУпаковки
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
УПОРЯДОЧИТЬ ПО
РеализацияТоваровУслугТовары.Ссылка.Дата УБЫВ)
(29) спасибо. Сделал с левым соединением, добавил условия на дату в запрос и убрал группировку по упаковкам, так как из за них дублирование было. И заработало.
(1) Использовать событие ПриПолученииДанных динамического списка
в примере выводятся цены последней и предпоследней поставки
&НаСервереБезКонтекста
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ПоступлениеТоваровТовары.Номенклатура.Код КАК НоменклатураКод,
| ПоступлениеТоваровТовары.Номенклатура КАК Номенклатура,
| ПоступлениеТоваровТовары.Ссылка.Дата КАК Дата,
| ПоступлениеТоваровТовары.Цена КАК Цена,
| ПоступлениеТоваровТовары.Ссылка.Контрагент КАК Контрагент
|ИЗ
| Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровТовары
|ГДЕ
| ПоступлениеТоваровТовары.Ссылка.Проведен
| И ПоступлениеТоваровТовары.Номенклатура В (&СписокНоменклатуры)
|
|УПОРЯДОЧИТЬ ПО
| Номенклатура,
| Дата УБЫВ
|ИТОГИ ПО
| Номенклатура";
Запрос.УстановитьПараметр("СписокНоменклатуры", Строки.ПолучитьКлючи());
РезультатЗапроса = Запрос.Выполнить();
ВыборкаНоменклатура = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаНоменклатура.Следующий() Цикл
ВыборкаДетальныеЗаписи = ВыборкаНоменклатура.Выбрать();
Сч=1;
СтрокаСписка=Строки[ВыборкаНоменклатура.Номенклатура];
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Если Сч=1 Тогда
Если СтрокаСписка.Данные.Свойство("ЦенаПоследнейПоставки") Тогда
СтрокаСписка.Данные.ЦенаПоследнейПоставки=ВыборкаДетальныеЗаписи.Цена;
КонецЕсли;
ИначеЕсли Сч=2 Тогда
Если СтрокаСписка.Данные.Свойство("ЦенаПредПоследнейПоставки") Тогда
СтрокаСписка.Данные.ЦенаПредПоследнейПоставки=ВыборкаДетальныеЗаписи.Цена;
КонецЕсли;
Иначе
Прервать;
КонецЕсли;
Сч=Сч+1;
КонецЦикла;
Если СтрокаСписка.Данные.Свойство("ЦенаПоследнейПоставки") И
СтрокаСписка.Данные.Свойство("Цена") И
СтрокаСписка.Данные.Свойство("Процент") Тогда
ЦенаЗакупки=СтрокаСписка.Данные.ЦенаПоследнейПоставки;
Цена=СтрокаСписка.Данные.Цена;
Если ЦенаЗакупки<>0 И Цена<>0 Тогда
СтрокаСписка.Данные.Процент=Окр(Цена/ЦенаЗакупки*100-100,2);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Использовать событие ПриПолученииДанных динамического списка
спасибо. Попробовал, создал у табличной части данную процедуру,но отладкой в нее не заходит, проверить не могу как работает. Подскажите, пожалуйста, что не так сделал?
(8) можно попробовать переместиться по списку в начало или в конец, процедура работает пакетно для строк, если строк немного, то вероятно количество вызовов будет минимально, или она не сработает
(1) Вот в этом куске - видимо нужно наложить фильтр ГДЕ
(ВЫБРАТЬ ПЕРВЫЕ 1
РеализацияТоваровУслугТовары.НомерУпаковки
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
УПОРЯДОЧИТЬ ПО
РеализацияТоваровУслугТовары.Ссылка.Дата УБЫВ)
(11) кстати: почему используются { } в тексте запроса ? (Скопировали запрос из отчета ?)
Часть запроса в фигурных скобках игнорируется - поэтому и тормоза !
Отредактируйте текст запроса, (уберите { } ) Попробуйте, затем пробуйте наложить фильтр на выборку (как я писал выше)
P.S. хотя нет - это не поможет; сделайте по рекомендации polax
Никаких соединений с реализацией. Прав в (2) ПриПолученииДанныхНаСервере. В основной запрос добавляешь 0 КАК НомерУпаковки. Все. Больше ничего. Выводишь поле НомерУпаковки в нужное место на форме. В СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
используй Сроки (посмотри в отладчике значение, разберешься) и заполняй нужными значениями поле НомерУпаковки (запрос или любым способом).
Плюсы: Не нагружается динамический список, скорость его вывода не меняется. Заполнение ТОЛЬКО видимых строк номером упаковки почти не тормозит работу
Минусы: По полю Номер упаковки нельзя сделать сортировку, упорядочивание, отбор. Но оно того стоит
вот запрос без моих изменений, что изначально был. Так же фигурные скобки имеются в запросе, при этом без тормозов все работает.
ВЫБРАТЬ
СпрНоменклатура.Ссылка КАК Ссылка,
СпрНоменклатура.Код КАК Код,
СпрНоменклатура.Наименование КАК Наименование,
СпрНоменклатура.Артикул КАК Артикул,
СпрНоменклатура.ВидНоменклатуры КАК ВидНоменклатуры,
СпрНоменклатура.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
СпрНоменклатура.СтавкаНДС КАК СтавкаНДС,
СпрНоменклатура.Родитель,
ВЫБОР
КОГДА СпрНоменклатура.ЕстьТоварыДругогоКачества
ТОГДА 4 + ВЫБОР
КОГДА СпрНоменклатура.ПометкаУдаления
ТОГДА 1
ИНАЧЕ 0
КОНЕЦ + ВЫБОР
КОГДА СпрНоменклатура.ИспользованиеХарактеристик = ЗНАЧЕНИЕ(Перечисление.ВариантыИспользованияХарактеристикНоменклатуры.НеИспользовать)
ТОГДА 0
ИНАЧЕ 2
КОНЕЦ
ИНАЧЕ ВЫБОР
КОГДА СпрНоменклатура.ПометкаУдаления
ТОГДА 1
ИНАЧЕ 0
КОНЕЦ
+ ВЫБОР
КОГДА СпрНоменклатура.ИспользованиеХарактеристик = ЗНАЧЕНИЕ(Перечисление.ВариантыИспользованияХарактеристикНоменклатуры.НеИспользовать)
ТОГДА 0
ИНАЧЕ 2
КОНЕЦ
КОНЕЦ КАК ИндексКартинки
ИЗ
Справочник.Номенклатура КАК СпрНоменклатура
ГДЕ
НЕ СпрНоменклатура.ЭтоГруппа
{ГДЕ
(СпрНоменклатура.Ссылка В
(ВЫБРАТЬ
Сегменты.Номенклатура
ИЗ
РегистрСведений.НоменклатураСегмента КАК Сегменты
ГДЕ
Сегменты.Сегмент = &СегментНоменклатуры))}
(16) Уточникте такой момент: Вам нужно РеализацияТоваровУслугТовары.НомерУпаковки из последнего по дате документа (самого свежего) или максимальный номер упаковки в которой была номенклатура ?
(25) Вот где собака порылась.! ))))
Событие ПриПолученииДанныхНаСервере работает начиная с версии 8.3.10. Платформа-то у тебя соответствует, а вот режим совместимости 8.3.7 ниже требуемого, поэтому и не работает событие. Или меняй режим совместимости или этот способ тебе не подходит
(19) составил запрос, логика по идее как в вашем примере, но ошибка вылезает
ВЫБРАТЬ
СпрНоменклатура.Ссылка КАК Ссылка,
СпрНоменклатура.Код КАК Код,
СпрНоменклатура.Наименование КАК Наименование,
СпрНоменклатура.Артикул КАК Артикул,
СпрНоменклатура.ВидНоменклатуры КАК ВидНоменклатуры,
СпрНоменклатура.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
СпрНоменклатура.СтавкаНДС КАК СтавкаНДС,
СпрНоменклатура.Родитель,
ВЫБОР
КОГДА СпрНоменклатура.ЕстьТоварыДругогоКачества
ТОГДА 4 + ВЫБОР
КОГДА СпрНоменклатура.ПометкаУдаления
ТОГДА 1
ИНАЧЕ 0
КОНЕЦ + ВЫБОР
КОГДА СпрНоменклатура.ИспользованиеХарактеристик = ЗНАЧЕНИЕ(Перечисление.ВариантыИспользованияХарактеристикНоменклатуры.НеИспользовать)
ТОГДА 0
ИНАЧЕ 2
КОНЕЦ
ИНАЧЕ ВЫБОР
КОГДА СпрНоменклатура.ПометкаУдаления
ТОГДА 1
ИНАЧЕ 0
КОНЕЦ + ВЫБОР
КОГДА СпрНоменклатура.ИспользованиеХарактеристик = ЗНАЧЕНИЕ(Перечисление.ВариантыИспользованияХарактеристикНоменклатуры.НеИспользовать)
ТОГДА 0
ИНАЧЕ 2
КОНЕЦ
КОНЕЦ КАК ИндексКартинки,
РеализацияТоваровУслугТовары.НомерУпаковки
ИЗ
Справочник.Номенклатура КАК СпрНоменклатура
ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
РеализацияТоваровУслугТовары.НомерУпаковки КАК НомерУпаковки,
РеализацияТоваровУслугТовары.Номенклатура КАК Номенклатура,
МАКСИМУМ(РеализацияТоваровУслугТовары.Ссылка.Дата) КАК ДатаДокумента
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
МАКСИМУМ(РеализацияТоваровУслугТовары.НомерУпаковки) КАК НомерУпаковки,
РеализацияТоваровУслугТовары.Номенклатура КАК Номенклатура,
РеализацияТоваровУслугТовары.Ссылка.Дата КАК ДатаДокумента
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
СГРУППИРОВАТЬ ПО
РеализацияТоваровУслугТовары.Ссылка.Дата,
РеализацияТоваровУслугТовары.Номенклатура) КАК РеализацияТоваровТовары
ПО РеализацияТоваровТовары.Номенклатура = РеализацияТоваровУслугТовары.Номенклатура
И РеализацияТоваровТовары.ДатаДокумента = РеализацияТоваровУслугТовары.Ссылка.Дата
И РеализацияТоваровТовары.НомерУпаковки = РеализацияТоваровУслугТовары.НомерУпаковки
СГРУППИРОВАТЬ ПО
РеализацияТоваровУслугТовары.Номенклатура,
РеализацияТоваровУслугТовары.НомерУпаковки) КАК РеализацияТоваровУслугТовары
ПО РеализацияТоваровУслугТовары.Номенклатура = СпрНоменклатура.Ссылка
ГДЕ
НЕ СпрНоменклатура.ЭтоГруппа
{ГДЕ
(СпрНоменклатура.Ссылка В
(ВЫБРАТЬ
Сегменты.Номенклатура
ИЗ
РегистрСведений.НоменклатураСегмента КАК Сегменты
ГДЕ
Сегменты.Сегмент = &СегментНоменклатуры))}
ИЗ
Справочник.Номенклатура КАК СпрНоменклатура
ВНУТРЕННЕЕ СОЕДИНЕНИЕ
// тут должно быть ЛЕВОЕ СОЕДИНЕНИЕ иначе в списке останутся только та Номенклатура, которая есть в Реализации
ПО РеализацияТоваровТовары.Номенклатура = РеализацияТоваровУслугТовары.Номенклатура
И РеализацияТоваровТовары.ДатаДокумента = РеализацияТоваровУслугТовары.Ссылка.Дата
И РеализацияТоваровТовары.НомерУпаковки = РеализацияТоваровУслугТовары.НомерУпаковки
Для большего ускорения желательно наложить фильтр ГДЕ на РеализацияТоваровТовары, РеализацияТоваровУслугТовары по дате (выбирать реализации не за всё время а с определенной даты)
Проверьте правильность подзапроса, вставьте его в консоль запросов и выполните; Может ошибка где то еще;
(29) спасибо. Сделал с левым соединением, добавил условия на дату в запрос и убрал группировку по упаковкам, так как из за них дублирование было. И заработало.