![]() |
![]() |
![]() |
|
Регистры правил или проклятие вариативности. | ☑ | ||
---|---|---|---|---|
0
Гений 1С
гуру
31.10.06
✎
18:59
|
Сформулируем проблему в общем виде.
Допустим, есть некоторые параметры, например Подразделение, Вид подразделения, Уровень подразделения, Товар, Вид товара. И допустим для этих параметров нужно вычислять некоторые фунцкии, например Прибыль, Доход, Затраты, Маржа и т.п. Допустим эти функции считаются по разному для разных параметров. Например, прибыль в разных видах подразделений считается по разному. В итоге получается такой код: Если УровеньПодразделения=… Тогда Прибыль=...; Доход=…; Иначе Если Подразделение=... Тогда Прибыль=...; ИначеЕсли Подразделение=… И УровеньПодразделения=… Тогда Прибыль=...; ИначеЕсли Подразделение=… Тогда Прибыль=...; КонецЕсли; КонецЕсли; В общем случае получается офигенно длинный и запутанный код. Кто-нибудь применял в своей программистской практике альтернативу, или смирился с этим, как со злом? Я лично запарилси... |
|||
1
Волшебник
31.10.06
✎
19:30
|
Могу порекомендовать психолога, он изменит твоё отношение к такому коду и ты будешь считать это добром. Следовательно, проблема будет решена.
|
|||
2
avmlvm
31.10.06
✎
19:33
|
(1) А почему "психолога"? чЁ "Волшебника" для этого не достаточно? :-)))
|
|||
3
nbIx
31.10.06
✎
19:36
|
(0) Про какую альтернативу ты говоришь?
Можно конечно ингда уменьшить количество Если Тогда, но все зависит от конкретной задачи. |
|||
4
avmlvm
31.10.06
✎
19:36
|
(0) Если функции считаются по разному для разных параметров - то это РАЗНЫЕ функции... Т.е. Задача сводится, что бы по типу подразделения вызвать ПРАВИЛЬНУЮ функцию... Ну и чЁ тут сложного? :-)
|
|||
5
Темный Эльф
31.10.06
✎
19:38
|
Можно сделать справочник формул, задавать в реквизитах параметры и способы расчета, а затем просто искать по справочнику. У меня был отчет, в котором каждый месяц какие-то графы переносились со страницы на страницу, графы добавлялись, менялась ширина и положение колонок - так через полгода задолбался переделывать и каждый раз исправлять свои глюки, а сделал справочником настройки и сказал бухгалтеру - "Приспичило? Берите и меняйте!"
|
|||
6
nbIx
31.10.06
✎
19:43
|
(5) Да. Чем больше универсальности, тем лучше.
|
|||
7
Гений 1С
гуру
31.10.06
✎
19:45
|
(4) окей, это будет туча разных функций, но от этого количество Если не уменьшится....
Хотя на самом деле вот тебе контрпример. Функция Доступ(Пользователь, Объект, ВидДоступа), которая определяет имеет ли пользователь доступ к объекту. Функция одна, а вариантов - туева хуча! |
|||
8
Гений 1С
гуру
31.10.06
✎
19:45
|
(5) не то, не то... алгоритмы известны, но настолько много вариантов, что все выходит из-под контроля!
|
|||
9
Темный Эльф
31.10.06
✎
19:53
|
(8)Насколько много? Можно Шаблон использовать, можно вообще текст модуля создавать, а потом по ЗагрузитьИзФайла вызывать.
|
|||
10
Вуглускр
01.11.06
✎
07:15
|
(0) Не знаю как это будет по-русски, по-английски то что тебе нужно называется
|
|||
11
Вуглускр
01.11.06
✎
07:32
|
опаньки, не ту кнопку нажал
Короче, Design Patterns. Классическая книга на эту тему написана GoF. Вот очень хорошая книга, причем бесплатно - "Thinkig in Patterns", www.bruceeckel.com |
|||
12
Гений 1С
гуру
01.11.06
✎
10:05
|
Поясню на примере прав доступа, хотя у меня сейчас задача по бюджетированию, но по правам тоже заморочки бывают.
Функция Доступ(Пользователь, Объект, ВидДоступа) Если НаборПрав="Админ" Тогда //1 Возврат Истина; КонецЕсли; //Пользователю запрещено редактировать дату //2 Если НаборПрав="Пользователь" И Объект.Тип="ПриходнаяНакладная" Тогда Возврат ложь; КонецЕсли; //Контроль даты //3 Если НаборПрав="Пользователь" ИЛИ Набор="Оператор" Тогда Если текущаяДата-Объект.Дата()>24*3600 Тогда Возврат ложь; КонецЕсли; КонецЕсли; ... КонецФункции т.е. как видим нужно правильно указывать последовательность, потому что если мы перепутаем местами 2 и 3, результат будет другой... |
|||
13
Defender aka LINN
01.11.06
✎
10:18
|
(12) Ж8-[ ] Это у тебя и правда такое в конфе?
Жесть... |
|||
14
Гений 1С
гуру
01.11.06
✎
10:45
|
(13) да
|
|||
15
Гений 1С
гуру
01.11.06
✎
10:45
|
Примерно
|
|||
16
Господин ПЖ
01.11.06
✎
10:58
|
Акуеть просто...
|
|||
17
asssa
01.11.06
✎
11:03
|
А рекурсия не поможет?
|
|||
18
Neco
01.11.06
✎
12:15
|
Ты же сам идеи толкал как в 1Ске Exel сделать. Ну так вперед. Реализуй.
|
|||
19
Гений 1С
гуру
01.11.06
✎
12:44
|
(17) тут ваще все слишком сложно, рекурсия - не поможет...
|
|||
20
Гений 1С
гуру
01.11.06
✎
12:45
|
(18) а каким боком здесь эксель поможет...
это фундаментальный вопрос |
|||
21
Salvador Limones
01.11.06
✎
12:47
|
(20) Тебя это беспокоит? Хочешь поговорить об этом?
|
|||
22
Гений 1С
гуру
01.11.06
✎
12:50
|
обобщенно вопрос можно сформулировать так.
Есть некая функция F(A1, A2, ..... AК). Эта функция принимает различные значения при различных наборах А1....АК. Значения могут повторяться. В случае функции Доступ таких значений вообще только 2 - истина или ложь. Возможна реализация следующим образом - составляется таблица различных значений А1.....АК и пишется для них значения. Но в общем случае таблица может быть офигенно большой. Как минимизировать таблицу, исходя из того, что мы знаем много частных случаев, когда принимаются те или иные значения при различных наборах параметров? |
|||
23
Бриарей
01.11.06
✎
13:07
|
(22) Полиморфизм тебе поможет
|
|||
24
Гений 1С
гуру
01.11.06
✎
13:21
|
(23) я думаю, мне поможет регистр правил... ;-(
|
|||
25
Гений 1С
гуру
01.11.06
✎
13:21
|
еще бы сообразить, как его соорудить.
|
|||
26
Asmody
01.11.06
✎
13:25
|
(25) гугл, первая строчка в выдаче: http://www.kint.ru/k.pl?p=110
|
|||
27
Гений 1С
гуру
01.11.06
✎
13:26
|
(26) это я уже читал, только это не очень то применишь к моему случаю. ;-)
|
|||
28
Asmody
01.11.06
✎
13:28
|
(27) да ладно. если и умом и руками подойти, на регистрах сведений можно реализовать регистры правил...
|
|||
29
Гений 1С
гуру
01.11.06
✎
13:28
|
(28) я не про то, что реализовать нельзя, просто не очень поможет наличие регистров правил. ;-)
|
|||
30
Бриарей
01.11.06
✎
13:42
|
(29) РП предназначен для хранения детерминированных корней. В данной задаче корень (прибыль, доход и т.д.) не детерминирован.
Юзай полиморфизм. |
|||
31
Scooter
01.11.06
✎
13:47
|
Смотри как в УПП бюджетирование сделано
перенеси подсистему если нужно |
|||
32
Wasya
01.11.06
✎
13:58
|
(0) Сам спрашиваешь и сам отвечаешь. Так делай регистр правил.
|
|||
33
Neco
01.11.06
✎
14:42
|
+(31) Система финансовых расчетов (Справочник финансовые расчеты + Отчеты)
|
|||
34
Гений 1С
гуру
01.11.06
✎
16:22
|
Я просто продемонстрирую код, чтобы вы поняли, как я извращаюсь.
Итак функция Показатель(П) вызывается для каждой ячейки отчета. П.Строка - ссылка на строку отчета П.Колонка - ссылка на строку отчета. Каждая строка и колонка отчета имеют уникальный идентификатор. П.Строка.Схема и П.Колонка.Схема - структуры, заполняются из таблицы, где напротив каждого идентификатора стоит список параметров, таких как ВидИтога, ФормулаИтога, ФормулаПростая, ФормулаАгрегатная и т.п. Получается нехилый если - то... Функция Показатель(П) Перем Показатель, Р; Перем С; Если НЕ П.Дерево.Данные.Свойство("ПараметрыВычислений") Тогда ДанныеПараметрыВычислений(П); П.Дерево.Данные.Вставить("ПараметрыВычислений", истина); КонецЕсли; С=П.Дерево.Данные; // Агрегат - используется для указания, что отчет представляет собой агрегат подотчетов // ЛистыСуммированияФакта // ЛистыСуммированияПлана // ЛистыСуммированияБюджета //Смотрим, какой показатель мы расчитываем Показатель=П.Строка.Схема.Идентификатор; //Определяем колонку Колонка=П.Колонка.Схема.Идентификатор; //Если итог по колонке считается по другому, указать специфику здесь //Для Колонки итого Если Колонка="ИтогПоКолонке" Тогда Если П.Строка.Схема.ВидИтога="Сумма" Тогда Возврат фоСумма(П,"@КолонкаМесяца"); КонецЕсли; //Берется значение последнего месяца Если П.Строка.Схема.ВидИтога="Последний" Тогда Возврат фоЗнач(П, "@М12"); КонецЕсли; //Берется значение первого месяца Если П.Строка.Схема.ВидИтога="Первый" Тогда Возврат фоЗнач(П, "@М1"); КонецЕсли; //Берется среднее значение по месяцам Если П.Строка.Схема.ВидИтога="Среднее" Тогда Возврат фоОКДеление(фоСумма(П,"@КолонкаМесяца"), 12,2); КонецЕсли; //А может быть есть явная формула итога? Если П.Строка.Схема.ФормулаИтога<>Неопределено Тогда Возврат ВычислитьФормулу(П, П.Строка.Схема.ФормулаИтога); КонецЕсли; //Иначе колонка итого считается так же, как и помесячная колонка ИначеЕсли Колонка="ФактПрошлогоГода" ИЛИ Колонка="ПланПрошлогоГода" Тогда //Простое суммирование за прошлые месяцы //Если фоКатегория("УВР_Департамент;УВР_Управление", П.ОбщийВидОтчета) Тогда // Листы=ДанныеЛисты; //КонецЕсли; //Если нужно суммирование данных подотчетов Если С.Агрегат Тогда //Смотрим, определена ли формула для агрегатных отчетов Формула=П.Строка.Схема.ФормулаАгрегат; Если Формула<>Неопределено И Формула<>"Сумма" Тогда Возврат ВычислитьФормулу(П, Формула); КонецЕсли; //Если формула не определена, но этот показатель подвержен суммированию //то считаем как обычную сумму листов книги //Или если явно указано, что нужно суммировать //Тогда суммируем подотчеты Если Формула="Сумма" ИЛИ фоЭтоКатегория("Сумма;Последний;Первый", П.Строка.Схема.ВидИтога) Тогда //Определяем, какие листы книги суммировать Листы=?(Колонка="ФактПрошлогоГода", С.ЛистыСуммированияФакта, С.ЛистыСуммированияПлана); //Если значение не заполнено, то оно не будет и учитываться Возврат ДанныеСуммаЛистов(П, П.Строка.Идентификатор, П.Строка.Значение, , Листы); КонецЕсли; КонецЕсли; //Смотрим, есть ли формула для вычисления факта/плана, если есть, она и используется Формула=П.Строка.Схема[Колонка]; Если Формула<>Неопределено Тогда Возврат ВычислитьФормулу(П, Формула); КонецЕсли; //Иначе данные по факту/плану считаются по обычной схеме месяца, по обычной формуле для месяца КонецЕсли; //Частные случаи по месяцам описываются здесь //В противном случае колонка итого расчитывается так же, как и месячный показатель Формула=П.Строка.Схема.ФормулаПростая; Возврат ВычислитьФормулу(П, Формула); КонецФункции Функция ВычислитьФормулу(П, Формула, Р=Неопределено) Если Формула="-" Тогда Возврат Неопределено; КонецЕсли; Возврат обВыполнитьФормулуСПараметром(Формула, П, Р); Возврат Р; КонецФункции |
|||
35
Гений 1С
гуру
01.11.06
✎
16:23
|
(33) слишком простая модель для нашей конторы
|
|||
36
ОбычныйЧеловек
01.11.06
✎
16:31
|
(Гений 1С) если тебе "регистр правил" не поможет то тебе уже ничего не поможет.
|
|||
37
France
01.11.06
✎
19:45
|
я бы пошел как в (30).. классический случай..
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |