Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Получение элемента с максимальной датой с подчиненного справочника
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 > Программисту > Программирование в 1С Предприятие 8.2 > Программирование обычных форм 1С 8.2 и не интерфейсной логики
Zlyukka
Получение элемента с максимальной датой с подчиненного справочника
Проблема в следующем есть два справочника 1-Товар является Родителем для справочника 2-Серия. Задача получить для товаров последнюю серию(В Серии содержатся различные данные типа цены ставки НДС и т.д.). Сейчас данная проблема решается следующим путем
Запрос=Новый Запрос;
Запрос.Текст="ВЫБРАТЬ
             |    Серии.Владелец КАК Владелец,
             |    Серии.ДатаСозд КАК ДатаСозд,
             |    Серии.Ссылка КАК Серия
             |ИЗ
             |    Справочник.Серии КАК Серии
             |        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Товары КАК Товары
             |        ПО Серии.Владелец = Товары.Ссылка
             |ГДЕ
             |    Товары.Завод = &Завод
             |
             |УПОРЯДОЧИТЬ ПО
             |    ДатаСозд УБЫВ
             |ИТОГИ ПО
             |    Владелец";
ВладВыб=Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам "Владелец");
ПоследняяСерия=Неопределено;
Пока ВладВыб.Следующий() Цикл
    СерВыб=ВладВыб.Выбрать();
    Пока СерВыб.Сбросить() Цикл
         ПоследняяСерия=Выб.Серия; //-Ура вот она серия
        Прервать;
    КонецЦикла;
КонецЦикла

Вопрос собственно вот в чем заключается. Как получить эти данные прямо в запросе. Заранее спасибо
pablo
Запрос.Текст="ВЫБРАТЬ
          
             |    Макс(Серии.ДатаСозд) КАК ДатаСозд,
             |    Серии.Ссылка КАК Серия
             |ИЗ
             |    Справочник.Серии КАК Серии
             |        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Товары КАК Товары
             |        ПО Серии.Владелец = Товары.Ссылка
             |ГДЕ
             |    Товары.Завод = &Завод
             |сгруппировать по Серия
             |УПОРЯДОЧИТЬ ПО
             |    ДатаСозд УБЫВ
             |";
Zlyukka
Цитата(pablo @ 12.08.14, 10:11) необходимо зарегистрироваться для просмотра ссылки
Запрос.Текст="ВЫБРАТЬ
          
             |    Макс(Серии.ДатаСозд) КАК ДатаСозд,
             |    Серии.Ссылка КАК Серия
             |ИЗ
             |    Справочник.Серии КАК Серии
             |        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Товары КАК Товары
             |        ПО Серии.Владелец = Товары.Ссылка
             |ГДЕ
             |    Товары.Завод = &Завод
             |сгруппировать по Серия
             |УПОРЯДОЧИТЬ ПО
             |    ДатаСозд УБЫВ
             |";


Вот что вернуло
ДатаСозд Ссылка
10.07.2014 0:00:00
10.07.2014 0:00:00 7351425
10.07.2014 0:00:00 7351425
31.01.2014 0:00:00 7351447A
Мне надо что б вернуло дату и ссылку прямо в запросе. А так мне придётся снова получать первую запись в цикле. Мне хотелось бы использовать запрос как подчиненный
pablo
Эту строчку оставили на месте?
ВладВыб=Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам,"Владелец");

или меняли ее?
Zlyukka
Я проверял в консоли запросов. значение в группировке владелец NULL

Да и причем тут владелец мне нужно получить Ссылку на серию с последней датой создания . Задача звучит как получить приходную цену последних поставок. Цена закупочная находится в серии.
pablo
Все дело в том, что группировки в консоли запросов быть не должно, если Вы используете мой запрос без изменения.
alex040269
ВЫБРАТЬ * ИЗ 
(ВЫБРАТЬ Владелец,Максимум(ДатаСозд)
    ИЗ Справочник.Серии
СГРУППИРОВАТЬ ПО
Владелец ) КАК Серии
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Товары КАК Товар
        ПО Серии.Владелец = Товары.Ссылка


Запрос должен выбрать товары с последней серией.
Это нужно?
Zlyukka
Цитата(pablo @ 12.08.14, 11:58) необходимо зарегистрироваться для просмотра ссылки
Все дело в том, что группировки в консоли запросов быть не должно, если Вы используете мой запрос без изменения.

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

Но в таком варианте нет группировки Владелец
за что получаем

{Отчет.а7.Форма.ФормаОтчета.Форма(25)}: Ошибка при вызове метода контекста (Выбрать)
ВыбМаксСер=Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Владелец");
по причине:
Измерение не найдено "Владелец"


Цитата(alex040269 @ 12.08.14, 12:13) необходимо зарегистрироваться для просмотра ссылки
ВЫБРАТЬ * ИЗ 
(ВЫБРАТЬ Владелец,Максимум(ДатаСозд)
    ИЗ Справочник.Серии
СГРУППИРОВАТЬ ПО
Владелец ) КАК Серии
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Товары КАК Товар
        ПО Серии.Владелец = Товары.Ссылка


Запрос должен выбрать товары с последней серией.
Это нужно?


Я же писал мне ссылку на серию с последней датой нужно получить. А не дату последнего прихода
alex040269
ВЫБРАТЬ Владелец, Серии.Ссылка ИЗ 
(ВЫБРАТЬ Владелец,Максимум(ДатаСозд)
    ИЗ Справочник.Серии
СГРУППИРОВАТЬ ПО
Владелец ) КАК ВЗСерии
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Серии КАК Серии
        ПО ВЗСерии.Владелец = Серии.Владелец
        И ВЗСерии.ДатаСозд  = Серии.ДатаСозд

Товар и Ссылка на последнюю серию.
pablo
Неправильно Вы меня поняли.
Запрос.Текст="ВЫБРАТЬ
             |    МАКСИМУМ(Серии.ДатаСозд) КАК ДатаСозд,
             |    Серии.Ссылка КАК Серия
             |ИЗ
             |    Справочник.Серии КАК Серии
             |        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Товары КАК Товары
             |        ПО Серии.Владелец = Товары.Ссылка
             |
             |СГРУППИРОВАТЬ ПО
             |    Серии.Ссылка
             |
             |УПОРЯДОЧИТЬ ПО
             |    ДатаСозд УБЫВ";
ВыбМаксСер=Запрос.Выполнить().Выбрать();
Пока ВыбМаксСер.Следующий() Цикл
    Сообщить("Сер-"+ВыбМаксСер.Серия+" Товар-"+ВыбМаксСер.Серия.Владелец);    
КонецЦикла;


А еще можно добавить в конец первой строки ПЕРВЫЕ 1
Zlyukka
Цитата(pablo @ 12.08.14, 11:24) необходимо зарегистрироваться для просмотра ссылки
Эту строчку оставили на месте?
ВладВыб=Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам,"Владелец");

или меняли ее?

Возможно smile.gif Но все равно это не то. Да и если допилить туда первые оно вернет одну строку. alex040269 Вам спасибо почти то что надо.
Kashemir
ВЫБРАТЬ
    Товары.Ссылка КАК Владелец,
    Серии.Ссылка,
    Серии.ДатаСозд
ИЗ
    Справочник.Товары КАК Товары
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Серии КАК Серии
            ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
                МАКСИМУМ(Серии.ДатаСозд) КАК ДатаСозд,
                Серии.Владелец КАК Владелец
            ИЗ
                Справочник.Серии КАК Серии
            
            СГРУППИРОВАТЬ ПО
                Серии.Владелец) КАК ВложенныйЗапрос
            ПО Серии.Владелец = ВложенныйЗапрос.Владелец
                И Серии.ДатаСозд = ВложенныйЗапрос.ДатаСозд
        ПО (Серии.Владелец = Товары.Ссылка)
ГДЕ
    Товары.Завод = &Завод



 ! 

Правила, п.12
 
Kashemir
Zlyukka приведенный листинг запроса в необходимо зарегистрироваться для просмотра ссылки просто ужастен.

Первое, поскольку очевидно что знания запросов не слишком глубокие - предлагаю взять за правило все использованные таблицы предварительно выносить во временные таблицы (кроме виртуальных таблиц регистров). Это сильно облегчит жизнь построителю планов запросов SQL.

Во вторых, данный запрос не выполняет поставленную задачу - при обращении к виртуальной таблице остатков и оборотов в середине отчетного периода, при отсутствии оборота за день, записей в пределах данного дня по остаткам не будет.
Допустим если 1.08 числа остатки были 200, а 2.08 не было оборота, то записи в результатах обращения к виртуальной таблице с остатком 200 на 2.08 тоже не будет (если отчет допустим строить за 01.08 - 03.08).

Ну и третье, использование менеджера временных таблиц здесь совершенно неуместено и никак не влияет на запрос.

Кстати больше всего данный запрос грузит скорее всего безумное размножение неотфильтрованных результатов соединений * количество записей временной таблицы "ДНИ".

Zlyukka
Благодарю за критику, в дальнейшем буду учитывать Ваши замечания по оптимизации. Что же до запроса - проверил остатки выводит корректно даже по дням без движений.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.