Имя: Пароль:
1C
 
Тернарные операторы в 1С
0 svsvsv
 
10.10.17
14:23
Уважаемые коллеги!
Есть ли у вас какие-то правила (для себя) по использованию тернарных операторов определенного уровня вложенности? (например, не использовать тернарный оператор внутри тернарного оператора).
И вообще, используете ли вы его?

Наткнулся на следующее Г, поэтому и возник вопрос:

ПериодПо = ?(Шапка.ЭтоУвольнение, Шапка.Дата, ?(Шапка.ЭтоАванс, Дата(Год(Шапка.ПериодРегистрации), Месяц(Шапка.ПериодРегистрации), 15), КонецМесяца(Шапка.ПериодРегистрации)));
1 Йохохо
 
10.10.17
14:28
(0) это Г только если это не твое Г )
2 Numerus Mikhail
 
10.10.17
14:28
Использую не больше 1 вложенного.
Пример из (0) вполне читабельный.
3 azernot
 
10.10.17
14:30
Использую. Регулярно. В т.ч. вложенные.
Как правило при формировании какой-либо строки (например, текста запроса). Но бывает и подобное (0), если есть чёткое булево условия как в (0), то почему бы и нет?
4 lubitelxml
 
10.10.17
14:31
(2) +1
5 Asmody
 
10.10.17
14:32
(0) А если переписать вот так:

ПериодПо = ?(Шапка.ЭтоУвольнение
           , Шапка.Дата
           , ?(Шапка.ЭтоАванс
             , Дата( Год(Шапка.ПериодРегистрации)
                   , Месяц(Шапка.ПериодРегистрации)
                   , 15
                   )
             , КонецМесяца(Шапка.ПериодРегистрации)
             )
           );
6 svsvsv
 
10.10.17
14:32
(2) Он читабельный, т.к. на мисте шрифт мельче, чем в конфигураторе (скажем, EDT-style)
В конфигураторе это 176 символов, не помещается в экран
7 Asmody
 
10.10.17
14:33
(5)+ хотя формирование даты просится отрефакториться в функцию
8 vde69
 
модератор
10.10.17
14:34
(5) лучше так

Если не Шапка.ЭтоУвольнение и Шапка.ЭтоАванс Тогда
  ПериодПо = Дата(Год(Шапка.ПериодРегистрации), Месяц(Шапка.ПериодРегистрации), 15);
ИначеЕсли не Шапка.ЭтоУвольнение Тогда
  ПериодПо = КонецМесяца(Шапка.ПериодРегистрации);
Иначе
  ПериодПо = Шапка.Дата
КонецЕсли;
9 svsvsv
 
10.10.17
14:34
(7) я и отрефакторил в функцию. Еще заменил "?" на "Если", а то не очень удобно смотреть, хоть и в одну строчку
10 Asmody
 
10.10.17
14:36
(8) Не лучше. Три присваивания вместо одного - потенциальный источник проблем.
11 Fedor-1971
 
10.10.17
14:37
(0) нормально читается так:
ПериодПо = ?(Шапка.ЭтоУвольнение,
             Шапка.Дата,
            ?(Шапка.ЭтоАванс, Дата(Год(Шапка.ПериодРегистрации), Месяц(Шапка.ПериодРегистрации), 15), КонецМесяца(Шапка.ПериодРегистрации)));

При рефакторинге имеет смысл переделывать на Если ... КонецЕсли;
12 Asmody
 
10.10.17
14:38
Я бы всё это вынес в функцию.
13 vde69
 
модератор
10.10.17
14:38
(10) Вы не правы, все три присвоения никогда не выполняются все вместе...

а из плюсов - любой из трех результатов наглядно записан в виде одной строчки, это примерно как case в других языках
14 vde69
 
модератор
10.10.17
14:41
ну и можно еще так


ПериодПо = Шапка.Дата //инициализация

Если не Шапка.ЭтоУвольнение Тогда
Если Шапка.ЭтоАванс Тогда
  ПериодПо = Дата(Год(Шапка.ПериодРегистрации), Месяц(Шапка.ПериодРегистрации), 15);
Иначе
  ПериодПо = КонецМесяца(Шапка.ПериодРегистрации);
КонецЕсли;
15 H A D G E H O G s
 
10.10.17
14:42
Не использую дичь вида
?
16 svsvsv
 
10.10.17
14:43
Я бы сделал так:

ПериодПо = Шапка.Дата//инициализация
ПериодРегистрации = Шапка.ПериодРегистрации;
Если Не Шапка.ЭтоУвольнение Тогда
Если Шапка.ЭтоАванс Тогда
  ПериодПо = Дата(Год(ПериодРегистрации),Месяц(ПериодРегистрации), 15);
Иначе
  ПериодПо = КонецМесяца(ПериодРегистрации);
КонецЕсли;

то есть добавил бы это:

ПериодРегистрации = Шапка.ПериодРегистрации;
17 Fragster
 
гуру
10.10.17
15:10
ПериодПо = ?(Шапка.ЭтоУвольнение, Шапка.Дата,
           ?(Шапка.ЭтоАванс, Дата(
                Год(Шапка.ПериодРегистрации)
                   , Месяц(Шапка.ПериодРегистрации)
                   , 15
                ),
           КонецМесяца(Шапка.ПериодРегистрации)
           ));
18 sitex
 
naïve
10.10.17
15:16
(0) Использую, причем но не более 3-4 вложенных. Далее просто становиться не читабельно.
19 drcrasher
 
10.10.17
15:17
(17)(5) за такой перенос запятой 1С смело разворачивает конфу на исправление
20 Fragster
 
гуру
10.10.17
15:19
(19) ты про запятую в начале в функции Дата? это мне тоже не нравится
21 oslokot
 
10.10.17
15:19
(0) ? использую, но без вложений
22 Fragster
 
гуру
10.10.17
15:19
ПериодПо = ?(Шапка.ЭтоУвольнение, Шапка.Дата,
           ?(Шапка.ЭтоАванс, Дата(
                   Год(Шапка.ПериодРегистрации),
                   Месяц(Шапка.ПериодРегистрации),
                   15
                ),
           КонецМесяца(Шапка.ПериодРегистрации)
           ));
23 drcrasher
 
10.10.17
15:22
(20) да. у них вообще много интересных требований к коду, сначала плеваться тянет, потом втягиваешься и даже логичность некоторая видна
24 Asmody
 
10.10.17
15:57
(19) 1С может ходить нахер. Или пусть опубликуют codestyle.
В таком стиле ты никогда не пропустишь и не забудешь запятую.
25 kittystark
 
10.10.17
16:11
(24) +1
26 Сти
 
10.10.17
16:13
(5) Это хорошо, когда платят за количество строк кода. Как по мне, так чем более кратко, тем лучше. После Perl, наверное )))
27 Fragster
 
гуру
10.10.17
16:41
в https://its.1c.ru/db/content/v8std/src/d810/i8100444.htm?_=1507132762 именно про запятые ничего нету
28 Ненавижу 1С
 
гуру
10.10.17
16:44
А почему 1С решила извратить этот классческий оператор?

Результат = Условие ? ПоложительныйОтвет, ОтрицателныйОтвет;
29 ptiz
 
10.10.17
16:56
В нашем деле, главное - читаемость кода. Вложенные "?" читаемость портят.
30 Fedor-1971
 
10.10.17
17:10
(28) Взяли за основу С
Вот так красивее:
Результат = ? Условие : ПоложительныйОтвет, ОтрицателныйОтвет;
31 Asmody
 
10.10.17
17:23
(28) (30) А разве не так:

<условие> ? <еслида> : <еслинет>;
32 Asmody
 
10.10.17
17:24
1С вообще сделали этот оператор как-бы функцией, каковой он не является.
Зато в 7.7 с его помощью делалась "ленивая" проверка условий.
33 тарам пам пам
 
10.10.17
17:26
Использую без вложенных. Пример вполне читабелен, но от вложенного ? я бы все равно избавился.
34 Филиал-msk
 
10.10.17
17:28
(28) (30) Да тоже, когда язык проектировали, забыли как пишется.
35 Филиал-msk
 
10.10.17
17:29
(32) Особенности реализации стековой машинки, очевидно. Дерево разбора у них ЕМНИП, только в эклипсе и появилось, до этого - тупая попытка компиляции и смотрим что получилось
36 Asmody
 
10.10.17
17:38
(35) хотя для ?() они все аргументы не вычисляют
37 mexanik_96
 
10.10.17
17:39
(0) сложные условия обычно объединяют(речь не про 1с) в переменную. Фиксин по моему даже писал где-то об этом
38 Филиал-msk
 
10.10.17
17:44
(36) Синтаксическая глюкоза от 1С (:
39 Fragster
 
гуру
10.10.17
18:39
(32) что в ?() что в ЕСЛИ - проверка ленивая
40 Филиал-msk
 
10.10.17
19:34
(39) в 7.7 нет
41 PiotrLoginov
 
10.10.17
19:54
(0) Тогда уж голосовалку.

Код в (0) очень даже норм.
42 Fragster
 
гуру
10.10.17
20:33
(40) да
43 Лефмихалыч
 
10.10.17
22:08
(0) правило простое - тернарные операторы должны быть простыми и укладываться в голове с одного прочтения. Если приходится читать по частям, то надо рефакторить.
Код в топике - УГ, фу так делать
44 Брудвар
 
10.10.17
23:17
(43) Да вроде норм. С одного раза все понятно
45 kittystark
 
10.10.17
23:49
вот как надо

Если ?(Отмерь(),?(Отмерь(),?(Отмерь(),?(Отмерь(),?(Отмерь(),?(Отмерь(),Отмерь(),ложь),ложь),ложь),ложь),ложь),ложь) тогда
Отрежь();
КонецЕсли
46 kittystark
 
10.10.17
23:52
если позаботиться о читабельности, то так выглядит лучше

Если ?(Отмерь(),
         ?(Отмерь(),
             ?(Отмерь(),
                 ?(Отмерь(),
                     ?(Отмерь(),
                         ?(Отмерь(),Отмерь(),ложь),
                         ложь),
                       ложь),
                     ложь),
                   ложь),
                 ложь)
Тогда
    Отрежь();
КонецЕсли
47 kittystark
 
10.10.17
23:53
поэтому (5) самый наиприемлемый варинат
48 kittystark
 
10.10.17
23:58
и зачастую, когда в запросе наворотишь условий со всякими И / ИЛИ, да ещещ перевложенными в скобочках, чтоб понимать суть условия приходится  делать отступы и потом НЕ ПОЛЬЗОВАТЬСЯ конструктором, чтобы потом вся "логическая"не слетела нах, после его "стандартизации"
49 kittystark
 
10.10.17
23:59
* "логическая Красота"
50 Asmody
 
11.10.17
00:24
(48) А вот если в запросе наворотишь вот это всё, то это 100% рефакторить надо.
51 VladZ
 
11.10.17
06:28
(0) Для себя решил так: вложенные конструкции в "?" не использовать.
52 Рэйв
 
11.10.17
06:57
(0)Только если под настроение для прикола могу навернуть:-)
А вообще стараюсь если есть вложенность, то использовать Если...Тогда.
Потому что потом сам материшься спустя какое то время разгадывая  этот ребус:-)
53 Ненавижу 1С
 
гуру
11.10.17
09:00
А вот если бы в SQL писали бы не

select
case
    when x>1000 then y1000
    when x>100  then y100
    when x>10   then y10
    else             y0
end as Y

а вот так (а ля Си-лайк):

select
Y = x>1000    ? y1000    :
    x>100    ? y100    :
    x>10    ? y10    :    
              y0
54 Сияющий в темноте
 
11.10.17
09:29
select case в запросах 1с прекрасно реализован
Проблемы невозможно решaть нa том же уровне компетентности, нa котором они возникaют. Альберт Эйнштейн