- •Лекция №7. Виды программных модулей. Выражения и операторы. Процедуры и функции
- •Программный модуль
- •Виды программных модулей
- •Структура программного модуля
- •Контекст выполнения программного модуля
- •Передача локального контекста программного модуля в качестве параметра
- •Выражения и операторы. Процедуры и функции. Выражения
- •Операции
- •Массивы
- •Встроенные функции для разных типов данных
- •Управляющие операторы и конструкции
- •Пользовательские процедуры и функции
- •Контрольные вопросы
- •Литература
Пользовательские процедуры и функции
Программирование "сверху вниз"
Разработка алгоритмов и программ осуществляется, как правило, по принципу "сверху вниз".
Суть такого подхода состоит в разбиении исходной задачи на ряд более простых задач - фрагментов - и последующей работе с ними.
При разбиении задачи на фрагменты надо придерживаться следующей схемы:
Проанализировать задачу и выделить в ней фрагменты.
Отобразить процесс разбиения в виде блок-схемы или линейной схемы и пронумеровать в ней фрагменты.
Установить между выделенными фрагментами связи: для каждого фрагмента определить, какие данные он получает (входные данные) и какие данные возвращает (выходные данные). Связи между фрагментами называются интерфейсом.
Рассмотреть далее каждый фрагмент самостоятельно; разработать для него алгоритм и записать его либо в виде линейной схемы, либо в виде блок-схемы. При необходимости подвергнуть фрагмент разбиению на более мелкие фрагменты. Такое разбиение продолжать до тех пор, пока не будут получены фрагменты, программирование которых не составляет особых затруднений.
Оформить выделенные фрагменты в виде программных компонентов или БОК.
При таком подходе программу можно рассматривать как совокупность фрагментов, которые, принимая некоторые данные, вырабатывают результат и передают его другому фрагменту и так вплоть до завершения вычислений.
Составляемые для фрагментов линейные схемы алгоритмов сопровождаются заголовком и описанием интерфейса, отражающим состав входных и выходных данных.
В 1С для реализации фрагментов можно использовать программные компоненты:
основную программу модуля;
процедуры и функции модуля.
Фрагмент алгоритма, как правило, оформляется в виде функции, если в результате выполненных в нем вычислений возвращается единственный скаляр. Если же фрагмент возвращает в вызывающий фрагмент в качестве результата несколько значений, в том числе и в виде массива, или не возвращает результатов, например осуществляет вывод данных в файл, то он оформляется в виде процедуры.
Структура процедур и функций
Процедуры и функции имеют схожую структуру:
Процедура | Функция Имя([[3нач] парам1 = [значение1]], ..., [[Знач] парамN = [значениеN]]) [Экспорт]
[неисполняемые операторы объявления переменных]
[исполняемые операторы]
КонецПроцедуры | КонецФункции
Ключевое слово, или атрибут, Экспорт указывается для процедур и функций, располагаемых в глобальном модуле, в том случае, если их надо сделать доступными для вызова в локальных модулях форм.
Процедуры вызываются в виде отдельного оператора с соблюдением следующего синтаксиса:
Имя_процедуры([парам1], ..., [парамN]);
Функции, как правило, вызываются из выражений, но могут, так же как и процедуры, вызываться в виде отдельно оператора:
Имя_функции([парам1],..., [парамN]);
Функция, если выход из нее осуществляется не в результате выполнения оператора
Возврат выражение;
а по оператору
КонецФункции
возвращает число 0.
Функция, в которой нет оператора
Возврат выражение;
всегда возвращает нуль.
Замечание. При программировании из функции следует выходить по оператору
Возврат выражение;
даже если выражение - это константа нуль.
Например, функции ф1 и ф2
функция ф1(а) функция ф2(а)
если а > 0 тогда если а > 0 тогда
возврат 2 * а; возврат 2 * а;
иначе конецЕсли;
возврат 0; конецФункции // ф2
конецЕсли;
конецФункции // ф1
возвращают одинаковый результат, однако вариант с ф1 отвечает принятому для функций стилю программирования, чего нельзя сказать о функции ф2. Впрочем, в данной ситуации функцию ф1 лучше записать так:
функция ф1(a)
возврат ?(а > 0, 2 * а, 0);
конецФункции // ф1
Процедуры и функции могут вызываться только из тех процедур и функций модуля, ранее которых расположены либо они сами, либо их предварительное описание.
Например, в модуле с кодом
функция ф1(а)
возврат ?(а > 0, 2 * а, 0);
конецФункции // ф1
процедура п1 (д) далее // Предварительное описание процедуры п1
процедура Выполнить()
перем б;
б = 2.5 * ф1(3); // б= 15; функция ф1 вызывается из выражения
п1(б); // б = 35; б - фактический параметр процедуры п1
Сообщить(б);
конецПроцедуры // Выполнить
функция ф2(с)
возврат с / 2;
конецФункции // ф2
процедура п1(д) // д - фактический параметр процедуры n1
д = 4*ф2(д) + 5; // д = 4 * 7.5 + 5 = 35
конецПроцедуры // п1
из процедуры Выполнить можно вызвать функцию ф1 и процедуру nl, но нельзя вызвать функцию ф2.
Предварительное описание процедуры (функции) должно дублировать заголовок процедуры (функции). Не допускаются расхождения имен параметров, и если заголовок процедуры (функции) снабжен ключевым словом Экспорт, то оно должно присутствовать и в тексте предварительного описания перед ключевым словом Далее. Например:
процедура п3(д1, д2) Экспорт далее // Предварительное описание процедуры пЗ
Перечень имен процедур и функций модуля можно просмотреть, нажав, находясь в конфигураторе, на иконку & на панели инструментов Текстовый редактор. Так, для вышеприведенного набора процедур и функций, если их разместить, например, в модуле обработки Проба, мы получим приведенный на рисунок 4 список (сортировка имен не задана).
Рисунок 4 Окно вывода списка процедур и функций модуля
На начало любой процедуры (функции) или на ее предварительное описание можно переместиться, выбрав в вышеприведенном окне необходимую строку и нажав на кнопку Перейти.
Параметры процедур и функций
Обмен данными между программными компонентами 1С осуществляется через:
глобальные объекты;
переменные модуля;
переменные диалога;
параметры процедур и функций. Дополнительно от функции можно получить и использовать в выражении возвращаемое значение функции.
Параметры, используемые при вызове процедуры или функции, называются фактическими. Так, в выражении, стоящем в правой части оператора присваивания
д = 4 * ф2(д) + 5; // д = 4 * 7.5 + 5 = 35
из процедуры п1 предшествующего раздела параметр д функции ф2 является фактическим.
Параметры, стоящие в заголовке процедуры (функции), в том числе и в заголовке, присутствующем в тексте предварительного описания, называются формальными. Таким является, например, параметр с в следующем заголовке:
функция ф2(с) // с - формальный параметр функции ф2
При вызове процедуры (функции) между фактическими и формальными параметрами устанавливается соответствие.
Формальные параметры процедур и функций являются необязательными. То есть соответствующие им фактические параметры могут быть опущены. Следующие за ними запятые должны быть при этом сохранены
Можно, в формальные параметры установить значения по умолчанию, которые будут использоваться в выражениях при отсутствии соответствующих им фактических параметров
Вложенные вызовы процедур и функций
Любая процедура или функция может содержать вызовы иных процедур и функций, но не может вызвать сама себя явно или через другую процедуру (функцию). Наличие такого вызова приведет к "зависанию" программы. Например:
процедура п6(а) далее
процедура п5(а) // Процедура п5 вызывает сама себя
а = 2 * а; // из процедуры п6. В результате имеем
п6(а); // зависание программы
конецПроцедуры // п5
процедура п6(а)
а = -а;
п5(а);
конецПроцедуры // п6
процедура Выполнить()
Предупреждение("Сейчас программа зависнет. Для продолжения вычислений нажмите Esc.");
а=1;
п5(а);
конецПроцедуры // Выполнить
Оператор возврат
Функция возвращает результат выражения оператора
Возврат выражение;
Такой оператор может быть использован в функции неоднократно. Однако его можно разместить и в процедуре (обычно внутри конструкций "если" или Попытка). При этом выражение должно быть опущено. Например:
процедура п7(а, б)
если а <= 0 тогда
Сообщить("Неверное значение аргумента функции Лог."); возврат; // выражение опущено
конецЕсли;
б = Лог(а);
конецПроцедуры // п7
Лучше обойтись без оператора Возврат, применив ветвление "если-то-иначе":
процедура п8(а, б)
если а <= 0 тогда
Сообщить("Неверное значение аргумента функции Лог.");
иначе
б = Лог(а);
конецЕсли;
конецПроцедуры // п8
