- •Лекция №7. Виды программных модулей. Выражения и операторы. Процедуры и функции
- •Программный модуль
- •Виды программных модулей
- •Структура программного модуля
- •Контекст выполнения программного модуля
- •Передача локального контекста программного модуля в качестве параметра
- •Выражения и операторы. Процедуры и функции. Выражения
- •Операции
- •Массивы
- •Встроенные функции для разных типов данных
- •Управляющие операторы и конструкции
- •Пользовательские процедуры и функции
- •Контрольные вопросы
- •Литература
Управляющие операторы и конструкции
Алгоритм как совокупность базовых структур
Программа и ее отдельные части создаются на основе алгоритмов. Фактически программа - это кодировка некоторого алгоритма или группы алгоритмов. Из этого следует, что до написания кода необходимо разработать и записать (последнее не всегда делается) алгоритм.
Алгоритм - это последовательность действий, либо приводящая к решению задачи, либо поясняющая, почему это решение получить нельзя. Например, отрицательный результат получается при ошибочном задании входных данных.
Алгоритм составляется из отдельных фрагментов, которые могут иметь одну из следующих структур:
блок операторов и конструкций;
ветвление;
цикл.
Блок операторов и конструкций (БОК) - это выполнение одного или нескольких простых или сложных действий. БОК может содержать и ветвления и циклы, которые являются примерами сложных действий. Простым действием является, например, выполнение присваивания или вызов процедуры. Конструкции состоят из нескольких операторов и используются для выполнения управляющих действий, например циклов. Так, конструкция Если ... КонецЕсли состоит из двух операторов: Если и КонецЕсли. Последний оператор конструкции должен завершаться точкой с запятой.
Ветвление - это выбор одного из возможных направлений выполнения алгоритма, осуществляемый в зависимости от значения некоторых условий. Ветвления подразделяются следующие виды:
если - то;
если - то - иначе;
если - то - иначе - если;
выбор по ключу (в 1С это ветвление не используется, вместо него употребляется «Если - то - иначе – если»);
попытка.
Цикл - это повторное выполнение некоторого БОК с разными, как правило, значениями входящих в БОК переменных. Однократное выполнение БОК цикла называют итерацией. БОК цикла также называют телом цикла.
Различают следующие циклы:
с параметром;
пока;
до.
Последний вид цикла применяется крайне редко; в 1С он отсутствует.
При записи алгоритма составляющие его базовые структуры либо отображаются графически, либо записываются в виде линейных схем. Проиллюстрируем обе эти возможности.
Ветвления «если»
В ветвлениях "если - то", "если - то - иначе" и "если - то - иначе - если" для записи условий используется логическое выражение (ЛВ), результатом которого может быть истина (И) или ложь (Л). Графически ветвления проиллюстрирует рисунок 1.
Рисунок 1 Ветвления: а - ветвление "если - то";
б - ветвление "если - то - иначе"
Ветвление "если - то" работает так:
вычисляется значение ЛВ;
если оно истинно, то выполняется БОК1;
если оно ложно, то управление передается БОК2.
Запись ветвление "если - то" в 1С:
если ЛВ тогда
БОК // Некоторые операторы
конецЕсли;
Например:
Если (РабочаяДата() > '01.01.95') и (Сег = "Понедельник") Тогда
Сообщить("Сегодня" + " " + Сег + " " + РабочаяДата());
КонецЕсли;
Ветвление "если - то - иначе" работает так:
вычисляется значение ЛВ;
если оно истинно, то выполняется БОК1
если оно ложно, то выполняется БОК2;
далее управление передается БОК3.
Запись ветвления "если - то - иначе" в 1С:
если ЛВ тогда
БОК1 // Некоторые операторы
иначе
БОК2 // Некоторые операторы
конецЕсли;
Если БОК1 и БОК2 в ветвлении "если - то - иначе" являются выражениями, то для выбора вычисляемого выражения лучше употреблять функцию, вычисляющую выражение по условию. Ее синтаксис:
результат = ?(ЛВ, выражение1 , выражение2 );
Пример:
у = ?(х > 0, Лог(х), х); // Вернет Лог(х), если х >0, или х - в противном случае
Приведенный оператор заменяет следующее ветвление:
если х > 0 тогда
у = Лог(х);
иначе
у = х;
конецЕсли;
Запись ветвление "если - то - иначе - если" в 1 С:
если ЛВ1 тогда
БОК1 // Некоторые операторы
иначеЕсли ЛВ2 тогда
БОК2 // Некоторые операторы
………….
иначеЕсли ЛВк тогда
БОКк // Некоторые операторы
[иначе // Последние два элемента конструкции
БОКк+1] // являются необязательными
конецЕсли;
«Попытка»
Ветвление Попытка служит для обработки исключений и реализуется в 1С виде следующей конструкции:
попытка
БОК1,
исключение
БОК2
конецПопытки;
где
БОК1 - последовательность операторов, в которых может возникнуть исключение;
БОК2 - последовательность операторов, обрабатывающих исключение.
Исключение - это ошибка, возникающая при исполнении программы, например деление на нуль или выход за границы массива. В первом случае система выдаст сообщение "Деление на 0", во втором - "Значение индексного выражения". Работа программы, если не используется обработка исключений, при возникновении ошибки прекращается.
Некоторые ошибки, приводящие к останову программы, могут быть, однако, устранены. Например, ошибка блокировки данных, возникающая при обращении к файлу, захваченному в настоящий момент другим приложением, устраняется после завершения работы этого приложения.
Применение конструкции Попытка целесообразно, если ошибка, не искажает конечного результата. Например, выход за границы массива. В таких случаях целесообразно использовать конструкцию Попытка с тем, чтобы при возникновении ошибки выполнить ее обработку, например, просто сообщить об ошибке, и продолжить расчеты.
Например. Вычислить сумму элементов вектора. В процедуре при обращении к вектору умышленно введена ошибка - выход за границы вектора. Для ее преодоления применяется конструкция Попытка.
процедура Выполнить() // Запускаем процедуру из обработки Проба
перем а[5], ин, сум;
// Инициализация вектора а
а[1] = 0; а[2] = 1.5; а[3] = 2.5; а[4] = -1; а[5] = 7;
// Сумма элементов массива а. Ожидаемый результат: сум = 10 сум = 0;
// Умышленно для иллюстрации работы конструкции Попытка
// задаем верхний параметр цикла большим числа элементов вектора а
для ин = 1 по 7 цикл
попытка // При выходе за границы вектора
сум = сум + а[ин]; // произойдет обработка исключения;
исключение // исполнение программы не прекратится
Сообщить(ОписаниеОшибки() + ". Вычисления будут продолжены.");
конецПопытки;
конецЦикла; // для
Сообщить("сум = " + сум); // Напечатает 10
конецПроцедуры // Выполнить
Встроенная функция ОписаниеОшибки возвращает описание ошибки в том виде, в каком оно выдается системой в окно сообщений при отсутствии обработки исключений.
Циклы
В цикле "с параметром n" задаются начальное значение параметра к, его конечное значение к и шаг ш - отличная от нуля величина, на которую изменяется значение параметра и после выполнения очередной итерации. В 1С шаг ш всегда принимается равным единице. Параметр п также называют переменной цикла, которая должна быть целочисленной. Параметры н и к являются в 1С числовыми выражениями и представляют соответственно нижнюю и верхнюю границы переменной цикла. Если параметр н(к) вычисляется с нецелым значением, то в качестве параметра используется целая часть результата.
Параметр цикла часто называют его индексом, для обозначения которого в программах нередко употребляют имя ин или инд.
Графически цикл "с параметром" иллюстрирует рисунок 2.
Рисунок 2 Цикл с параметром
Цикл "с параметром" работает так (случай ш > 0):
1. Присвоить: п = н.
2. Если п <= к, то перейти к п.3, иначе завершить цикл.
3. Выполнить БОК.
4. Присвоить: п = п + ш и перейти к п.2 (повтор).
Когда ш < 0, п.2 выглядит так:
Если п > к , то переход к п. 3°, иначе завершить цикл.
В цикле "с параметром" приведенные в пп. 1 и 4 операторы в тексте программы не присутствуют, но будут автоматически встроены компилятором в объектный код при компиляции программы.
В 1С запрет на изменение значения переменной цикла п не действует. Однако следует помнить, что изменение п в теле цикла - это плохой стиль программирования.
Запись цикла “с параметром” в 1С:
для п = н по к цикл
БОК
конецЦикла;
Цикл Пока выполняется до тех пор, пока истинно некоторое ЛВ. Причем проверка истинности ЛВ выполняется перед началом очередной итерации. Цикл До отличается от цикла Пока тем, что проверка истинности ЛВ осуществляется после выполнения очередной итерации. Графическая интерпретация циклов Пока и До приведена на рисунке 3.
Рисунок 3 Цикл Пока
При работе с циклом Пока надо следить, чтобы ЛВ обязательно рано или поздно приняло значение ложь. Иначе произойдет зацикливание - "бесконечное" выполнение операторов цикла.
Запись цикла Пока в 1С:
пока ЛВ цикл
БОК // Некоторые операторы
конецЦикла;
Далее при ссылке на циклы будем использовать принятые в 1С имена операторов циклов - Для и Пока.
Циклы Для и Пока могут быть вложенными. То есть в теле цикла Для (Пока) могут быть другие циклы Для и/или Пока. Например, записав код вывода групп подряд следующих непериодических констант, сообщающий перед выводом группы ее номер. (Уточним: в примере группа - это подмножество подряд следующих непериодических констант, не имеющее периодических констант. То есть группы разделяются одной и более периодическими константами.)
// Процедура, выводящая группы непериодических констант
// Запускается из обработки Проба
процедура Выполнить()
перем всегоКонстант, ин, номерГруппы, иден;
ОчиститьОкноСообщений();
номерГруппы = 0;
всегоКонстант = Метаданные.Константа();
ин = 1; // Номер константы
пока ин <= всегоКонстант цикл
если Метаданные.Константа(ин).Периодический = 0 тогда
номерГруппы = номерГруппы + 1;
Сообщить("Выводится группа с номером " + номерГруппы);
// Вложенный цикл Пока
пока Метаданные.Константа(ин).Периодический = 0 цикл иден = Метаданные.Константа(ин).Идентификатор; Сообщить(иден + " " + Константа.ПолучитьАтрибут(иден)); ин = ин + 1; // переход к следующей константе
если ин > всегоКонстант тогда
прервать; //Досрочный выход из вложенного цикла
конецЕсли; конецЦикла; // пока Метаданные.Константа(ин).Периодический = 0 иначе //Имеем периодическую константу
ин = ин + 1; // переход к следующей константе
конецЕсли
конецЦикла; // пока ин <= всегоКонстант
если номерГруппы = 0 тогда
Сообщить("В конфигураторе нет непериодических констант");
конецЕсли;
конецПроцедуры // Выполнить
Переход по метке
Выполняется оператором
Перейти метка;
где метка - это имя, начинающееся с тильды (знака ~),
например
~М1.
Этот оператор неприемлем для сторонников структурного программирования. Однако есть ситуации, кода он полезен, например для досрочного выхода из вложенного цикла.
Например. Записать, код вывода групп подряд следующих непериодических констант, сообщающий перед выводом группы ее номер, завершая вывод, обнаружив непериодическую константу типа Календарь.
// Процедура, выводящая группы непериодических констант. Завершается либо при обнаружении
// непериодической константы типа Календарь, либо после вывода всех групп.
процедура Выполнить()
перем всегоКонстант, ин, номерГруппы, иден;
ОчиститьОкноСообщений();
номерГруппы = 0;
всегоКонстант = Метаданные.Константа();
ин = 1; // Номер константы
пока ин <= всегоКонстант цикл
если Метаданные.Константа(ин).Периодический = 0 тогда
номерГруппы = номерГруппы + 1;
Сообщить("Выводится группа с номером " + номерГруппы);
// Вложенный цикл Пока
пока Метаданные.Константа(ин).Периодический = 0 цикл
если Метаданные.Константа(ин).Тип = "Календарь" тогда
перейти ~М1; // Выход из всех циклов
конецЕсли;
иден = Метаданные.Константа(ин).Идентификатор; Сообщить(иден + " " + Константа.ПолучитьАтрибут(иден)); ин = ин + 1; // перейти к следующей константе
если ин > всегоКонстант тогда
прервать; // Досрочный выход из вложенного цикла конецЕсли;
конецЦикла; // пока Метаданные.Константа(ин).Периодический = 0 иначе // Имеем периодическую константу
ин = ин + 1; // перейти к следующей константе
конецЕсли;
конецЦикла; // пока ин <= всегоКонстант
// Располагаем после метки ~М1 двоеточие
~М1: // Сюда передается управление оператором Перейти ~М1;
если номерГруппы = 0 тогда
Сообщить("В конфигураторе нет непериодических констант.");
конецЕсли;
конецПроцедуры // Выполнить
В данной задаче метку ~М1 нельзя расположить перед оператором конецЦикла:
~М1:
конецЦикла; // пока ин <= всегоКонстант
поскольку такое использование метки не приводит к выходу из цикла, а передает управление на оператор Пока внешнего цикла. В конкретном случае результатом такого размещения метки будет зацикливание программы.
Задачу можно решить и без использования оператора, введя флаг обнаружения константы типа Календарь и применив, например, объединение условий.
