|
Формула с условием в УНФ | ☑ | ||
---|---|---|---|---|
0
vladimir80
11.04.17
✎
17:21
|
Всем привет! В УНФ есть механизм динамического формирования цен в зависимости от статического, опорного типа цен. Весь механизм по сути - замена строки идентификатора типа цен на значение цены и вычисление методом Вычислить()....
К сожалению, в нашем случае это не сильно удобно, т.к. существуют несколько статических типов цен (пример - Закупочная и РекомендованнаяЗаводом), и в зависимости от этих цен нужно формировать ту или иную цену по типу Если [РекомендованнаяЗаводом] > 0 Тогда [РекомендованнаяЗаводом] Иначе [Закупочная] * 1.35 КонецЕсли Собственно вопрос - можно ли как-то оформить обработку такого кода, если да, то с помощью каких методов встроенного языка... |
|||
1
AlvlSpb
11.04.17
✎
17:25
|
(0) Поясните задачу. Вам нужно формирование прайс листа или установка цен в документах? Т.е. оформляем приходную и в нее подтягиваются либо Рекомендованное заводом (при наличии) либо Закупочная (нет рекомендованных)
|
|||
2
vladimir80
11.04.17
✎
17:29
|
Формирование прайс-листа. Если быть совсем точным, то изменение процедуры
ЦенообразованиеФормулыСервер.РасчетДанныхПоФормуле() |
|||
3
AlvlSpb
11.04.17
✎
17:35
|
(2) Еще одно уточнение. Вы хотите, чтобы в прайс выводились разные цены? Т.е. при наличии рекомендованных заводом - они, если таковых нет - закупочная*1,35. Правильно понял?
|
|||
4
AlvlSpb
11.04.17
✎
17:36
|
Какая версия УНФ? Не нашел что-то такой процедуры в своей 1.6.10.27
|
|||
5
vladimir80
11.04.17
✎
17:40
|
(3) Возможно Вы незнакомы с механизмом ценообразования в УНФ. Там не вывод в прайс, а именно формирование цен для динамического типа цены по формуле от опорного статического. Версия последняя, 1.6.9.36 (!), 10 еще нет...
|
|||
6
AlvlSpb
11.04.17
✎
17:40
|
(4) Вопрос снимаю. нашлась )), а вопрос (3) остается
|
|||
7
AlvlSpb
11.04.17
✎
17:45
|
(5) ))) есть есть, тестовая. Но это другой вопрос. Вы не ответили. Вернее ответили, что опять непонятно. С УНФ работаю с 2012-го, поэтому уточняю: Динамическая цена вам нужна для предоставления прайс-листа покупателям или для подстановки в документы продажи?
|
|||
8
vladimir80
11.04.17
✎
17:47
|
По сути вопроса - да, =0, больше, меньше и т.п. Условия чисто математические.
Наверное можно распарсить конструкцию, или заключить условную конструкцию в спецсимволы и проверять истинность, а значения после Тогда и Иначе обрабатывать через Вычислить... Динамическая цена нужна для подставновки в документы, выгрузки на сайт, и еще много где. Наверное я просто не понимаю цели вопроса. По сути хочу получить тип цен "Розничная". |
|||
9
AlvlSpb
11.04.17
✎
17:47
|
Не поймите неправильно, это не занудство. Разные подходы возможны. Для формирования прайса, наверное, придется вносить изменения в общий модуль (то что вы написали), а если для документа, то проще расширением не формировать, а выбирать цену из регистра сведений
|
|||
10
Вафель
11.04.17
✎
17:49
|
(8) Открой для себя функцию "?"
|
|||
11
vladimir80
11.04.17
✎
17:51
|
Работаю через расширения, поэтому изменения меня не беспокоят. Я понял что есть смысл в вопросе. Но мне нужно получать цены в РС ЦеныНоменклатуры.
(10) Сразу нет, мне придется открыть тогда и язык 1с для людей, которые в экселе неспособны формулу написать, да и конструкции с иначеесли превратят ? в такую кашу, что разобрать ее визуально будет практически невозможно |
|||
12
Вафель
11.04.17
✎
17:52
|
(11) Тогда мучайся дальше
|
|||
13
Вафель
11.04.17
✎
17:53
|
(11) напиши простой вид такого выражения из (0), которое может понять и менеджер-сапожник
|
|||
14
vladimir80
11.04.17
✎
17:59
|
(13) Это понятно, что за неимением служанки сойдет и дворецкий. Если обработать "Если" из 1с нельзя, напишу парсер выражения и сделаю красиво. Вопрос в том, что возможно кто-то решал уже подобную задачу, или имеет взгляд на решение, отличный от моего, в общем то поэтому и вопрос.
В итоге хочется получить решение, доступное пользователю, а не костыль. На сложных условиях, как по мне, будет некрасиво. |
|||
15
AlvlSpb
11.04.17
✎
18:06
|
(11) В документ вставить несложно. В ПриСозданииНаСервере делаете Запрос к РС ЦеныНоменклатурыСрезПоследних Выбираете актуальные цены РекомендованныеЗаводом и Закупочные, а в выборке условие Если ЗначениеЗаполнено(Рекомендованные) Тогда Выборка.Рекомендованные Иначе Выборка.Закупочные*1,35
А вот с прайсом, что-то первоначальная моя мысль не сработает. Там расчет по всем введенным товарам. Надо подумать |
|||
16
AlvlSpb
11.04.17
✎
18:07
|
Если ЗначениеЗаполнено(Выборка.Рекомендованные)*
|
|||
17
vladimir80
11.04.17
✎
19:28
|
(16) написать в коде процедуры несложно... Сложно задать кучу разносторонних условий, вводимых пользователем, и обрабатывать это...
По склоняюсь к мысли парсить все в некий массив структур с ключами условие и формула. Если условие дает истину, то отдавать формулу, если нет переходить к следующему условию, если условие пустое (после Иначе), то отдавать последнее условие. По сути все реализуемо, главное правильно распарсить текст условия и добавить проверку на корректность введенных данных... |
|||
18
vladimir80
11.04.17
✎
19:34
|
Написал, сам не понял...
Массив значение элемента массива - структура Ключи структуры - "Условие" (формула строкой, берется между если и тогда) - "Значение" (Формула строкой, берется между тогда и Иначе) Если это последний сегмент, между иначе и конец если, то ключ условия пустой или заведомо истина, значение - формула В цикле массив прогоняем через вычислить условие и если истина - отдаем вычислить значение с прерыванием цикла. Как то так. Если есть мысли как сделать красивее - буду рад выслушать. |
|||
19
AlvlSpb
11.04.17
✎
20:22
|
(18) Т.е. у вас регулярно меняются цены. Не проще тогда просто использовать минусовые процентные скидки от какой-то базовой цены (та же формула, установленная вручную), а чтобы не нервировать клиента просто переделать печатную форму, чтобы выводилась только цена уже со скидкой
|
|||
20
vladimir80
11.04.17
✎
20:38
|
(19) Ну и цены регулярно меняются, и цены поставщиков могут отличаться, и еще есть условие на ~15% ассортимента в виде РекЦены, ниже которой показывать нельзя.
Печатные формы меня сильно не интересуют, основной упор на интернет-магазины. РекЦены могут формироваться ооочень своеобразно, т.е. % скидки/наценки от дилерской цены это реализовать невозможно. Поэтому и пришла мысль сделать более вариативным ценообразование. На самом деле механизм интересный, но кастрированный, уже допилил ТЧ в вид цены, для установки фиксированных цен, отдельных формул скидок по ценовым группам и т.п. |
|||
21
AlvlSpb
11.04.17
✎
20:43
|
(20) Тогда опять как вариант. В расширении в форму ввести поле куда менеджер вводит формулу, а уже в документе во всех или только выделенных строках установленная рекомендованная цена пересчитывается по этой формуле
|
|||
22
vladimir80
11.04.17
✎
20:55
|
(21) Как вариант, да. Но на практике - костыль.
1 - неизвестно, в скольких местах придется внести эту формулу 2 - При изменении формулы будет невозможно отследить историю цен В любом случае спасибо за варианты, интересно обдумать со всех сторон. |
|||
23
vladimir80
11.04.17
✎
22:11
|
Вот что придумалось, криво конечно, буду рад советам по улучшению и упрощению...
Получив массив делаем цикл по нему, и если условие верно то передаем формулу. Последнее условие всегда верное. Код должен быть в формате, указанном в (0) Функция РазложитьУсловияВМассив(ТекстУсловия) МассивПодстрок = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(НРег(ТекстУсловия), "тогда", ложь); КоличествоПодстрок = МассивПодстрок.Количество(); МассивУсловийЗначений = Новый Массив; индекс = 0; Для Каждого м ИЗ МассивПодстрок Цикл СтруктураУсловий = Новый Структура; Если индекс = 0 Тогда // получаем только условие СтруктураУсловий.Вставить( "Условие", ПочиститьСтроку(м)); МассивУсловийЗначений.Добавить(СтруктураУсловий); индекс = индекс + 1; Продолжить; КонецЕсли; МассивСтроки = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(м, "иначе", ложь); Если индекс = (КоличествоПодстрок - 1) Тогда МассивУсловийЗначений[индекс - 1].Вставить("Значение", ПочиститьСтроку(МассивСтроки[0]) ); СтруктураУсловий = Новый Структура; СтруктураУсловий.Вставить("Условие", "1=1"); СтруктураУсловий.Вставить("Значение", ПочиститьСтроку(МассивСтроки[1])); МассивУсловийЗначений.Добавить(СтруктураУсловий); Возврат МассивУсловийЗначений; КонецЕсли; МассивУсловийЗначений[индекс - 1].Вставить("Значение", ПочиститьСтроку(МассивСтроки[0]) ); СтруктураУсловий.Вставить("Условие", ПочиститьСтроку(МассивСтроки[1])); МассивУсловийЗначений.Добавить(СтруктураУсловий); индекс = индекс + 1; КонецЦикла; Возврат МассивУсловийЗначений; КонецФункции Функция ПочиститьСтроку(Т) Т = СтрЗаменить(НРег(Т), "если", ""); Т = СтрЗаменить(Т, "тогда", ""); Т = СтрЗаменить(Т, "иначе", ""); Т = СтрЗаменить(Т, "конец", ""); Возврат СокрЛП(Т); КонецФункции |
|||
24
Мимохожий Однако
11.04.17
✎
23:16
|
Может быть, посмотреть в сторону видов расчета в ЗУП и регистров расчета? Смешно, конечно. Но там есть формулы
|
|||
25
vladimir80
11.04.17
✎
23:21
|
(24) да в принципе работает все... только синтаксис формулы бы еще проверять...
|
|||
26
vladimir80
12.04.17
✎
00:29
|
&НаСервере
&Вместо("РасчетДанныхПоФормуле") Процедура Расш1_РасчетДанныхПоФормуле(Знач ФормулаСтрокой, СтруктураОперандов, РасчетныеДанные = Неопределено, ОкруглятьВБольшуюСторону = Неопределено, ПравилоОкругления = Неопределено) Экспорт ....... Для каждого Операнд Из СтруктураОперандов Цикл ФормулаСтрокой = СтрЗаменить(ФормулаСтрокой, Операнд.Ключ, Операнд.Значение); КонецЦикла; Если СтрНайти(ВРег(ФормулаСтрокой), "ЕСЛИ") > 0 Тогда ЗначениеФормулы = Неопределено; МассивУсловий = РазложитьУсловияВМассив(ФормулаСтрокой); Для Каждого Условие ИЗ МассивУсловий Цикл Если Вычислить(Условие.Условие) Тогда ЗначениеФормулы = Условие.Значение; Прервать; КонецЕсли; КонецЦикла; КонецЕсли; ФормулаСтрокой = ?(ЗначениеФормулы = Неопределено, ФормулаСтрокой, ЗначениеФормулы); ......... КонецПроцедуры Функция РазложитьУсловияВМассив(ТекстУсловия) МассивПодстрок = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ТекстУсловия, "Тогда", ложь); КоличествоПодстрок = МассивПодстрок.Количество(); МассивУсловийЗначений = Новый Массив; индекс = 0; Для Каждого м ИЗ МассивПодстрок Цикл СтруктураУсловий = Новый Структура; Если индекс = 0 Тогда // получаем только условие СтруктураУсловий.Вставить( "Условие", ПочиститьСтроку(м)); МассивУсловийЗначений.Добавить(СтруктураУсловий); индекс = индекс + 1; Продолжить; КонецЕсли; МассивСтроки = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(м, "Иначе", ложь); Если индекс = (КоличествоПодстрок - 1) Тогда МассивУсловийЗначений[индекс - 1].Вставить("Значение", ПочиститьСтроку(МассивСтроки[0]) ); СтруктураУсловий = Новый Структура; СтруктураУсловий.Вставить("Условие", "1=1"); СтруктураУсловий.Вставить("Значение", ПочиститьСтроку(МассивСтроки[1])); МассивУсловийЗначений.Добавить(СтруктураУсловий); Возврат МассивУсловийЗначений; КонецЕсли; МассивУсловийЗначений[индекс - 1].Вставить("Значение", ПочиститьСтроку(МассивСтроки[0]) ); СтруктураУсловий.Вставить("Условие", ПочиститьСтроку(МассивСтроки[1])); МассивУсловийЗначений.Добавить(СтруктураУсловий); индекс = индекс + 1; КонецЦикла; Возврат МассивУсловийЗначений; КонецФункции Функция ПочиститьСтроку(Т) Т = СтрЗаменить(Т, "Если", ""); Т = СтрЗаменить(Т, "Тогда", ""); Т = СтрЗаменить(Т, "Иначе", ""); Т = СтрЗаменить(Т, "Конец", ""); Возврат СокрЛП(Т); КонецФункции |
|||
27
vladimir80
12.04.17
✎
00:32
|
Работает. Если кто-нибудь захочет упростить, добавить проверку синтаксиса или сделает красиво обход различного регистра идентификатора формул и слов конструкций - пишите!
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |