Имя: Пароль:
1C
1С v8
О применении "Пока Истина Цикл"
,
0 Ksandr
 
21.09.11
17:45
Сегодня, наконец, понял для чего в типовых такая конструкция.
Она отлично помогает выделить блок, который нужно выполнить, если на каком то участке блока необходимо выйти из блока, например:

Пока Истина Цикл

Произвольный_Код
// Результат нас устраивает?
// Если да
Прервать;

//Идем далее
Произвольный_Код2
// Результат нас устраивает?
// Если да
Прервать;

..............
Прервать;
КОнецЦикла;

Есть ли у кого-нибудь аргументы за и против использования такого подхода?
1 DJ Anthon
 
21.09.11
17:47
ты сам понял, что сказал?
2 rutony
 
21.09.11
17:48
Маразм...
3 Goggy
 
21.09.11
17:50
(0)Ну тебе всамы раз в руки такой руль :)

Перейти ~Метка1;
....
~Метка1:
4 Ksandr
 
21.09.11
17:52
(3) Так это как раз более прямая альтернатива меткам.
5 Anempadest
 
21.09.11
17:54
А чем не нравится Если...Тогда?
6 Ksandr
 
21.09.11
17:54
(3) т.к. одним из минусов меток является то, что можно долго ломать голову над тем как же выполнение кода оказалось именно в этом месте - тут такого вопроса не возникает
7 Fragster
 
гуру
21.09.11
17:57
для выделения блоков есть процедуры
8 Ksandr
 
21.09.11
17:57
(5) допустим есть 5 вариантов поиска элемента.
Писать:
Если НеНашли Тогда
ПроизвольныйКод
КонецЕсли
Если НеНашли Тогда
ПроизвольныйКод
КонецЕсли
Если НеНашли Тогда
ПроизвольныйКод
КонецЕсли
Если НеНашли Тогда
ПроизвольныйКод
КонецЕсли
Если НеНашли Тогда
ПроизвольныйКод
КонецЕсли

Это достаточно простой пример, в реальности он может быть куда сложнее.
9 Ksandr
 
21.09.11
18:01
(7) Согласен. Этим подходом и пользуюсь, просто сегодня понял, зачем в типовых делают однопроходный цикл вида - Пока Истина Цикл, чтобы выйти из него на произвольном участке кода.
10 Grusswelle
 
21.09.11
18:02
Господи, Иисусе! (с) South park
11 Anempadest
 
21.09.11
18:03
Обычно в таких случаях я пишу внешнюю функцию, внутри которой проверяю значение, а функция уже возвращает "Удовлетворяет или не удовлетворяет". И если говорить об удобстве разбора кода, то мой вариант также претендует на удобство и красоту. Например:
...
Если ПроверитьСоответствиеЗначенияЗаданномуУсловию(ТекЗначение) Тогда
 //произвольный код
КонецЕсли
...
КонецПроцедуры

Функция ПроверитьСоответствиеЗначенияЗаданномуУсловию(Значение)
 Если Значение=1 Тогда
   Возврат Истина;
 ИначеЕсли Значение=2 Тогда
   Возврат Истина;
 ИначеЕсли Значение=3 Тогда
   Возврат Ложь;
КонецФункции
12 Fragster
 
гуру
21.09.11
18:10
(10) Господи и SuSE! (про внедренный таки линупс на рабочих станциях)
13 GROOVY
 
21.09.11
18:15
(9) Да они просто новый набор прогеров понабрали, а те кодить нормально не умеют.
14 Шапокляк
 
21.09.11
18:38
Ну да, классно. Запустил юзверя с именем "ДятелОповещатель" и при запуске поставил обработку с этим циклом, в котором задал условие БоссОткрылБазу. Ждем босса - цикл крутится. Босс зашел в базу - всем письмо с текстом "Атас! Начальство на месте" и выход из цикла.
15 GoldenDawn
 
21.09.11
18:39
(0)как глубоко )))
16 BigRoma
 
21.09.11
18:40
(0) Бред, такая конструкция нужна для других целей.
17 GoldenDawn
 
21.09.11
18:41
(0)нужно ещё обсосать компиляцию интерпретацию и не помню где забыл как с этой точки зрения называется платформа
и посаться обязательно
18 wade25
 
21.09.11
18:42
Уф, минут 5 смотрел и не вдуплял, пока не увидел, что "Пока Истина Цикл" входит в код =)
19 Ksandr
 
21.09.11
18:44
(16) для каких?
20 Fragster
 
гуру
21.09.11
18:45
(19) цикл с заранее неизвестным количеством итераций. хотя его все равно лучше заменить на
Пока НужноПродолжать Цикл...
21 Кириллка
 
21.09.11
18:50
Применимость, например, для такого случая:
0. В таком бесконечном цикле..
1. Спросить пользователя о чем-то;
2. Проверить введенное значение;
3. Если значение неверное, то повторно попросить его ввести значение или отказать от дальнейшего ввода;
4. В зависимости от того, что он выберет (ввести новое корректное значение или прекратить ввод вообще) выходить из цикла;
Главное здесь предусмотреть возможность пользователю прекратить эту феерию :)
Короче, это же азы.
22 GoldenDawn
 
21.09.11
18:52
тру проги пишут по НЕ нужнопродолжать цикл
23 Fragster
 
гуру
21.09.11
19:01
(22) бухаете?
24 Сияющий Асинхраль
 
21.09.11
19:21
Стаж 2 г 7 месяцев - долго же до тебя доходило... :-(
25 Guk
 
21.09.11
19:26
(0) нормальная конструкция, да простит меня NS ;)...
26 Rie
 
21.09.11
19:39
О goto ещё не вспоминали? :-)

(0) Блок кода - помогает видеть. А вот условие, по которому выходят из цикла, - его придётся поискать. Причём опытный кодер всегда сумеет запрятать это условие куда поглубже и сделать его максимально неудобочитаемым :-)

А так - конструкция как конструкция. Если возникает потребность именно в ней - используй. Если можно обойтись другими - лучше использовать другие.
27 jsmith
 
21.09.11
19:49
Видимо, ты испытал просветление. Могу предположить, ты имеешь в виду давнюю дискуссию между сторонниками меток и его противниками. Первые говорят, что такой код опасен (современные компиляторы даже выдают предупреждения). В принципе считаю это дело вкуса, от всех ошибок не застрахуешься, а при правильном мышлении ты можешь изощряться как хочешь.
28 Sk0rp
 
21.09.11
20:00
(0),(29) :))

ФлагПродолженияРаботы = Истина;
Пока ФлагПродолженияРаботы Цикл
.....
  Если ОченьХитроЗапрятанноеУсловие Тогда
     ФлагПродолженияРаботы = Ложь;
     Продолжить;
  КонецЕсли;

КонецЦикла;
29 Rie
 
21.09.11
20:06
(28) О чём и речь - рядом с опытным кодером обфускаторы нервно курят за кулисами :-)
30 Sk0rp
 
21.09.11
20:09
У меня где-то в коде есть:
Пока НЕ "Хлебом единым" = "жив человек" Цикл
О чем думал когда писал не помню, но уже исправлять не буду.
31 jsmith
 
21.09.11
20:29
(30) метко
32 Упанишады
 
21.09.11
20:35
(30)Поклонник Дудинцева?
33 zak555
 
21.09.11
20:43
(0) ещё пойми следущее, что


Пока Условие = Истина Цикл

конецЦикла;

идёт две операции, поэтому пищут просто

Пока Условие Цикл
34 DJ Anthon
 
21.09.11
20:55
(30) а у меня

Пока (2 * b) OR NOT (2 * b) Цикл

пришлось даже в глобальнике писать
Перем b Экспорт;
35 zak555
 
21.09.11
21:05
(34) "долгое" логическое выражение =)
36 Икогнито
 
21.09.11
21:16
а кто вот так пишет _ТабЗнач?
37 Morphius
 
21.09.11
21:19
(0) А матчасть почитать не пробовал? Таким образом люди реализуют do..while , которого нет в 1с. То бишь когда нужно условное выражение проверять в конце каждой итерации, а не в начале
http://phpclub.ru/manrus/cont/do.while.html
38 Kraft
 
22.09.11
06:15
(37) тс... автор познает основы программирования, не взрывайте ему моск не1с-ными вещами )
39 Ksandr
 
22.09.11
10:38
(27) ага, именно.
(28) а в чем отличие от (0) ? наличием флага?
(37)(38) знаю я мат часть, знаю.
40 Ненавижу 1С
 
гуру
22.09.11
10:39
простов 1С нет цикла с постусловием
41 Anempadest
 
22.09.11
18:32
Чё вы набросились на автора? Он вам ничего не предлагает. Человек просто озадачился однажды, а теперь наконец понял, почему в типовых конфигурациях код выглядит так, а не иначе.
42 Mort
 
22.09.11
18:39
(40) +1 вот и весь секрет
43 vmv
 
22.09.11
20:48
(40) да, его очень не хватает иногда
44 Stim213
 
22.09.11
20:50
такой код очень легко уйдет в бесконечный.
45 vmv
 
22.09.11
20:54
я тоже так пишу, вот вариант

&НаКлиенте
Функция ДанныеФормыДеревоПолучитьУровеньЭлемента(ДФЭлементДерева)
   
   Если ДФЭлементДерева = Неопределено Тогда
       Возврат Неопределено;
   КонецЕсли;
   
   Уровень = 0;
   
   ДФЭлементДереваПотомок = ДФЭлементДерева;
   Пока Истина Цикл
       ДФЭлементДереваРодитель = ДФЭлементДереваПотомок.ПолучитьРодителя();
       Если ДФЭлементДереваРодитель = Неопределено Тогда
           Прервать;
       Иначе
           Уровень = Уровень + 1;
       КонецЕсли;
       ДФЭлементДереваПотомок = ДФЭлементДереваРодитель;
   КонецЦикла;
   
   Возврат Уровень;
   
КонецФункции

работает без всякого ухода.

в 8.2. для деревоколлекця нет метода Урувень(), увы
46 Rie
 
22.09.11
20:56
(44) Любой нетривиальный цикл имеет шанс уйти в бесконечность.
47 Guk
 
22.09.11
22:10
(44) надо очень сильно постараться...
48 Лефмихалыч
 
22.09.11
22:22
(0) такой код пишут люди, у которых руки растут из жопы пальцами внутрь
49 Guk
 
22.09.11
22:23
о, наконец-то гений программирования в ветку заглянул ;)...
50 Stim213
 
22.09.11
22:26
(47) и стараться не надо. Число итераций должно быть всегда жестко определено, иначе условия выхода из цикла может не сработать и цикл будет бесконечным.
51 Guk
 
22.09.11
22:29
(50) хм, а можно пример?...
52 Stim213
 
22.09.11
22:36
(51) запросто. Конкретный пример - создаю pdf-файл через отправку табличного документа на виртуальный pdf-принтер - ком-объект. Команда Напечатать() отправилась, код 1С шагнул в следующую строку, а файл еще создается.
В цикле проверяем размер файла(что это не пустой файл), если размер больше 1кб - то Прервать; Но Если по каким-то причинам файл так и не создался, то цикл будет крутится бесконечно. Поэтому ставится счетчик итераций ~10000 и внутри них проверяется наличие заполненного файла
53 Stim213
 
22.09.11
22:41
+ код
ИмяФайла = ПОлучитьИмяФайла(ЭлементСписка.Значение);
               Файл = Новый ТекстовыйДокумент;
               Файл.Записать(ИмяФайла);
               Принтер = Новый ComObject("Bullzip.PDFPrinterSettings");
               Принтер.SetValue("output", ИмяФайла);
               Принтер.SetValue("ShowSaveAS", "never");
               Принтер.SetValue("ShowProgress", "no");
               Принтер.SetValue("ShowProgressFinished", "no");
               Принтер.SetValue("ShowSettings", "never");
               Принтер.SetValue("ShowPDF", "no");
               Принтер.SetValue("ConfirmOverwrite","no");
               Принтер.SetValue("OwnerPassword","");
               Принтер.SetValue("Permissions",61636);
               Принтер.WriteSettings();
               
               ТабДокумент.Автомасштаб=Истина;    
               ТабДокумент.ИмяПринтера = "Bullzip PDF Printer";
               ТабДокумент.Напечатать();
               Счетчик = 1;
               ФайлПДФ = Новый Файл(имяФайла);
               Пока Счетчик <> 100000 Цикл
                   ОбработкаПрерыванияПользователя();
                   РазмерФайла = ФайлПДФ.Размер() ;
                   Если  РазмерФайла > 100  Тогда
                       Прервать;
                   Конецесли;
                   Счетчик = Счетчик + 1;
               КонецЦикла;    

Если после 100000 итераций размер файла так и не увеличился - значит, он не увеличится уже никогда
54 Лефмихалыч
 
22.09.11
22:42
(52) такой - тоже
55 Guk
 
22.09.11
22:43
(53) а счетчик итераций это не условие выхода из цикла? и как это портит конструкцию в (0)?...
56 Stim213
 
22.09.11
22:45
(55) чукча писатель? Если бы я писал цикл по (0), мне пришлось бы писать

Пока ИСТИНА Цикл
                   РазмерФайла = ФайлПДФ.Размер() ;
                   Если  РазмерФайла > 100  Тогда
                       Прервать;
                   Конецесли;
               КонецЦикла;    


Или ты совсем не видишь разницы?
57 Guk
 
22.09.11
22:47
(56) тебе конструкция do..while вообще не знакома?...
58 Stim213
 
22.09.11
22:48
+ можно, конечно, написать
Счетчик = 1;
Пока ИСТИНА Цикл
                   РазмерФайла = ФайлПДФ.Размер() ;
                   Если  РазмерФайла > 100  Тогда
                       Прервать;
                   Конецесли;
Если Счетчик = 100000 Тогда
Прервать;
КОнецЕсли;
Счетчик = Счетчик + 1;
               КонецЦикла;  

Но читабельность такого кода уменьшается в разы
59 Лефмихалыч
 
22.09.11
22:50
60 Stim213
 
22.09.11
22:50
(57) это-то причем здесь?)
61 Guk
 
22.09.11
22:51
(60) это при том что ты написал в (58) ;)...
62 Stim213
 
22.09.11
22:54
(61) блин, не тупи же! Твой оператор - это цикл с постусловием, он к сабжу не имеет отношения, в сабже цикл с предусловием:
while <условие> do
begin  
 <тело цикла>
end;

Перестань уже позориться своим непрофессионализмом
63 Guk
 
22.09.11
22:59
(62) Стимка, жжошь! ;)
ты по=моему вообще не понимаешь о чем речь ;)...
64 Stim213
 
22.09.11
23:00
(63) куда мне до тебя, о гуру
65 Guk
 
22.09.11
23:02
(64) так а что ты хрень то какую-то несешь ;) тебе русским по белому намекают, что вся суть конструкции (0) в условии выхода из цикла. но ты почему-то напрочь этого не понимаешь. то ли дурака включил, то ли не включал ;)...
66 Попытка1С
 
22.09.11
23:02
(30)(34) Ненавижу таких юмористов... руки таким надо отрывать.
67 Оболтус
 
22.09.11
23:23
(14)Скорее всего проц загонишь, лучше обработкой ожидания такое делать.
68 Песец
 
23.09.11
07:19
(0) Если религия (корпоративная или личная) не позволяет юзать гоуту, а юзать надо, то самое оно.
69 Песец
 
23.09.11
07:21
(4) Альтернатива кривая - попробуй выйти из вложенного цикла.
70 zak555
 
23.09.11
08:09
можно сделать два условия проверки =)


Пока Истина Цикл

  Если УсловиеОстановаИстина Тогда
     Прервать;
  КонецЕсли;
КонецЦикла;
71 popcorn
 
23.09.11
08:15
(0) О, прикольно! Сразу не понял смысла, но потом понял. Тоже буду использовать такую идею.
72 Песец
 
23.09.11
08:52
(69+) Не удивлюсь, если выяснится, что подобная (0) хрень генерируется автоматически обработкой-"препроцессором", компилирующим исходный код с гоуту в код без оператора, попавшего в опалу корпоративного стандарта.
73 Morphius
 
23.09.11
10:06
Кстати, т.к. в 7.7 типа "Булево" не было, встречал такую конструкцию(и сам потом использовал):

Пока 1=1 Цикл
....
....
КонецЦикла;
74 vladenoff
 
23.09.11
15:47
Использую:
//
Пока Истина Цикл
....
Если <Условие> Тогда
прервать;
КонецЕсли;
КонецЦикла

использую, когда условие повторного повторения (вхождение в цикл) должно проверяться в конце алгоритма самого цикла. Это обеспечит их выполнения хотя бы раз.

В паскале были конструкции "While do..." и "reaped until", вот второй конструкции у 1С нету. Её заменяю "Пока Истина Цикл
...."

заменить можно, но наверное гемора больше. Пришлось бы, наверное, указывать булевую переменную, типа "ПрошлоРазЦикл".
75 Fragster
 
гуру
23.09.11
16:00
(74)


Условие = Истина

Пока Условие Цикл

 Условие = (условие выхода из цикла);
КонецЦикла;
76 Necessitudo
 
24.09.11
09:17
Велосипедописатели
77 Torquader
 
24.09.11
16:15
Ну не сделали в 1С цикл с условием в конце - видимо - не умеют.
"Бесконечный" цикл используется, если хочется выполнить повторение кода с начала при неудаче на каком-то участке кода, а также для "корректного" выхода из ситуации, когда код выполняться не может.
Требовать и эффективности, и гибкости от одной и той же программы — все равно, что искать очаровательную и скромную жену... по-видимому, нам следует остановиться на чем-то одном из двух. Фредерик Брукс-младший