Функции Продолжим исследовать и улучшать пример с количеством занятий в каждый из дней. Посмотрите на ту его часть, которая, зная день недели, узнает вам количество занятий (рис. 1). Рис. 1
Скачать 454.36 Kb.
|
Функции Продолжим исследовать и улучшать пример с количеством занятий в каждый из дней. Посмотрите на ту его часть, которая, зная день недели, узнает вам количество занятий (рис. 1). Рис. 1. Часть примера, которая определяет день недели В вашем примере она выглядит довольно просто, но в реальной программе это может быть большой и сложный алгоритм. Он по сложным правилам, в зависимости от многих условий решает, сколько будет занятий. Представьте себе, что этот алгоритм вам нужно использовать не только здесь, где он написан, но и в каком-то другом месте вашей конфигурации. Только там, например, вам нужно просто вычислить, сколько занятий будет в какой-то один определенный день. Который вы заранее не знаете. Что делать? В том, другом, месте заново еще раз писать весь этот алгоритм? Это нехорошо. А если таких мест не одно, а несколько? А если вы потом захотите изменить этот алгоритм? Придется изменять его во всех местах, где он написан? Тогда легко допустить ошибку и что-то пропустить. Но выход есть! Нужно просто оформить этот алгоритм в виде функции. Тогда он будет написан у вас в одном единственном месте, а использовать его вы сможете в разных местах своей конфигурации. Функция – это не инструкция. Это просто специальная форма записи нескольких инструкций вместе. Чтобы не было скучно, воспользуйтесь синтакс-помощником. Откройте в нем ветку Общее описание встроенного языка – Операторы. Нажмите мышью на Функция и перетащите ее в свой модуль парой строк ниже строки КонецПроцедуры (рис. 2). Рис. 2. Заготовка функции Платформа вставит в ваш модуль заготовку функции. Теперь после строки Функция добавьте пустую строку и перетащите в нее всю инструкцию Если, которая выделена на рис. 1. Используйте форматирование, чтобы платформа сама расставила синтаксические отступы. У вас получится такая конструкция (рис. 3). Рис. 3. Тело функции То, что находится между строкой Функция … () и строкой КонецФункции, называется тело функции. Это те инструкции, которые будут выполнены при вызове функции. Первая строка – Функция … () – это определение функции. Им вы сейчас и займетесь. Потому что пока у вас есть только заготовка. Определение функции всегда начинается с ключевого слова Функция. За ним, через пробел, нужно указать имя этой функции. Имя вы придумываете сами. Оно нужно для того, чтобы вызвать эту функцию из другого места. Назовите функцию СколькоЗанятий (рис. 4). Рис. 4. Имя функции – «СколькоЗанятий» После имени, без пробела, всегда следуют круглые скобки – (). В них может быть что-то написано, а может и не быть. Это зависит от того, нужны вашей функции специальные, особенные данные для работы или нет. В вашем случае функция должна сказать, сколько занятий в тот день недели, который вас интересует. Поэтому такие специальные данные ей нужны. Ей нужно сказать, какой именно день недели вас интересует. Посмотрите на тело функции. Функция ожидает, что этот день недели будет находиться в переменной ДеньНедели. То есть значение, которое будет в этой переменной, функция должна получить откуда-то «снаружи». Чтобы платформа это поняла, напишите имя переменной ДеньНедели внутри круглых скобок (рис. 5). Рис. 5. Параметр функции Теперь платформа знает, что значение для переменной ДеньНедели будет получено в тот момент, когда вы вызовете эту функцию. Если это сейчас непонятно, не расстраивайтесь. Чуть позже вы увидите, как это происходит. Такие переменные, написанные в определении в скобках после имени функции, называются формальными параметрами функции. В данном случае слово «формальный» нужно понимать в значении «ожидаемый», «планируемый». Например, формально вы должны просыпаться в 7 часов утра, чтобы успеть в школу или на работу. Но фактически вы можете проспать, или, наоборот, проснуться раньше. Формально спектакль должен начаться в 7 часов вечера. Но фактически он может начаться позже, потому что не все зрители успели зайти в зал. То есть формальные параметры – это то, что функция ожидает получить в тот момент, когда вы ее вызовете. У вашей функции всего один формальный параметр. Другую переменную, Занятий, она создаст сама в процессе работы. Поэтому описание функции готово. После описания функции принято вставлять пустую строку. Так текст программы читается лучше. Вставьте ее и вы (рис 6). Рис. 6. Пустая строка после описания фукнции Теперь переместитесь в конец функции. Там есть строка Возврат … ;. «Возврат» – это специальное ключевое слово. С его помощью вы можете указать, что именно должна вернуть функция в то место, откуда ее вызвали. В вашем случае функция должна вернуть количество занятий. Оно получится в переменной Занятий. Поэтому после слова Возврат через пробел укажите имя этой переменной (рис. 7). Рис. 7. Возвращаемое значение Последняя строка – это КонецФункции. Перед ней тоже принято вставлять пустую строку, чтобы программа читалась лучше. Вставьте ее и вы (рис. 8). Рис. 8. Пустая строка перед концом функции Обратите внимание, что после слова КонецФункции нет точки с запятой. Это еще раз говорит о том, что функция не является инструкцией, которая будет выполняться. Функция – это просто специальная форма записи нескольких инструкций вместе. В стандартных настройках конфигуратора указано, что нужно группировать и сворачивать функции. Поэтому платформа автоматически дорисовала слева от вашей функции вертикальную линию со знаком «-» наверху (рис. 9). Рис. 9. Группировка и сворачивание функций Если вы нажмете мышью на «-», текст процедуры свернется, останется только ее определение. А «-» изменится на «+» (рис. 10). Рис. 10. Свернутая функция Это удобно в тех случаях, когда в одном модуле находится много функций. Тогда их можно быстро просмотреть и открыть ту, которая нужна. Итак, теперь ваша функция полностью готова. Если хотите, можете раскрыть ее обратно. Если не хотите, можете не раскрывать. Теперь вам нужно вызвать эту функцию в том месте, в котором нужно. А в котором нужно? Наверное, вы уже догадались. В том самом месте, откуда вы «утащили» инструкцию Если. Чтобы вызвать функцию, нужно написать ее имя, а в скобках – выражение или переменную. Значение этого выражения или переменной будет передано в функцию. А поскольку функция вернет вам количество занятий, то вызов функции нужно написать в инструкции присваивания. И присвоить это значение той переменной, которая вам нужна. То есть переменной Занятий (рис. 11). Рис. 11. Вызов функции Как будет работать эта инструкция? Сначала, как вы знаете, платформа вычислит выражение, которое находится справа от знака равенства. То есть она вызовет функцию СколькоЗанятий(). В эту функцию она передаст значение переменной ДеньНедели. В этом месте – там, где функция вызывается, – переменные, указанные в скобках, называются фактическими параметрами. То есть это то, что на самом деле будет передано в функцию. Результатом вычисления выражения справа от знака равенства будет значение, которое вернет ваша функция. И это значение будет присвоено переменной Занятий. После чего вы используете эту переменную, чтобы сформировать «печатаемую» строку. Чтобы убедиться, что вы не допустили ошибки, посмотрите на рисунок 12. Ваш модуль должен выглядеть так. Заодно еще раз обратите внимание на то, что называется фактическим параметром, а что – формальным. Рис. 12. Модуль с процедурой Теперь самое интересное! Установите точку останова в начале цикла и запустите «1С:Предприятие» в режиме отладки. Посмотрите, как это работает. Сделайте один шаг. Платформа остановится на инструкции присваивания. Она приготовится ее исполнять (рис. 13). Рис. 13. Перед вызовом функции Это первый «проход» цикла, поэтому день недели равен 1. Шагните еще раз. Платформа «провалится» в функцию (рис. 14). Рис. 14. Исполнение «провалилось» в функцию Обратите внимание, что платформа передала сюда значение дня недели 1. И теперь есть все необходимые данные для того, чтобы выполнить инструкцию Если. Сделайте еще три шага. Платформа остановится перед выполнением инструкции Возврат (рис. 15). Рис. 15. Инструкция «Возврат» Вы можете посмотреть, какое значение функция собирается возвращать. Это значение 6. Сделав еще шаг, вы перейдете на строку КонецФункции. Это значит, что исполнение функции закончилось. А шагнув еще раз, вы вернетесь обратно к инструкции присваивания (рис. 16). Рис. 16. Возврат в место вызова функции Сейчас у вас картинка очень похожа на то, что было на рис. 13. Платформа приготовилась выполнить инструкцию присваивания. Но если раньше платформа собиралась вычислить выражение, находящееся справа, то теперь она его уже вычислила. И сейчас она готова поместить получившееся значение в переменную. Сделайте один шаг. Исполнение перейдет к следующей строке. А в переменной Занятий появится значение 6. Это то значение, которое вернула функция (рис. 17). Рис. 17. Инструкция присваивания выполнена И если вы шагнете еще раз, то сформируется строка, предназначенная «для печати» (рис. 18). Рис. 18. Сформирован текст «для печати» После этого исполнение цикла продолжится, но день недели будет равен 2. И так далее. Можете пройти несколько итераций цикла и посмотреть еще раз, как работает этот пример. Итак, чтобы закрепить свои знания, посмотрите на рис. 19. На нем стрелками показана последовательность исполнения встроенного языка при вызове функции. Рис. 19. Последовательность исполнения при вызове функции В тот момент, когда платформа встречает вызов функции, исполнение «проваливается» в функцию (2). После того как функция выполнит инструкции, написанные в ее теле, исполнение возвращается в ту точку, из которой была вызвана функция. И только после этого исполнение встроенного языка переходит к следующей инструкции (3). Контекст и область видимости Вы, наверное, обратили внимание на то, что в вашем примере имена фактического и формального параметра совпали – ДеньНедели (рис. 20). Рис. 3.20. Имена фактического и формального параметров У вас это получилось случайно. Просто потому, что вы перетаскивали фрагмент программы из одного места в другое. На самом деле имена формальных и фактических параметров не совпадают. В этом нет необходимости. Чтобы разобраться с этим, упростите пример. В процедуре создайте переменную и напишите вызов функции. А функцию тоже упростите, чтобы она возвращала только два значения: 5 или 6. И обратите внимание, что в этом примере специально изменены имена переменных так, чтобы они были разными внутри функции и снаружи нее (рис. 21). Рис. 21. Упрощенный пример Установите точку останова на первой инструкции присваивания, запустите «1С:Предприятие» в режиме отладки и откройте локальные переменные. Они вам сейчас очень помогут разобраться с тем, что будет происходить (рис. 22). Рис. 22. Локальный контекст процедуры Сейчас вы находитесь в процедуре ПриНачалеРаботыСистемы(). Вы пока еще не знакомились с тем, что такое процедуры. Но это не страшно. Для этого примера будет достаточно представить, что процедура – это то же самое, что и функция. Так вот. Вы находитесь внутри процедуры. И здесь вам доступны переменные НомерДняНедели и Занятий. Они показаны в окне локальных переменных. Это те переменные, которые создаются и определяются в этой процедуре. Теперь сделайте пару шагов, чтобы перейти в функцию (рис. 23). Рис. 23. Локальный контекст функции Обратите внимание на то, что вы видите в окне локальных переменных. НомерДняНедели и Занятий исчезли. Зато вместо них появились ДеньНедели и КоличествоЗанятий, которые определены внутри этой функции. Теперь, если вы пройдете всю функцию и вернетесь обратно в процедуру, состав локальных переменных снова изменится (рис. 24). Рис. 24. Локальный контекст процедуры Он станет таким, каким он был в самом начале. Для обозначения этой ситуации во встроенном языке используют слово контекст. Контекст – это то, что доступно вам в том месте программы, в котором вы находитесь в данный момент. Если переменная определена в какой-то функции, то она доступна только в ней. И недоступна в других функциях. Поэтому в разных функциях вы можете создавать переменные с разными именами или с одинаковыми именами. В любом случае это будут разные переменные. Это правило относится и к параметрам функций. Переменные, которые указаны в качестве фактического и формального параметра, могут иметь одинаковые имена. Или разные имена. Это не важно. Потому что каждая из этих переменных существует только в контексте «своей» процедуры или функции. Теперь познакомьтесь с другим термином, который часто используется при написании программ. Это область видимости. Область видимости чего-то – это область конфигурации, откуда это что-то видно и доступно. Область видимости переменных ограничивается той функцией или процедурой, внутри которой они созданы. Если быть совсем точным, то область видимости переменной начинается с инструкции присваивания, в которой она создается, и заканчивается концом функции или процедуры (рис. 25). Рис. 25. Область видимости переменной «НомерДняНедели» Ради развлечения попробуйте использовать переменную НомерДняНедели в самом начале процедуры. Например, так, как на рисунке 26. Рис. 26. Попытка использовать процедуру до ее определения Если вы попробуете запустить такую программу, то получите вполне ожидаемую ошибку (рис. 27). Рис. 27. Сообщение об ошибке Действительно, в третьей строке переменная НомерДняНедели еще не определена. И платформа о ней ничего не знает. Эта переменная появится только двумя строками ниже. У процедур и функций тоже есть своя область видимости. Это весь модуль, в котором они определены. Именно поэтому и существует возможность вызвать функцию или процедуру из любого места модуля. Например, как в вашем примере, из другой процедуры. Процедуры Теперь, когда вы умеете создавать и использовать функции, можно заняться изучением процедур. Процедуры очень похожи на функции. Есть только одно отличие. Процедура ничего не возвращает. Она просто выполняет инструкции, которые находятся в ее теле. Во всем остальном процедуры выглядят точно так же, как функции, которые вам уже хорошо известны. Вместо слова Функция используется Процедура, а вместо КонецФункции используется КонецПроцедуры (рис. 28). Рис. 28. Пример процедуры В этом примере у процедуры нет параметров, но если нужно, вы можете их указать так же, как и в функции. Напишите в своей конфигурации этот пример. Процедура в этом примере проверяет, какой сейчас день недели. Если номер дня недели равен 7 (воскресенье), она выводит на экран напоминание о том, что завтра нужно идти в школу. Запустите этот пример и посмотрите, как выглядит это напоминание. Но не забывайте, что оно появится только в воскресенье. Если вы читаете книгу не в воскресенье, то вместо 7 напишите номер вашего текущего дня недели. Оповещение появится в небольшом окне в правой нижней части экрана, а затем постепенно пропадет (рис. 29). Рис. 29. Оповещение пользователя Для вывода такого оповещения вы использовали встроенную процедуру ПоказатьОповещениеПользователя(). Вы о ней ничего не знаете, просто написали так, как было на рисунке. Но наверняка вы хотите узнать, для чего нужна эта процедура и как ею пользоваться. В этом вам поможет синтакс-помощник. Причем найти в нем эту процедуру очень просто. Когда в тексте программы вам попадается незнакомая процедура или функция встроенного языка, вы можете просто установить на нее курсор и нажать сочетание клавиш Ctrl + F1. Откроется синтакс-помощник, и в его нижнем окне будет показано описание процедуры или функции (рис. 30). Рис. 30. Описание процедуры в синтакс-помощнике Если вы захотите узнать, какие еще есть похожие процедуры и функции, нажмите кнопку Найти текущий элемент в дереве на командной панели (рис. 31). Рис. 31. Кнопка «Найти текущий элемент в дереве» В верхнем окне синтакс-помощник раскроет дерево и отметит в нем вашу процедуру. Если вы пролистаете дерево вверх, то увидите, что есть еще большое количество процедур и функций, предназначенных для интерактивной работы. То есть для «общения» с пользователем (рис. 32). Рис. 32. Процедуры и функции интерактивной работы
|