|
Выбор наибольшей цены товара из табличной части | ☑ | ||
---|---|---|---|---|
0
НоваяВолна
11.05.21
✎
13:53
|
Есть документ, Приобретение Товаров в котором могут быть сроки с одинаковой номенклатурой, но разной ценой. При проведении этого документа автоматически должен создаваться документ Установка цен номенклатуры.
При этом понятно что в регистр цены номенклатуры не может записываться одинаковая номенклатура с тем же регистратором. Если есть дублирование номенклатуры, то надо отобрать позицию с большей ценой и только ее переносить в документ "Установка цен номенклатуры", остальные пропускать. Подскажите каким образом проще всего выбрать максимальную цену дублирующийся номенклатуры в табличной части ещё не записанного документа? |
|||
1
Aleksey
11.05.21
✎
13:54
|
запросом?
|
|||
2
Ненавижу 1С
гуру
11.05.21
✎
13:55
|
При проведении документ уже записан
|
|||
3
Гений 1С
гуру
11.05.21
✎
14:31
|
(1) (2) поддерживаю (двачую) ораторов. ;-)
документ записан, запросом. |
|||
4
Малыш Джон
11.05.21
✎
15:06
|
(0)>>Подскажите каким образом проще всего выбрать максимальную цену дублирующийся номенклатуры в табличной части ещё не записанного документа?
Давай, накидай нам какие варианты рассматриваешь, а мы скажем какой проще) |
|||
5
benj
11.05.21
✎
15:43
|
Типо так
ТаблицаДанных = ДокументПриобретения.Товары.Выгрузить(,"Номенклатура,Цена"); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Товары.Номенклатура КАК Номенклатура, | Товары.Цена КАК Цена |ПОМЕСТИТЬ Данные |ИЗ | &Товары КАК Товары |; | |//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | Данные.Номенклатура КАК Номенклатура, | МАКСИМУМ(Данные.Цена) КАК Цена |ИЗ | Данные КАК Данные | |СГРУППИРОВАТЬ ПО | Данные.Номенклатура"; Запрос.УстановитьПараметр("Таблица",ТаблицаДанных) РезультатЗапроса = Запрос.Выполнить(); ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать(); Пока ВыборкаДетальныеЗаписи.Следующий() Цикл // Вставить обработку выборки ВыборкаДетальныеЗаписи КонецЦикла; |
|||
6
benj
11.05.21
✎
15:44
|
(5) Ссори ошибку сделал в параметре
ТаблицаДанных = ДокументПриобретения.Товары.Выгрузить(,"Номенклатура,Цена"); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Товары.Номенклатура КАК Номенклатура, | Товары.Цена КАК Цена |ПОМЕСТИТЬ Данные |ИЗ | &Товары КАК Товары |; | |//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | Данные.Номенклатура КАК Номенклатура, | МАКСИМУМ(Данные.Цена) КАК Цена |ИЗ | Данные КАК Данные | |СГРУППИРОВАТЬ ПО | Данные.Номенклатура"; Запрос.УстановитьПараметр("Товары",ТаблицаДанных) РезультатЗапроса = Запрос.Выполнить(); ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать(); Пока ВыборкаДетальныеЗаписи.Следующий() Цикл // Вставить обработку выборки ВыборкаДетальныеЗаписи КонецЦикла; |
|||
7
lubitelxml
11.05.21
✎
15:49
|
(6) а где же РАЗЛИЧНЫЕ?
|
|||
8
benj
11.05.21
✎
15:51
|
(7) А смысл есть в группировке по номенклатуре и цене выбирать различные?
|
|||
9
НоваяВолна
12.05.21
✎
07:36
|
(6) сделал вот так
ТаблицаДанных = ТекущийОбъект.Товары.Выгрузить(,"Номенклатура, Цена"); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Товары.Номенклатура КАК Номенклатура, | Товары.Цена КАК Цена |ПОМЕСТИТЬ Данные |ИЗ | &Товары КАК Товары |; | |//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | Данные.Номенклатура КАК Номенклатура, | МАКСИМУМ(Данные.Цена) КАК Цена, | ПриобретениеТоваровУслугТовары.Количество КАК Количество, | ПриобретениеТоваровУслугТовары.КоличествоУпаковок КАК КоличествоУпаковок, | ПриобретениеТоваровУслугТовары.СуммаНДС КАК СуммаНДС, | ПриобретениеТоваровУслугТовары.СуммаСНДС КАК СуммаСНДС |ИЗ | Данные КАК Данные | ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПриобретениеТоваровУслуг.Товары КАК ПриобретениеТоваровУслугТовары | ПО Данные.Номенклатура = ПриобретениеТоваровУслугТовары.Номенклатура |ГДЕ | ПриобретениеТоваровУслугТовары.Ссылка = &Ссылка | |СГРУППИРОВАТЬ ПО | Данные.Номенклатура, | ПриобретениеТоваровУслугТовары.Количество, | ПриобретениеТоваровУслугТовары.КоличествоУпаковок, | ПриобретениеТоваровУслугТовары.СуммаНДС, | ПриобретениеТоваровУслугТовары.СуммаСНДС"; Запрос.УстановитьПараметр("Товары",ТаблицаДанных); Запрос.УстановитьПараметр("Ссылка",ТекущийОбъект.Ссылка); РезультатЗапроса = Запрос.Выполнить(); ТЗТовары = РезультатЗапроса.Выгрузить(); В результате в ТЗТовары имеется две строки с одинаковой номенклатурой, в поле цена у каждой указана максимальная для этой номенклатуры цена в документе |
|||
10
Ненавижу 1С
гуру
12.05.21
✎
07:53
|
(9) зачем ты тащишь суммы и количество? Естественно они разные для разных строк могут быть. Тебе нужно только номенклатура и цена.
И при проведении документ уже записан. Тогда не нужно загружать таблицу параметром, делать временную таблицу и левое соединение |
|||
11
Simod
12.05.21
✎
08:00
|
(6), (9) Зачем такие сложности?
МаксЦенаНоменклатуры = Новый Соответствие; Для Каждого СтрокаТЧ Из ЭтотОбъект.Товары Цикл ЦенаНоменклатуры = МаксЦенаНоменклатуры.Получить(СтрокаТЧ.Номенклатура); Если ЦенаНоменклатуры = Неопределено ИЛИ СтрокаТЧ.Цена > ЦенаНоменклатуры Тогда МаксЦенаНоменклатуры.Вставить(СтрокаТЧ.Номенклатура, СтрокаТЧ.Цена); КонецЕсли; КонецЦикла; |
|||
12
Sserj
12.05.21
✎
08:05
|
А все уверены что Запрос при проведении лучший вариант?
Зачем напрягать БД, грузить в нее временную таблицу или вон еще лучше выполнять полноценный запрос по документам если все нужные данные уже загружены в память. Неужто банальный обход каждой строки в памяти будет дольше запроса. Что типа максЦены = Новый Соответствие() Для Каждого Строка из ТабличнаЧасть Цикл последняяЦена = Строка.Получить(Строка.Номенклатура); Если (последняяЦена = Неопределено) или (последняяЦена < Строка.Цена) Тогда максЦены.Вставить(Строка.Номенклатура, последняяЦена); КонецЕсли; КонецЦикла; Ну а потом обход и запись. |
|||
13
Ненавижу 1С
гуру
12.05.21
✎
08:06
|
(11) а потом ещё один цикл чтобы соответствие в ТЧ превратить. Даешь больше кодинга с циклами
|
|||
14
Sserj
12.05.21
✎
08:11
|
(13) Т.е. "даешь меньше кодинга" оправдываешь лишнии запросы в обработке проведения, удорожания транзакций в времени блокировок данных?
|
|||
15
НоваяВолна
12.05.21
✎
08:12
|
(10) в общем разобрался. Убрал из второй таблицы количество и сумму, сделал ее временной и окончательным запросом прилепил количество и сумму.
Всем спасибо! |
|||
16
Ненавижу 1С
гуру
12.05.21
✎
08:21
|
(14) неоправданная оптимизация в ущерб читаемости кода
Но вопрос на поболтать чисто. Однозначного мнения нет |
|||
17
Bigbro
12.05.21
✎
08:26
|
поддержку (11) (14)
все что можно делать не дергая базу - надо делать именно так. |
|||
18
Sserj
12.05.21
✎
08:31
|
(16) А почему бы и не поболтать, зачем еще форум то нужен :)
"..в ущерб читаемости кода.." - по мне так красота текста запроса очень спорная, если следовать религии ЧистогоКода то маленькие функции будут выглядеть гораздо симпотичнее портянок запроса: Фунцкия получитьСтруктуруМаксимальныхЦен() ..... Возврат максимальныеЦены; КонецФункции Функция УстановкаМаксимальныхЦен(максимальныеЦены) документУстановкиЦен = Неопределено; ... Возврат документУстановкиЦен КонецФункции Процедура ОбработкаПроведения() ... максимальныеЦены = получитьСтруктуруМаксимальныхЦен(); Если УстановкаМаксимальныхЦен(максимальныеЦены) = Неопределено Тогда Отказ = Истина; КонецЕсли КонецПроцедуры 2. "..неоправданная оптимизация в ущерб читаемости кода.." - та ладно, если документ на тысячи строк это будет ой какая "оправданность". |
|||
19
fisher
12.05.21
✎
09:08
|
(0) Ну, я бы тупо создал соответствие номенклатура/цена и за один проход заполнил его номенклатурой с максимальными ценами (т.е. сначала пробуем получить цену номенклатуры из соответствия и если еще нет или меньше чем текущая - пишем новые данные).
|
|||
20
fisher
12.05.21
✎
09:10
|
Я слоупок. В (11) уже реализация.
(16) "Неоправданная оптимизация"? Надеюсь, это был сарказм. Это прямой как железная дорога лобовой подход. |
|||
21
ChMikle
12.05.21
✎
09:12
|
сортировать ТЗ по цене по возрастанию и записывать. Не прокатит так ?
|
|||
22
fisher
12.05.21
✎
09:12
|
Хотя да, постановка задачи неправильная. Документ будет уже записан.
|
|||
23
mikecool
12.05.21
✎
09:16
|
если все данные уже есть - зачем еще запрос?
|
|||
24
fisher
12.05.21
✎
09:20
|
(23) При проведении так или иначе будут какие-то запросы. Впендюрить в пакет подготовку данных еще и для этой задачи будет вполне оптимальным вариантом. В общем, вопрос вкусовой и ситуативный.
|
|||
25
BIP1
12.05.21
✎
09:56
|
(9) Скажите, чем вы руководствовались, когда эту задачу решили с помощью такой "портянки" кода с запросом? Чем вас не устроил цикл?
Запрос "моднее", чем цикл или что? Смысл запроса ускользает конкретно в данном случае. Что не так с ЭтотОбъект.Товары (или как там у вас в документе ТЧ называется)? (16) Сравните "портянку" автора и один из вариантов с циклом. Использование запроса явно "в ущерб читаемости кода". Любят иногда люди пихать циклы везде, где только можно:) Зато ЗАПРОС! Авторитета так программистского добирают или чего? непонятно🤷♂️ |
|||
26
Ненавижу 1С
гуру
12.05.21
✎
10:06
|
(25) затем что вы привели только половину
потом еще это соответствие в ТЧ надо развернуть В 1С нет функциональщины типа LINQ и поэтому все это выглядит крайне некрасиво |
|||
27
BIP1
12.05.21
✎
10:09
|
(26) Так "вторая половина" и с запросом будет. Её можно в отдельную процедуру/функцию оформить и передать туда данные Товар+Цена.
|
|||
28
Bigbro
12.05.21
✎
10:13
|
(26) что некрасивого в простейшем цикле по ТЧ который строит структуру-соответствие?
смысл этого поймет любой новичок с первого взгляда. более того и с точки зрения работы с БД данный подход более правильный - не нужно дергать базу когда без этого можно обойтись. вам кажется это мелочи тут дернул легкий запросик там. а в итоге из этих тут и там может вырасти паразитный фоновый режим нагрузки, который составит существенную долю и уже будет оказывать влияние на работу. зачем?? я бы понял, если пришлось бы писать некий архисложный трехэтажный алгоритм из костылей а реализация запросом была бы в 3 строки. но тут не тот случай. |
|||
29
BIP1
12.05.21
✎
10:23
|
(28) К тому же, прямо в этом цикле можно заполнять и документ УстановкаЦенНоменклатуры. А используя ЗаполнитьЗначенияСвойств() количество строк кода можно свести к минимуму. А любые "некрасивости" можно сопроводить веским комментарием😀
Но кто-то любит запросы и всё тут🤷♂️ несмотря на то, что такие "портянки" иногда фиг поймешь с первого/второго раза |
|||
30
НоваяВолна
12.05.21
✎
10:25
|
(25) В (1), (3), (6) посоветовали запросом. Запросом и сделал. И по моему запрос читается проще, чем два цикла подряд.
|
|||
31
Bigbro
12.05.21
✎
10:27
|
(30) ну против авторитета (3) конечно идти не стоит.
умолк. |
|||
32
Sserj
12.05.21
✎
10:49
|
(30) Так не делай два цикла подряд :)
Почитай старину Мартина и спрячь все в маленький функциях. Циклы есть всегда и везде, по сути в язаках программирования ничего и нет кроме переменных, условий и циклов (ну если быть точнее то и циклов то нет, это всего лишь прикрытие для ненавистного GOTO). Вопрос только на каком уровне абстракции они спрятаны. |
|||
33
fisher
12.05.21
✎
10:57
|
(32) Тут когда народ заглядывает в БСП и видит подход старины Мартина - пеной исходят. Мол стек вызовов за страницу вылазит, а можно было бы все в одной.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |