|
v7: ТиС 9.2, глВернутьЦену() - не въезжаю по коду в глубокий смысл написанного | ☑ | ||
---|---|---|---|---|
0
Злопчинский
27.11.19
✎
08:39
|
//******************************************************************************
// глВернутьЦену(Номенклатура, ТипЦены, ДатаЦены, ЦенаЦены, ЕдЦены, ВалЦены, НаценкаЦены, НайденнаяЦена) // // Параметры: // Номенклатура - элемент справочника "Номенклатура" // ТипЦены - элемент справочника "ТипыЦен" // ДатаЦены - дата, на которую надо получить цену // ЦенаЦены - переменная, которую надо заполнитиь значением (число) полученной цены // ЕдЦены - переменная, которую надо заполнитиь значением // (элемент справочника Единицы) единицы, за которую дается цена // ВалЦены - переменная, которую надо заполнитиь значением валюты, в которой выражена цена // НайденнаяЦена - переменная, которую надо заполнить найденным элементом справочника цен // // Возвращаемое значение: // 1 - если есть такая цена, пераметры цены заполнены // 0 - нет такой цены // -1 - есть только цены, помеченные на удаление // // Описание: // Формирует ценовые характеристики номенклатурной единицы по заданному типу цен. // Функция глВернутьЦену(Номенклатура, ТипЦены, ДатаЦены = 0, ЦенаЦены = 0, ЕдЦены = 0, ВалЦены = 0, НаценкаЦены = 0, НайденнаяЦена = 0) Экспорт Перем ЦеныНоменклатуры; Перем Рассчетная; Перем НужныйТипЦен; Перем ЕстьУдаленные; Рез = 1; НайденнаяЦена = ПолучитьПустоеЗначение("Справочник.Цены"); Если ПустоеЗначение(ДатаЦены) = 1 Тогда ДатаЦены = РабочаяДата(); КонецЕсли; // Найдет или нужную цену в справочнике // если она рассчитывается, то найдем базовую цену Рассчетная = ТипЦены.Рассчитывается; НужныйТипЦен = ?(ПустоеЗначение(Рассчетная) = 1, ТипЦены, ТипЦены.БазовыйТипЦен); ЦеныНоменклатуры= СоздатьОбъект("Справочник.Цены"); ЦеныНоменклатуры.ИспользоватьВладельца(Номенклатура); ЦеныНоменклатуры.ВыбратьЭлементы(); Пока ЦеныНоменклатуры.ПолучитьЭлемент() = 1 Цикл Если ЦеныНоменклатуры.ТипЦен <> НужныйТипЦен Тогда Продолжить; КонецЕсли; // КТ1 === ??? ======= НайденнаяЦена = ЦеныНоменклатуры.ТекущийЭлемент(); Если ЦеныНоменклатуры.ПометкаУдаления() = 1 Тогда Рез = - 1; // Цена есть, но помечена на удаление Продолжить; // КТ2 === ВОТ ЗДЕСЬ КАКОЙ ГЛУБОКИЙ СМЫСЛ. почему не ПРЕРВАТЬ ..? ======= Иначе Прервать; КонецЕсли; КонецЦикла; Если ПустоеЗначение(НайденнаяЦена) = 1 Тогда // Нет такой цены Возврат 0; КонецЕсли; // Заполним все ценовые характериситики // если не задана единица цены на эту дату, то потом придется обрабатывать случай нулевого коэффициента у пустой единицы ЕдЦены = НайденнаяЦена.Единица.Получить(ДатаЦены); Если ПустоеЗначение(Рассчетная) = 1 Тогда //Если цена не рассчитывается ЦенаЦены = НайденнаяЦена.Цена.Получить(ДатаЦены); // элемент справочника существует Валюту и Наценку возьмем из него ВалЦены = НайденнаяЦена.Валюта; НаценкаЦены = НайденнаяЦена.Процент; Иначе //Если цена рассчитывается БазоваяЦена = НайденнаяЦена.Цена.Получить(ДатаЦены); БазоваяВалюта = НайденнаяЦена.Валюта; // Цены у базового типа могут отличаться ЦенаЦены = глПересчет(БазоваяЦена, БазоваяВалюта, ДатаЦены, ТипЦены.Валюта, ДатаЦены); ЦенаЦены = глОкруглить(ЦенаЦены * (100 + ТипЦены.Процент) / 100, ТипЦены.ПорядокОкругления); // элемент справочника Цены не существует (расчетный). Валюту и Наценку возьмем из типа цены ВалЦены = ТипЦены.Валюта; НаценкаЦены = ТипЦены.Процент; КонецЕсли; Возврат Рез; КонецФункции // глВернутьЦену() |
|||
1
Kigo_Kigo
27.11.19
✎
08:42
|
А что не понятного то?
|
|||
2
Злопчинский
27.11.19
✎
08:43
|
сек, пишу...
|
|||
3
Kigo_Kigo
27.11.19
✎
08:44
|
Потому что может быть другой такой же тип цен, не помеченный на удаление иначе прервать
|
|||
4
Кодер
27.11.19
✎
08:45
|
Дальше по коду отлови ситуацию, когда на твоих данных цена всё же получена, и запиши (в ЖР, мыло, в крайнем случае сообщением пользователю - только дойдёт несколько % таких сообщений) себе этот случай.
|
|||
5
Злопчинский
27.11.19
✎
08:46
|
1. допустим, что вот так вот получилось что в Спр.Цены "задвоены" записи для ТипЦены, первая запись помечена на удаление, вторая - норм.
получится что через _параметры_ вернет норм.цену (для второй записи), а как результат функции вернет -1 (для первой записи) - НЕХОРОШО. 2. допустим, что вот так вот получилось что в Спр.Цены "задвоены" записи для ТипЦены, первая запись норм, вторая - помечена на удаление. получится что через _параметры_ вернет норм.цену (для первой записи), а как результат функции вернет 1 (для первой записи) - хорошо. |
|||
6
Kigo_Kigo
27.11.19
✎
08:47
|
Может быть 2 цены - тип - розничная, если одна помеченна на удаление - тоищем дальше, до первого вхождения не помеченной
|
|||
7
Злопчинский
27.11.19
✎
08:47
|
По идее в КТ1 надо поставить
Рез = 1; ???? |
|||
8
Злопчинский
27.11.19
✎
08:48
|
(6) кривой результат будет, сп. п.5.1
|
|||
9
Kigo_Kigo
27.11.19
✎
08:49
|
(5) п.1 вернет "-1" если не найдет НЕ помеченную на уделения цену, найдет вернет 1
п.2 до втрой не дойдет, потому что там прервать! |
|||
10
Sserj
27.11.19
✎
08:51
|
Смысл в том что это то что обычно называется "овнокод" :)
Функция возвращает цену побочным эффектом в передваемый параметр ЦенаЦены. А сам результат функции якобы используется для каких то проверок. |
|||
11
Kigo_Kigo
27.11.19
✎
08:54
|
Но вот здесь я вижу вот так
Если ЦеныНоменклатуры.ПометкаУдаления() = 1 Тогда Рез = - 1; // Цена есть, но помечена на удаление Продолжить; // КТ2 === ВОТ ЗДЕСЬ КАКОЙ ГЛУБОКИЙ СМЫСЛ. почему не ПРЕРВАТЬ ..? ======= Иначе Рез = 1;// переприсвоить результат после помеченой на удаление Прервать; КонецЕсли; |
|||
12
Kigo_Kigo
27.11.19
✎
08:59
|
(10) Кроме ЦенаЦены, она еще возвращает ссылку на подчиненный справочник цены подчиненный номенклатуре по типу цены со всеми его атрибутами
|
|||
13
Злопчинский
27.11.19
✎
09:01
|
(12) это несущественно сейчас
|
|||
14
Sserj
27.11.19
✎
09:01
|
(12) Так вот и нужно смотреть контекст вызова этой функции. Она видимо может вызываться
когда в любом случае нужно получить актуальную цену или это контекст где проверяется что цена с требуемым типом помечена на удаление. |
|||
15
Злопчинский
27.11.19
✎
09:01
|
(9) кто-то из нас тупит.
по 5.1 - если НАЙДЕТ удаленую - вернет -1, при этом параметрами вернет ПРО НЕУДАЛЕННУЮ |
|||
16
Kigo_Kigo
27.11.19
✎
09:03
|
(15) Читай (11)
|
|||
17
Kigo_Kigo
27.11.19
✎
09:03
|
проеп 1с кодеров однозначно
|
|||
18
Kigo_Kigo
27.11.19
✎
09:04
|
но кстати такие ситуации крайне редки ИМХО, по крайней мере у меня такого не было
|
|||
19
Злопчинский
27.11.19
✎
09:05
|
(16) ну да так тоже можно
|
|||
20
Злопчинский
27.11.19
✎
09:07
|
(18) ну, у меня тоже не было, бо штатно такой ситуации с задвоением хрен получишь (урбд нет), но потенциально - можно
|
|||
21
Злопчинский
27.11.19
✎
09:07
|
(17) то есть согласен что диагноз я поставил верно?
|
|||
22
Kigo_Kigo
27.11.19
✎
09:08
|
(21) да, согласен
|
|||
23
Злопчинский
27.11.19
✎
09:12
|
(22) ок
|
|||
24
Злопчинский
27.11.19
✎
09:14
|
Есть в типовой еще один косяк, он достаточно тяжелый, приводит к неявным труднообнаруживаемым пересортам, но проявляется когда включена партионока, в партиях задаются свойства (например, цвет) и по продаже идет ВозвратОтПокупателя - могут пересортиться на остатках, возвращают допустим красный цвет, а на остатки ляжет синий...
|
|||
25
Галахад
гуру
27.11.19
✎
09:17
|
Гм. А занимательно читать записки археологов. :-)
|
|||
26
Злопчинский
27.11.19
✎
09:23
|
(25) Без знания прошлого - нет будущего! что мы и видим в тупиковом развитии 8-ки ;-)
|
|||
27
VladZ
27.11.19
✎
10:36
|
Мы в свое время оптимизировали эту функцию.
Делали отбор по реквизиту "Тип цен" и в коде ЦеныНоменклатуры.ИспользоватьВладельца(Номенклатура); ЦеныНоменклатуры.ВыбратьЭлементы(); добавляли выборку по реквизиту "Тип цены". В базах данных с большим количеством типов цен это значительно повышало производительность. |
|||
28
Злопчинский
27.11.19
✎
10:41
|
Если принять что для помеченых на удаление цен (элементов СПр.Цены) числовое значение цены должно трактоваться как 0(ноль) - т.е. цены нет - то все правик сводятся к трем операторам в функции глВернутьЦену.
. Прошерстил глоб.модуль и конфигу (974 релиз) - более никаких доработок по коду не требуется, все остается работоспособным "автоматом". . Типа вот так получается, тестирвоание на юзверях покажет ;-) . //****************************************************************************** //[*]progadmin, 27.11.2019, НЕТИПОВОЕ //// глВернутьЦену(Номенклатура, ТипЦены, ДатаЦены, ЦенаЦены, ЕдЦены, ВалЦены, НаценкаЦены, НайденнаяЦена) // ------------- // глВернутьЦену(Номенклатура, ТипЦены, ДатаЦены, ЦенаЦены, ЕдЦены, ВалЦены, НаценкаЦены, НайденнаяЦена, ВозвращатьУдаленнуюЦенаЦены) // Параметры: // ВозвращатьУдаленнуюЦенаЦены - 0/1, если для удаленных цен значение ЦенаЦены считается незаданным/заданным (0/1 соответственно) //[*]_progadmin, 27.11.2019, НЕТИПОВОЕ // // Параметры: // Номенклатура - элемент справочника "Номенклатура" // ТипЦены - элемент справочника "ТипыЦен" // ДатаЦены - дата, на которую надо получить цену // ЦенаЦены - переменная, которую надо заполнитиь значением (число) полученной цены // ЕдЦены - переменная, которую надо заполнитиь значением // (элемент справочника Единицы) единицы, за которую дается цена // ВалЦены - переменная, которую надо заполнитиь значением валюты, в которой выражена цена // НайденнаяЦена - переменная, которую надо заполнить найденным элементом справочника цен // // Возвращаемое значение: // 1 - если есть такая цена, пераметры цены заполнены // 0 - нет такой цены // -1 - есть только цены, помеченные на удаление // // Описание: // Формирует ценовые характеристики номенклатурной единицы по заданному типу цен. // //[*]progadmin, 27.11.2019, НЕТИПОВОЕ //Функция глВернутьЦену(Номенклатура, ТипЦены, ДатаЦены = 0, ЦенаЦены = 0, ЕдЦены = 0, ВалЦены = 0, НаценкаЦены = 0, НайденнаяЦена = 0) Экспорт // ------------- Функция глВернутьЦену(Номенклатура, ТипЦены, ДатаЦены = 0, ЦенаЦены = 0, ЕдЦены = 0, ВалЦены = 0, НаценкаЦены = 0, НайденнаяЦена = 0, ВозвращатьУдаленнуюЦенаЦены=0) Экспорт //[*]_progadmin, 27.11.2019, НЕТИПОВОЕ Перем ЦеныНоменклатуры; Перем Рассчетная; Перем НужныйТипЦен; Перем ЕстьУдаленные; Рез = 1; НайденнаяЦена = ПолучитьПустоеЗначение("Справочник.Цены"); Если ПустоеЗначение(ДатаЦены) = 1 Тогда ДатаЦены = РабочаяДата(); КонецЕсли; // Найдет или нужную цену в справочнике // если она рассчитывается, то найдем базовую цену Рассчетная = ТипЦены.Рассчитывается; НужныйТипЦен = ?(ПустоеЗначение(Рассчетная) = 1, ТипЦены, ТипЦены.БазовыйТипЦен); ЦеныНоменклатуры= СоздатьОбъект("Справочник.Цены"); ЦеныНоменклатуры.ИспользоватьВладельца(Номенклатура); ЦеныНоменклатуры.ВыбратьЭлементы(); Пока ЦеныНоменклатуры.ПолучитьЭлемент() = 1 Цикл Если ЦеныНоменклатуры.ТипЦен <> НужныйТипЦен Тогда Продолжить; КонецЕсли; НайденнаяЦена = ЦеныНоменклатуры.ТекущийЭлемент(); Если ЦеныНоменклатуры.ПометкаУдаления() = 1 Тогда Рез = - 1; // Цена есть, но помечена на удаление Продолжить; Иначе Рез = 1; //[+]progadmin, 27.11.2019, НЕТИПОВОЕ, косяк писателей типовых Прервать; КонецЕсли; КонецЦикла; Если ПустоеЗначение(НайденнаяЦена) = 1 Тогда // Нет такой цены Возврат 0; КонецЕсли; Множитель = ?(Рез=-1,ВозвращатьУдаленнуюЦенаЦены,1); //[+]progadmin, 27.11.2019, НЕТИПОВОЕ // Заполним все ценовые характериситики // если не задана единица цены на эту дату, то потом придется обрабатывать случай нулевого коэффициента у пустой единицы ЕдЦены = НайденнаяЦена.Единица.Получить(ДатаЦены); Если ПустоеЗначение(Рассчетная) = 1 Тогда //Если цена не рассчитывается ЦенаЦены = НайденнаяЦена.Цена.Получить(ДатаЦены); // элемент справочника существует Валюту и Наценку возьмем из него ВалЦены = НайденнаяЦена.Валюта; НаценкаЦены = НайденнаяЦена.Процент; Иначе //Если цена рассчитывается БазоваяЦена = НайденнаяЦена.Цена.Получить(ДатаЦены); БазоваяВалюта = НайденнаяЦена.Валюта; // Цены у базового типа могут отличаться ЦенаЦены = глПересчет(БазоваяЦена, БазоваяВалюта, ДатаЦены, ТипЦены.Валюта, ДатаЦены); ЦенаЦены = глОкруглить(ЦенаЦены * (100 + ТипЦены.Процент) / 100, ТипЦены.ПорядокОкругления); // элемент справочника Цены не существует (расчетный). Валюту и Наценку возьмем из типа цены ВалЦены = ТипЦены.Валюта; НаценкаЦены = ТипЦены.Процент; КонецЕсли; ЦенаЦены = ЦенаЦены * Множитель; //[+]progadmin, 27.11.2019, НЕТИПОВОЕ Возврат Рез; КонецФункции // глВернутьЦену() |
|||
29
Злопчинский
27.11.19
✎
10:45
|
(27) ага, спсб.
я где-то тоже так делал, ЦеныНоменклатуры.ИспользоватьВладельца(Номенклатура); ЦеныНоменклатуры.ВыбратьЭлементыПоРеквизиту(....); //здеся... в 974 релизе (клиентовском) Сортировка=1 и Отбор=1 (не знаю штатно или нет это) |
|||
30
Злопчинский
27.11.19
✎
10:46
|
для ВыбратьПоРеквизиту() достаточно Сортировка=1
Отбор=1 - он для интерактивных отборов работает только. |
|||
31
Злопчинский
27.11.19
✎
10:49
|
И раз уже про глВернутьЦену() - то вот тоже еще полезняшка
http://catalog.mista.ru/public/76287/ - ускорение для конструкций типа Цикл ГлВернутьЦену() КОнецЦикла; |
|||
32
Djelf
27.11.19
✎
10:50
|
(28) Ээээ....
Если ЦеныНоменклатуры.ПометкаУдаления() = 1 Тогда Продолжить; с учетом твоего ВозвращатьУдаленнуюЦенаЦены должно быть Если ВозвращатьУдаленнуюЦенаЦены = 1 Тогда Прервать; ИначеЕсли ЦеныНоменклатуры.ПометкаУдаления() = 1 Тогда Продолжить; |
|||
33
Злопчинский
27.11.19
✎
10:52
|
И, наверное, можно еще так сказать:
в спр.Цены - помечать на удаление имеет смысл только если цены надо удалить кардинально с концами. если история нужна, то лучше оставлять цену "живой", но значение цены _на нужную_ (_с нужной даты_) ставить = 0 |
|||
34
Злопчинский
27.11.19
✎
10:53
|
вот, ух блин, работун страшный напал
|
|||
35
Злопчинский
27.11.19
✎
10:56
|
(32) не въехал (целый код давай ;-), бошка не варит уже после ночи.
мои исправления вроде все правильно должны дать (может и не оптимально). |
|||
36
Kigo_Kigo
27.11.19
✎
10:57
|
(32) Я честно не пнял замысел Злопа в этом кодинке, смысл этого всего
Есть не помеченная на удаления цена(совместно с помеченной) возвращаем не помеченную нет, возвращаем помеченную но с результатом "-1" далее в коде уже анализируем Если глВернутьЦену(трататата) = , тут уже варианты 0 -нет такой цены для переанного типацен, 1 есть цена, -1 естьцена но помечена на удаление, вот и вся арифметика |
|||
37
Kigo_Kigo
27.11.19
✎
10:58
|
(35) Твои исправления дадут отрицательную цену, вопрос, зачем?
|
|||
38
Kigo_Kigo
27.11.19
✎
10:58
|
ЦенаЦены = ЦенаЦены * Множитель;//[+]progadmin, 27.11.2019, НЕТИПОВОЕ
|
|||
39
Djelf
27.11.19
✎
11:00
|
(35) Да вот же
|
|||
40
Злопчинский
27.11.19
✎
11:03
|
(39) я подумаю.
|
|||
41
Kigo_Kigo
27.11.19
✎
11:04
|
(39) Так вы лишаете себя найти не удаленную цену, нахуя?
|
|||
42
Злопчинский
27.11.19
✎
11:06
|
а все почему: начал блок производства тихонька впиливать.
Печать техкарт с полным разузлованием (так это называется?) для расчета плановой себестоимости изделия (кузяво получается, из карточки номенклатуры, из комплектации или из документов заявкапокупателя/реализация). ну и наткнулся... чувствую, что где-то криво... |
|||
43
Kigo_Kigo
27.11.19
✎
11:07
|
ВозвращатьУдаленнуюЦенаЦены
Вообще эта врезка нахер не нужна |
|||
44
pechkin
27.11.19
✎
11:08
|
по хорошему не нужно останавдиваться когда нашел свой тип цен.
но это утормозит вс процедуру. поэтому на дубли просто забили |
|||
45
Kigo_Kigo
27.11.19
✎
11:23
|
(44) Ну если уж получать саму актульную цену из набора одинаковых типов цен для номенклатры, то тут уже через "переодический" кмк оптимальнее лезть
|
|||
46
Arbuz
27.11.19
✎
15:20
|
мда... заменил
//ЦеныНоменклатуры.ВыбратьЭлементы(); // //Пока ЦеныНоменклатуры.ПолучитьЭлемент() = 1 Цикл // Если ЦеныНоменклатуры.ТипЦен <> НужныйТипЦен Тогда // Продолжить; // КонецЕсли; // ------------- ЦеныНоменклатуры.ВыбратьЭлементыПоРеквизиту("ТипЦен", НужныйТипЦен,, 0); и вынес из функции глПустаяЦена = ПустоеЗначение("Справочник.Цены"); глСпрЦены = СоздатьОбъект("Справочник.Цены"); получил почти 25% ускорения на функции глВернутьЦену, неплохо |
|||
47
Злопчинский
27.11.19
✎
16:21
|
(46) ну, это критично на больших массивах вызовов глВернутьЦену, штатно таких глобальных потоковых глвернутьцену - разве что в отчете по опстаткам со столбиком цены.
а так, я давно обрабатывал (без прямых запросов) приличные массивы истории изменения нескольких цен. там использование объекта "Периодический" само по себе дает до 25% выигрыша по скорости |
|||
48
Кодер
27.11.19
✎
17:49
|
Всё не читал, если туплю - прошу извинить.
Добавлял одну константу и одну ТЗ. ПриНачалеСистемы заполнял ТЗ текущими ценами и устанавливал флажок "брать цены из ТЗ". В 1с++, наверное, можно индексированную ТЗ. Соответственно для быстрого получения цены смотрел на флаг, если он взведён - брал из ТЗ, это не дёргало БД, т.к. ТЗ была в ОЗУ. |
|||
49
Злопчинский
27.11.19
✎
18:45
|
(48) а как актуализировал ТЗ при изменении цен в базе?
|
|||
50
Duke1C
27.11.19
✎
19:05
|
(49) Видимо, никак. Либо обработкой ожидания, но это то ещё "гумно" в данном случае...
|
|||
51
Кодер
27.11.19
✎
22:37
|
Извините, отъезжал.
(49) При изменении цен сбрасывал флаг и всё работало типовым образом. |
|||
52
Злопчинский
27.11.19
✎
22:43
|
(51), ну... это неинтересно... ;-)
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |