Как сделать цикл в 1с

Добавил пользователь Дмитрий К.
Обновлено: 19.09.2024

Продукты 1с, Авторские разработки, Форум, Краудсорсинг

1С- Налегке

Продукты 1с, Авторские разработки, Форум, Краудсорсинг

ЦИКЛЫ

Разберем самый простой вид цикла. Этот цикл имеет следующий синтаксис.

В этом цикле, переменной НазваниеПерем в самом начале присваивается выражение СчетчНачало, которое имеет числовое значение (целое число). Потом, в каждой итерации цикла переменная НазваниеПерем увеличивается на 1. Цикл будет выполняться пока переменная НазваниеПерем меньше или равно переменной СчетчКонец.

СчетчНачало и СчетчКонец могут быть как числами, так и переменными с типом число.

Причем СчетчНачало может быть меньше нуля.

Чтобы цикл корректно работал СчетчНачало должно быть меньше СчетчКонец.

Такой код будет не корректен!!

С этим циклом удобно работать, когда нам нужно линейно заполнить какие-нибудь величины. Например, заполним массив в 1С цифрами от -3 до 3.

Или когда нужно получить какие-нибудь значения, которые следуют друг за другом. Например, значения того же массива.

Если при помощи предыдущего цикла можно было делать линейные обходы от меньшего значения к большему, то этот вид цикла позволяет выполнять практически любые обходы.

Данный цикл имеет следующий синтаксис

ЗначениеВыражения – какое-то логическое выражение. Пока это выражение истинно, то операторы цикла будут выполняться. Если выражение принимает значение Ложь, то цикл прекращается.

Массив = Новый Массив; НачЗначение = 3; КонЗначение = — 3; ТекЗнач = НачЗначение; Пока ТекЗнач >= КонЗначение Цикл Массив.Добавить(ТекЗнач); ТекЗнач = ТекЗнач — 1; КонецЦикла;

Этот цикл можно также использовать, когда нужно что-то заполнить датами.

Массив = Новый Массив; НачЗначение = ‘20100101’; КонЗначение = ‘20100131’; ТекЗнач = НачЗначение; Пока ТекЗнач КонецЦикла

Переменной ЭлементКоллекции присваивает очередное значение элемента коллекции.

Например, если мы напишем вот такой код.

Массив1 = Новый Массив; Массив1.Добавить(100); Массив1.Добавить(45); Массив1.Добавить(1000); Для Каждого элМассива из Массив1 Цикл КонецЦикла;

То при первом обходе переменная ЭлМассива будет равна 100, при втором — 45, а при третьем – 1000.

Пример в этом коде

И результат работы этого кода

Обход циклом Для каждого цикл

ПРЕРВАТЬ ЦИКЛ 1С

Иногда возникают такие ситуации, когда нужно из цикла выйти. Сделать это можно при помощи оператора Прервать. Этот оператор применим ко всем тремя видам циклов.

После выполнения этого оператора Прервать все последующие операторы в теле цикла не выполняются, и следующим выполняется оператор после ключевого слова КонецЦикла.

Рассмотрим следующий пример.

В этом примере мы обходим простым циклом ряд чисел от -5 до 5, и делим 1 на обходимое число. Если же переменная счетчика равна 0, то чтобы не происходила исключительная ситуация, то выходим из цикла. Т.е. мы выполним деление только для отрицательных чисел.

ПРОДОЛЖИТЬ ЦИКЛ 1С

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

Операторы после этого ключевого слова выполняться не будут, и произойдет следующая итерация цикла.

Рассмотрим такой пример.

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

Для решения задач, поставленных перед программистом, целесообразно использовать циклы. С их помощью можно заметно упростить код и сократить его количество. В 1С существуют 3 цикла: "Для", "Пока" и "Для каждого Из".

Циклы "Для" и "Пока"

С циклами все куда проще. Задачу можно решить так:

циклы

На изображении представлены 2 вида цикла, с помощью которых можно получить желаемый результат.

Разберем синтаксис. Сам цикл оборачивается командами "Цикл" и "КонецЦикла;". Перед началом цикла прописывается условие - то, что будет проверяться на каждой итерации (повторении).

Цикл "Для каждого Из"

На практике чаще приходится использовать иной цикл - Для каждого Из. Выглядит он так:

для каждого цикл

С его помощью осуществляется перебор элементов той или иной коллекции значений. Синтаксис схож с предыдущими циклами. Внутри самого цикла осуществляется выполнение действия, но условие задается несколько иначе. В данном случае работа осуществляется с массивом, содержащим 2 элемента. Элемент массива с индексом [0] - строка "Номер 1" и элемент массива с индексом [2] - строка "Номер 2".

Особое внимание!

При работе с циклами нужно обращать особое внимание на то, чтобы выносить постоянные значения за его пределы. Например, в цикл мы подставляем путь к файлу, который не меняется, или программно осуществляем запрос к базе. В таких случаях следует вынести все необходимые манипуляции за цикл и положить результат вычислений в переменную, чтобы в дальнейшем передавать эту переменную в цикл. Таким образом, значительно улучшится быстродействие программы. Общее правило: если в цикле используются постоянные данные, то следует выносить их за цикл, а в цикле работать с переменной, содержащей эти данные. В цикле оставляем только то, что нужно менять динамически на каждой итерации.

В данном случае программа выполняет один и тот же кусок кода и вычисляет результат сложения чисел 1000 раз, поскольку цикл выполнится 1000 раз.


Естественно, что относить рекурсию к циклам не совсем корректно, но тем ни менее с её помощью можно добиться похожих результатов. Сразу оговорюсь, что в дальнейшем тестировании рекурсия не участвовала. Во первых все тесты проводились при 1 000 000 итераций, а рекурсия выпадает уже при 2 000. Во вторых скорость рекурсии в десятки раз меньше, чем скорость остальных циклов.

Ну что ж, поехали. В качестве тела цикла использовалось чтение из заранее заполненного массива.


Тестирование проводилось на платформе 8.3.5.1231 для трех видов интерфейса (Обычное приложение, Управляемое приложение и Такси).

Результаты для 8.3.5.1231
Интерфейс ДляПо ДляКаждого Пока Если
Обычное приложение 5734,2 4680,4 7235,4 7263,0
Управляемое приложение 5962,4 4882,6 7497,4 7553,6
Такси 5937,2 4854,6 7500,8 7513,0
Числа это время в миллисекундах полученное с помощью функции ТекущаяУниверсальнаяДатаВМиллисекундах(), которую я вызывал до цикла и после его завершения. Числа дробные, потому что я использовал среднее арифметическое пяти замеров. Почему я не использовал Замер производительности? У меня не было цели замерить скорость каждой строчки кода, только скорость циклов с одинаковым результатом работы.

Казалось бы и все, но — тестировать так тестировать!
Результат для платформы 8.2.19.106

Результаты для 8.2.19.106
Интерфейс ДляПо ДляКаждого Пока Если
Обычное приложение 4411,8 3497,2 5432,0 5454,0
Управляемое приложение 4470,8 3584,8 5522,6 5541,0
В среднем платформа 8.2 на 25% быстрее, чем 8.3. Я немножко не ожидал такой разницы и решил провести тест на другой машине. Результаты приводить не буду, в можете сами нагенерировать их с помощью вот этой конфигурации. Скажу только, что там 8.2 была быстрее процентов на 20.

Почему? Не знаю, дезасемблировать ядро в мои планы не входило, но в замер производительности я все же заглянул. Оказалось, что сами циклические операции в 8.3 проходят несколько быстрее, чем в 8.2. Но на строке

то есть при считывании элемента коллекции в переменную происходит значительное снижение производительность.

В итоге:

Процентное соотношение скорости циклов
ДляПо ДляКаждого Пока Если
78,97% 64,57% 99,57% 100,00%
К чему всё это? Для себя я сделал несколько выводов:

Алгоритмы многих программ зачастую предполагают циклическое повторение определённых действий. 1С в этом случае не является исключением. Циклы в 1С позволяют:

  • Перебрать элементы справочника;
  • Заполнить области макета;
  • Выполнить определенные действия с выборкой документов;
  • И многое многое другое.

Типы циклов

В 1С принято различать три типа циклов в зависимости от набора слов, входящих в конструкцию:

Рассмотрим их подробнее.

Для каждого из

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

  • Переменная, определяющая текущий элемент коллекции;
  • Определение коллекции значений.

Наиболее часто возникающая ошибка в этом случае показана на рис.1


Чаще всего она возникает, когда программист не до конца понимает разницу между объектом (документом, справочником) и коллекцией (выборкой) значений, получаемой с помощью оператора Выбрать().

Для по

В качестве параметров, передаваемых в строку, в этом случае выступают:

  1. Имя переменной – итератора;
  2. Начальное значение переменной;
  3. Конечное значение переменной.

Повторение блока операторов, входящих в тело цикла будет осуществляться до тех пор, пока переменная не сравняется или первый раз не превысит конечное значение. При этом итератор будет каждый шаг увеличиваться на 1. Значения сравниваются до выполнения следующего шага.

Такая конструкция очень часто используется при обходе табличных частей.

При использовании данного обходчика важно различать количество строк табличной части и индекс отдельной взятой строки. В первом случае начальное значение будет равно 1, конечное можно получить с помощью оператора Количество(). Индексы начинаются с 0 и заканчиваются Количество()-1. В противном случае можно получить ошибку (Рис.2).

Здесь всего один параметр – логическое выражение, которое перед каждым следующим шагом цикла проверяется на истинность. Как только логическое выражение не будет выполнено, обработчик завершит обход.

Очень важно понимать, что в некоторых случаях проверяемое выражение может постоянно находиться в значении Истина, тем самым обход будет совершаться бесконечное количество раз, подвешивая систему.

В таких случаях необходимо внутри тела цикла прописать один из двух вариантов прерывания выполнения.

Иногда может сложиться ситуация, когда истинность проверяемого выражения не наступит никогда. Это может привести к бесполезным поискам ошибки в коде и потере времени.

Прерывание выполнения нажатием комбинации клавиш

Во избежание неприятных последствий своей деятельности, программистам крайне полезно приучить себя в тело обработки прописывать эту процедуру.

Прерывание по условию

Достаточно часто алгоритм программы предполагает остановку цикличной обработки, если выполняется то или иное условие. Заложить эту процедуру в тело цикла можно с помощью оператора Прервать.

Правильно записанный в код программы этот оператор выделяется красным цветом.

Перескакивание некоторых операций цикла

Зачастую в цикле необходимо проверять выполнение какого-либо условия и в случае, если это условие не выполняется, проскакивать основной обработчик. Такие конструкции могут быть реализованы двумя способами:

Читайте также: