Вход | Регистрация
 

Выбор наибольшей цены товара из табличной части

Выбор наибольшей цены товара из табличной части
Я
   НоваяВолна
 
11.05.21 - 13:53
Есть документ, Приобретение Товаров в котором могут быть сроки с одинаковой номенклатурой, но разной ценой. При проведении этого документа автоматически должен создаваться документ Установка цен номенклатуры.
    При этом понятно что в регистр цены номенклатуры не может записываться одинаковая номенклатура с тем же регистратором.
Если есть дублирование номенклатуры, то надо отобрать позицию с большей ценой и только ее переносить в документ "Установка цен номенклатуры", остальные пропускать.
Подскажите каким образом проще всего выбрать максимальную цену дублирующийся номенклатуры в табличной части ещё не записанного документа?
 
 Партнерская программа EFSOL Oblako
   Aleksey
 
1 - 11.05.21 - 13:54
запросом?
   Ненавижу 1С
 
2 - 11.05.21 - 13:55
При проведении документ уже записан
   Гений 1С
 
3 - 11.05.21 - 14:31
(1) (2) поддерживаю (двачую) ораторов. ;-)
документ записан, запросом.
   Малыш Джон
 
4 - 11.05.21 - 15:06
(0)>>Подскажите каким образом проще всего выбрать максимальную цену дублирующийся номенклатуры в табличной части ещё не записанного документа?

Давай, накидай нам какие варианты рассматриваешь, а мы скажем какой проще)
   benj
 
5 - 11.05.21 - 15:43
Типо так
    ТаблицаДанных = ДокументПриобретения.Товары.Выгрузить(,"Номенклатура,Цена");
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |    Товары.Номенклатура КАК Номенклатура,
        |    Товары.Цена КАК Цена
        |ПОМЕСТИТЬ Данные
        |ИЗ
        |    &Товары КАК Товары
        |;
        |
        ////////////////////////////////////////////////////////////////////////////////

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

    КонецЦикла;
   benj
 
6 - 11.05.21 - 15:44
(5) Ссори ошибку сделал в параметре
    ТаблицаДанных = ДокументПриобретения.Товары.Выгрузить(,"Номенклатура,Цена");
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |    Товары.Номенклатура КАК Номенклатура,
        |    Товары.Цена КАК Цена
        |ПОМЕСТИТЬ Данные
        |ИЗ
        |    &Товары КАК Товары
        |;
        |
        ////////////////////////////////////////////////////////////////////////////////

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

    КонецЦикла;
   lubitelxml
 
7 - 11.05.21 - 15:49
(6) а где же РАЗЛИЧНЫЕ?
   benj
 
8 - 11.05.21 - 15:51
(7) А смысл есть в группировке по номенклатуре и цене выбирать различные?
   НоваяВолна
 
9 - 12.05.21 - 07:36
(6) сделал вот так
                ТаблицаДанных = ТекущийОбъект.Товары.Выгрузить(,"Номенклатура, Цена");
                Запрос = Новый Запрос;
            
                Запрос.Текст = 
                "ВЫБРАТЬ
                |    Товары.Номенклатура КАК Номенклатура,
                |    Товары.Цена КАК Цена
                |ПОМЕСТИТЬ Данные
                |ИЗ
                |    &Товары КАК Товары
                |;
                |
                ////////////////////////////////////////////////////////////////////////////////

                |ВЫБРАТЬ
                |    Данные.Номенклатура КАК Номенклатура,
                |    МАКСИМУМ(Данные.Цена) КАК Цена,
                |    ПриобретениеТоваровУслугТовары.Количество КАК Количество,
                |    ПриобретениеТоваровУслугТовары.КоличествоУпаковок КАК КоличествоУпаковок,
                |    ПриобретениеТоваровУслугТовары.СуммаНДС КАК СуммаНДС,
                |    ПриобретениеТоваровУслугТовары.СуммаСНДС КАК СуммаСНДС
                |ИЗ
                |    Данные КАК Данные
                |        ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПриобретениеТоваровУслуг.Товары КАК ПриобретениеТоваровУслугТовары
                |        ПО Данные.Номенклатура = ПриобретениеТоваровУслугТовары.Номенклатура
                |ГДЕ
                |    ПриобретениеТоваровУслугТовары.Ссылка = &Ссылка
                |
                |СГРУППИРОВАТЬ ПО
                |    Данные.Номенклатура,
                |    ПриобретениеТоваровУслугТовары.Количество,
                |    ПриобретениеТоваровУслугТовары.КоличествоУпаковок,
                |    ПриобретениеТоваровУслугТовары.СуммаНДС,
                |    ПриобретениеТоваровУслугТовары.СуммаСНДС";

                
                Запрос.УстановитьПараметр("Товары",ТаблицаДанных);
                Запрос.УстановитьПараметр("Ссылка",ТекущийОбъект.Ссылка);
                РезультатЗапроса = Запрос.Выполнить();
            
                ТЗТовары = РезультатЗапроса.Выгрузить();



В результате в ТЗТовары имеется две строки с одинаковой номенклатурой, в поле цена у каждой указана максимальная для этой номенклатуры цена в документе
   Ненавижу 1С
 
10 - 12.05.21 - 07:53
(9) зачем ты тащишь суммы и количество? Естественно они разные для разных строк могут быть. Тебе нужно только номенклатура и цена.

И при проведении документ уже записан. Тогда не нужно загружать таблицу параметром, делать временную таблицу и левое соединение
   Simod
 
11 - 12.05.21 - 08:00
(6), (9) Зачем такие сложности?

МаксЦенаНоменклатуры = Новый Соответствие;
Для Каждого СтрокаТЧ Из ЭтотОбъект.Товары Цикл
    ЦенаНоменклатуры = МаксЦенаНоменклатуры.Получить(СтрокаТЧ.Номенклатура);
    Если ЦенаНоменклатуры = Неопределено
        ИЛИ СтрокаТЧ.Цена > ЦенаНоменклатуры Тогда
        МаксЦенаНоменклатуры.Вставить(СтрокаТЧ.Номенклатура, СтрокаТЧ.Цена);
    КонецЕсли;
КонецЦикла;
   Sserj
 
12 - 12.05.21 - 08:05
А все уверены что Запрос при проведении лучший вариант?
Зачем напрягать БД, грузить в нее временную таблицу или вон еще лучше выполнять полноценный запрос по документам если все нужные данные уже загружены в память.
Неужто банальный обход каждой строки в памяти будет дольше запроса.
Что типа
максЦены = Новый Соответствие()
Для Каждого Строка из ТабличнаЧасть Цикл
  последняяЦена = Строка.Получить(Строка.Номенклатура);
  Если (последняяЦена = Неопределено) или (последняяЦена < Строка.Цена) Тогда
    максЦены.Вставить(Строка.Номенклатура, последняяЦена);
  КонецЕсли;
КонецЦикла;
Ну а потом обход и запись.
   Ненавижу 1С
 
13 - 12.05.21 - 08:06
(11) а потом ещё один цикл чтобы соответствие в ТЧ превратить. Даешь больше кодинга с циклами
   Sserj
 
14 - 12.05.21 - 08:11
(13) Т.е. "даешь меньше кодинга" оправдываешь лишнии запросы в обработке проведения, удорожания транзакций в времени блокировок данных?
   НоваяВолна
 
15 - 12.05.21 - 08:12
(10) в общем разобрался. Убрал из второй таблицы количество и сумму, сделал ее временной и окончательным запросом прилепил количество и сумму.
Всем спасибо!
   Ненавижу 1С
 
16 - 12.05.21 - 08:21
(14) неоправданная оптимизация в ущерб читаемости кода

Но вопрос на поболтать чисто. Однозначного мнения нет
   Bigbro
 
17 - 12.05.21 - 08:26
поддержку (11) (14)
все что можно делать не дергая базу - надо делать именно так.
   Sserj
 
18 - 12.05.21 - 08:31
(16) А почему бы и не поболтать, зачем еще форум то нужен :)
"..в ущерб читаемости кода.." - по мне так красота текста запроса очень спорная, если следовать религии ЧистогоКода то маленькие функции будут выглядеть гораздо симпотичнее портянок запроса:
Фунцкия получитьСтруктуруМаксимальныхЦен()
  .....
  Возврат максимальныеЦены;
КонецФункции

Функция УстановкаМаксимальныхЦен(максимальныеЦены)
  документУстановкиЦен = Неопределено;
  ...
  Возврат документУстановкиЦен
КонецФункции

Процедура ОбработкаПроведения()
...
максимальныеЦены = получитьСтруктуруМаксимальныхЦен();
Если УстановкаМаксимальныхЦен(максимальныеЦены) = Неопределено Тогда
  Отказ = Истина;
КонецЕсли
КонецПроцедуры

2. "..неоправданная оптимизация в ущерб читаемости кода.." - та ладно, если документ на тысячи строк это будет ой какая "оправданность".
   fisher
 
19 - 12.05.21 - 09:08
(0) Ну, я бы тупо создал соответствие номенклатура/цена и за один проход заполнил его номенклатурой с максимальными ценами (т.е. сначала пробуем получить цену номенклатуры из соответствия и если еще нет или меньше чем текущая - пишем новые данные).
   fisher
 
20 - 12.05.21 - 09:10
Я слоупок. В (11) уже реализация.
(16) "Неоправданная оптимизация"? Надеюсь, это был сарказм. Это прямой как железная дорога лобовой подход.
   ChMikle
 
21 - 12.05.21 - 09:12
сортировать ТЗ по цене по возрастанию и записывать. Не прокатит так  ?
   fisher
 
22 - 12.05.21 - 09:12
Хотя да, постановка задачи неправильная. Документ будет уже записан.
   mikecool
 
23 - 12.05.21 - 09:16
если все данные уже есть - зачем еще запрос?
   fisher
 
24 - 12.05.21 - 09:20
(23) При проведении так или иначе будут какие-то запросы. Впендюрить в пакет подготовку данных еще и для этой задачи будет вполне оптимальным вариантом. В общем, вопрос вкусовой и ситуативный.
   BIP1
 
25 - 12.05.21 - 09:56
(9) Скажите, чем вы руководствовались, когда эту задачу решили с помощью такой "портянки" кода с запросом? Чем вас не устроил цикл?
Запрос "моднее", чем цикл или что?
Смысл запроса ускользает конкретно в данном случае. Что не так с ЭтотОбъект.Товары (или как там у вас в документе ТЧ называется)? (16) Сравните "портянку" автора и один из вариантов с циклом. Использование запроса явно "в ущерб читаемости кода". Любят иногда люди пихать циклы везде, где только можно:) Зато ЗАПРОС! Авторитета так программистского добирают или чего? непонятно🤷‍♂️
   Ненавижу 1С
 
26 - 12.05.21 - 10:06
(25) затем что вы привели только половину
потом еще это соответствие в ТЧ надо развернуть

В 1С нет функциональщины типа LINQ и поэтому все это выглядит крайне некрасиво
   BIP1
 
27 - 12.05.21 - 10:09
(26) Так "вторая половина" и с запросом будет. Её можно в отдельную процедуру/функцию оформить и передать туда данные Товар+Цена.
   Bigbro
 
28 - 12.05.21 - 10:13
(26) что некрасивого в простейшем цикле по ТЧ который строит структуру-соответствие?
смысл этого поймет любой новичок с первого взгляда.
более того и с точки зрения работы с БД данный подход более правильный - не нужно дергать базу когда без этого можно обойтись.
вам кажется это мелочи тут дернул легкий запросик там.
а в итоге из этих тут и там может вырасти паразитный фоновый режим нагрузки, который составит существенную долю и уже будет оказывать влияние на работу.
зачем??
я бы понял, если пришлось бы писать некий архисложный трехэтажный алгоритм из костылей а реализация запросом была бы в 3 строки.
но тут не тот случай.
   BIP1
 
29 - 12.05.21 - 10:23
(28) К тому же, прямо в этом цикле можно заполнять и документ УстановкаЦенНоменклатуры. А используя ЗаполнитьЗначенияСвойств() количество строк кода можно свести к минимуму. А любые "некрасивости" можно сопроводить веским комментарием😀
Но кто-то любит запросы и всё тут🤷‍♂️ несмотря на то, что такие "портянки" иногда фиг поймешь с первого/второго раза
   НоваяВолна
 
30 - 12.05.21 - 10:25
(25) В (1), (3), (6) посоветовали запросом. Запросом и сделал. И по моему запрос читается проще, чем два цикла подряд.
 
 
   Bigbro
 
31 - 12.05.21 - 10:27
(30) ну против авторитета (3) конечно идти не стоит.
умолк.
   Sserj
 
32 - 12.05.21 - 10:49
(30) Так не делай два цикла подряд :)
Почитай старину Мартина и спрячь все в маленький функциях.
Циклы есть всегда и везде, по сути в язаках программирования ничего и нет кроме переменных, условий и циклов (ну если быть точнее то и циклов то нет, это всего лишь прикрытие для ненавистного GOTO).
Вопрос только на каком уровне абстракции они спрятаны.
   fisher
 
33 - 12.05.21 - 10:57
(32) Тут когда народ заглядывает в БСП и видит подход старины Мартина - пеной исходят. Мол стек вызовов за страницу вылазит, а можно было бы все в одной.


Список тем форума
 
Программист всегда исправляет последнюю ошибку.
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.