8.х Отбор по множественному значению измерения в регистре сведений.

Тема в разделе "Конфигурирование на платформе "1С:Предприятие 8"", создана пользователем Steel Rain, 18 ноя 2014.

  1. TopicStarter Overlay
    Steel Rain
    Offline

    Steel Rain Опытный в 1С

    Регистрация:
    29 сен 2006
    Сообщения:
    408
    Симпатии:
    2
    Баллы:
    29
    Доброго всем времени суток.

    Платформа 8.2, Конфигурация УТ 10.3
    Имеется независимый периодический регистр сведений СпециальныеЦены с измерениями
    ГоловнойКонтрагент, Торговая точка - Справочник.Контрагенты и Номенклатура - Справочник.Номенклатура, ресурсами Цена - Число, ЕдиницаИзмерения - Справочник.ЕдиницыИзмерения и Валюта - Справочник.Валюты.
    Требуется получить из этого регистра список торговых точек у которых присутствуют все позиции из заданного списка номенклатуры, на дату. Т.е. на форме есть некий заполненный список номенклатуры "Товары", по нему нужно заполнить список "Котрагенты".

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

    К примеру:
    Имеется Контр1 и Контр2, на текущую дату для Контр1 в регистре две записи Тов1 и Тов2, у Контр2 также две записи Тов1 и Тов3. По вышеуказанным процедурам, если в списке номенклатуры указать Тов1 и Тов3, то в результате получим список из обоих контрагентов, а требуется только Контр2, у которого список номенклатуры точно совпадает.

    Заранее признателен.
    Последнее редактирование: 18 ноя 2014
  2. Draco
    Offline

    Draco Модераторы Команда форума Модератор

    Регистрация:
    28 окт 2009
    Сообщения:
    13.628
    Симпатии:
    946
    Баллы:
    204
    Ну так если не изящно, но быстро и на вскидку
    1. берете с формы этот список, если он у вас как ТЧ, то сразу к нему запросом можно обратиться с отбором по регистратору. ссылке, ну ли как вы добавляете го в список можно в ТЗ добавить и передать как парметр в запрос
    2. в запросе делаете Левое соединение вашего списка с РС срез последних по номенклатуре, и группируете по Торговым точкам
    а потом обрабатываете результат следующим образом пример:

    У вас есть Номенклатуры :Н1,Н2,Н3, и Точки: А,В,С

    Допустим Вам второй пункт выдал результат

    Н1 А
    Н1 В
    Н1 С
    Н2 А
    Н2 С
    Н3 А
    Н3 В
    Н3 С

    После группировки по Точкам будет
    А
    Н1,
    Н2,
    Н3,
    В
    Н1,
    Н3,
    С
    Н1,
    Н2,
    Н3,

    Начинаете обрабатывать

    КоличествоВсписке =ТЗНоменклатура.Количестово()-1; // Это количество вашей разной номенклатуры, которая в списке

    А потом циклом с обходом по группировкам
    если ВыборкаДетали.Количество()=КоличествоВсписке - тогда эту точку добавляйте
    Т.е зашли в А, сделали выборку деталей - там количество номенклатуы равно количеству ее в ТЗ, знаячит вся номенклатура есть - добавили.
    Зашли в В, там меньше , значит не вся, В С - вся.

    Думаю алгоритм понятен
    Steel Rain нравится это.
  3. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Может я не совсем понял что надо, почему нельзя просто сделать что-то вроде:
    Код:
    "ВЫБРАТЬ
    | СпециальныеЦеныСрезПоследних.ТорговаяТочка
    |ИЗ
    | РегистрСведений.СпециальныеЦены.СрезПоследних(&Дата, Номенклатура В (&Номенклатура)) КАК СпециальныеЦеныСрезПоследних
    |сгруппировать по СпециальныеЦеныСрезПоследних.ТорговаяТочка
    |имеющие Количество(СпециальныеЦеныСрезПоследних.Номенклатура) = &КоличествоНоменклатурыВСписке"
    
    ?
    Steel Rain и Draco нравится это.
  4. Draco
    Offline

    Draco Модераторы Команда форума Модератор

    Регистрация:
    28 окт 2009
    Сообщения:
    13.628
    Симпатии:
    946
    Баллы:
    204
    Ну вот это оно, просто я про имеющие все время забываю.
    И отвлекают, чет я намудрил с левым соединением, можно было то же просто, опять же писал на скорую, так что ссори.
  5. TopicStarter Overlay
    Steel Rain
    Offline

    Steel Rain Опытный в 1С

    Регистрация:
    29 сен 2006
    Сообщения:
    408
    Симпатии:
    2
    Баллы:
    29
    Спасибо за предложение, уже ближе, но не полностью. В выборку попадают контрагенты у которых присутствуют записи по всей номенклатуре из списка, но также и контрагенты у которых есть дополнительные записи. Т.е.
    Контр1: Тов1, Тов2, Тов3
    Контр2: Тов1, Тов2.
    Контр3: Тов1, Тов3
    Если в списке номенклатуры Тов1 и Тов2 то, по предложенному алгоритму, в выборке Контр1 и Контр2. А должен быть только Контр2.
    Либо я что то сделал не так...

    Код:
    Процедура ЗаполнитьКонтрТоварСоответствие(Кнопка)
        СписокНоменклатуры = Новый СписокЗначений;
        СписокНоменклатуры.Очистить();
    
        Для Каждого Стр ИЗ Товары Цикл
            СписокНоменклатуры.Добавить(Стр.Номенклатура);
            Стр.Цена = 0;
        КонецЦикла;
    
        Запрос = Новый Запрос;
        Запрос.Текст =
        "ВЫБРАТЬ
        |    СпециальныеЦеныСрезПоследних.ТорговаяТочка
        |ИЗ
        |    РегистрСведений.СпециальныеЦены.СрезПоследних(&Дата, Номенклатура В (&Номенклатура)) КАК СпециальныеЦеныСрезПоследних
        |ГДЕ
        |    СпециальныеЦеныСрезПоследних.Цена > 0
        |
        |СГРУППИРОВАТЬ ПО
        |    СпециальныеЦеныСрезПоследних.ТорговаяТочка
        |
        |ИМЕЮЩИЕ
        |    КОЛИЧЕСТВО(СпециальныеЦеныСрезПоследних.Номенклатура) = &Количество";
        Запрос.УстановитьПараметр("Дата", ДатаАктуальности);
        Запрос.УстановитьПараметр("Номенклатура", СписокНоменклатуры);
        Запрос.УстановитьПараметр("Количество", СписокНоменклатуры.Количество());
    
        //ТЗ = Запрос.Выполнить().Выгрузить();
        //ТЗ.ВыбратьСтроку();
    
        Контрагенты.Очистить();
    
        Выборка = Запрос.Выполнить().Выбрать();
        Пока Выборка.Следующий() Цикл
            Стр = Контрагенты.Добавить();
            Стр.Контрагент = Выборка.ТорговаяТочка;
        КонецЦикла;
    КонецПроцедуры
    
    P.S. ну логично, в общем то, по параметру таблицы регистра сведений "Номенклатура В (&Номенклатура)" выбираются только записи с номенклатурой из списка, если там что то ещё есть, то оно на этом этапе уже отсеклось... Буду думать дальше. Спасибо.
    Последнее редактирование: 18 ноя 2014
  6. TopicStarter Overlay
    Steel Rain
    Offline

    Steel Rain Опытный в 1С

    Регистрация:
    29 сен 2006
    Сообщения:
    408
    Симпатии:
    2
    Баллы:
    29
    А может как то через набор записей это сделать, а не запросом?
  7. Draco
    Offline

    Draco Модераторы Команда форума Модератор

    Регистрация:
    28 окт 2009
    Сообщения:
    13.628
    Симпатии:
    946
    Баллы:
    204
    Я не совсем могу понять как у вас может получиться
    Контр1: Тов1, Тов2, Тов3
    Контр2: Тов1, Тов2.
    Контр3: Тов1, Тов3
    Когда есть условие
    Номенклатура В (&Номенклатура)

    И в &Номенклатура у Вас только товар1,товар2
  8. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Draco, нет, нет. Будет как ТС описал.
    В РС по Контр1 запись цены по номенклатуре Тов1, Тов2, Тов3, в отбор он ставит только Тов1, Тов2. Но запись то по Тов3 из РС в любом случае никуда не девается. А ТС как я понял нужно строго условие что цены должны быть установлены только на переданную номенклатуру, не больше не меньше.
    --- Объединение сообщений, 19 ноя 2014 ---
    Код:
        "ВЫБРАТЬ
        |    СпециальныеЦеныСрезПоследних.ТорговаяТочка
        |ПОМЕСТИТЬ ВТ_НоменклатураИзСписка
        |ИЗ
        |    РегистрСведений.СпециальныеЦены.СрезПоследних(&Дата, Номенклатура В (&Номенклатура)) КАК СпециальныеЦеныСрезПоследних
        |
        |СГРУППИРОВАТЬ ПО
        |    СпециальныеЦеныСрезПоследних.ТорговаяТочка
        |
        |ИМЕЮЩИЕ
        |    КОЛИЧЕСТВО(СпециальныеЦеныСрезПоследних.Номенклатура) = &Количество"
        |;
        |ВЫБРАТЬ
        |    СпециальныеЦеныСрезПоследних.ТорговаяТочка
        |ПОМЕСТИТЬ ВТ_НоменклатураНЕИзСписка
        |ИЗ
        |    РегистрСведений.СпециальныеЦены.СрезПоследних(&Дата, НЕ Номенклатура В (&Номенклатура)) КАК СпециальныеЦеныСрезПоследних
        |
        |СГРУППИРОВАТЬ ПО
        |    СпециальныеЦеныСрезПоследних.ТорговаяТочка
        |
        |ИМЕЮЩИЕ
        |    КОЛИЧЕСТВО(СпециальныеЦеныСрезПоследних.Номенклатура) = 0
        |;
        |ВЫБРАТЬ
        |    ВТ_НоменклатураИзСписка.ТорговаяТочка
        |ИЗ
        |    ВТ_НоменклатураИзСписка КАК ВТ_НоменклатураИзСписка 
        |ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_НоменклатураНЕИзСписка КАК ВТ_НоменклатураНЕИзСписка 
        |ПО ВТ_НоменклатураИзСписка.ТорговаяТочка = ВТ_НоменклатураНЕИзСписка.ТорговаяТочка"
    
    Последнее редактирование: 19 ноя 2014
  9. TopicStarter Overlay
    Steel Rain
    Offline

    Steel Rain Опытный в 1С

    Регистрация:
    29 сен 2006
    Сообщения:
    408
    Симпатии:
    2
    Баллы:
    29
    shurikvz, поясните пожалуйста алгоритм. Попробовал реализовать, всегда на выходе пустая выборка.
    Я так понял: В первую ВТ помещаем контрагентов у которых есть записи с номенклатурой из списка, во вторую ВТ, контрагентов у которых нет записей с такой номенклатурой.
    Но тут, при условии "|ИМЕЮЩИЕ КОЛИЧЕСТВО(СпециальныеЦеныСрезПоследних.Номенклатура) = 0" вторая ВТ всегда пустая, а без этого условия таблицы не совпадают ни по одной позиции.
  10. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Так. Да, похоже так не будет работать. Сейчас.
  11. Draco
    Offline

    Draco Модераторы Команда форума Модератор

    Регистрация:
    28 окт 2009
    Сообщения:
    13.628
    Симпатии:
    946
    Баллы:
    204
    А зачем =0?
  12. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Код:
    "ВЫБРАТЬ
        |    СпециальныеЦеныСрезПоследних.ТорговаяТочка
        |ПОМЕСТИТЬ ВТ_НоменклатураИзСписка
        |ИЗ
        |    РегистрСведений.СпециальныеЦены.СрезПоследних(&Дата, Номенклатура В (&Номенклатура)) КАК СпециальныеЦеныСрезПоследних
        |
        |СГРУППИРОВАТЬ ПО
        |    СпециальныеЦеныСрезПоследних.ТорговаяТочка
        |
        |ИМЕЮЩИЕ
        |    КОЛИЧЕСТВО(СпециальныеЦеныСрезПоследних.Номенклатура) = &Количество"
        |;
        |ВЫБРАТЬ
        |    СпециальныеЦеныСрезПоследних.ТорговаяТочка
        |ПОМЕСТИТЬ ВТ_НоменклатураНЕИзСписка
        |ИЗ
        |    РегистрСведений.СпециальныеЦены.СрезПоследних(&Дата, НЕ Номенклатура В (&Номенклатура)) КАК СпециальныеЦеныСрезПоследних
        |
        |;
        |ВЫБРАТЬ
        |    ВТ_НоменклатураИзСписка.ТорговаяТочка
        |ИЗ
        |    ВТ_НоменклатураИзСписка КАК ВТ_НоменклатураИзСписка
        |ГДЕ НЕ ВТ_НоменклатураИзСписка.ТорговаяТочка В (ВЫБРАТЬ Т.ТорговаяТочка  ИЗ ВТ_НоменклатураНЕИзСписка КАК Т)
    
    так?
    --- Объединение сообщений, 20 ноя 2014 ---
    Оно не нужно, но там не только в этом дело, последний подзапрос тоже поменял.
    Steel Rain нравится это.
  13. TopicStarter Overlay
    Steel Rain
    Offline

    Steel Rain Опытный в 1С

    Регистрация:
    29 сен 2006
    Сообщения:
    408
    Симпатии:
    2
    Баллы:
    29
    Да, так, вроде, работает. Огромное спасибо. Завтра будем тестировать.

Поделиться этой страницей