Контекст и область видимости
Вы, наверное, обратили внимание на то, что в вашем примере имена фактического и формального параметра совпали – ДеньНедели (рис. 3.157).
Рис. 3.157. Имена фактического и формального параметров
У вас это получилось случайно. Просто потому, что вы перетаскивали фрагмент программы из одного места в другое.
На самом деле имена формальных и фактических параметров не совпадают. В этом нет необходимости.
Чтобы разобраться с этим, упростите пример. В процедуре создайте переменную и напишите вызов функции. А функцию тоже упростите, чтобы она возвращала только два значения: 5 или 6. И обратите внимание, что в этом примере специально изменены имена переменных так, чтобы они были разными внутри функции и снаружи нее (рис. 3.158).
Рис. 3.158. Упрощенный пример
Установите точку останова на первой инструкции присваивания, запустите «1С:Предприятие» в режиме отладки и откройте локальные переменные. Они вам сейчас очень помогут разобраться с тем, что будет происходить (рис. 3.159).
Рис. 3.159. Локальный контекст процедуры
Сейчас вы находитесь в процедуре ПриНачалеРаботыСистемы(). Вы пока еще не знакомились с тем, что такое процедуры. Но это не страшно. Для этого примера будет достаточно представить, что процедура – это то же самое, что и функция.
Так вот. Вы находитесь внутри процедуры. И здесь вам доступны переменные НомерДняНедели и Занятий. Они показаны в окне локальных переменных. Это те переменные, которые создаются и определяются в этой процедуре.
Теперь сделайте пару шагов, чтобы перейти в функцию (рис. 3.160).
Рис. 3.160. Локальный контекст функции
Обратите внимание на то, что вы видите в окне локальных переменных. НомерДняНедели и Занятий исчезли. Зато вместо них появились ДеньНедели и КоличествоЗанятий, которые определены внутри этой функции.
Теперь, если вы пройдете всю функцию и вернетесь обратно в процедуру, состав локальных переменных снова изменится (рис. 3.161).
Рис. 3.161. Локальный контекст процедуры
Он станет таким, каким он был в самом начале. На что это похоже?
Это похоже на то, что вы ходите из одной комнаты в другую. Каждая функция (процедура) – как отдельная комната. Например, гостиная и кухня.
Когда вы находитесь в гостиной, вы видите только то, что находится в гостиной. Диван, кресло, журнальный столик (рис. 3.162). Вы не видите то, что находится на кухне.
Рис. 3.162. Гостиная
Если вы выйдете из гостиной и зайдете на кухню, вы увидите то, что находится на кухне. Обеденный стол, стулья, холодильник, духовку (рис. 3.163).
Рис. 3.163. Кухня
И в это же время вы перестанете видеть, что находится в гостиной.
Для обозначения этой ситуации во встроенном языке используют слово контекст. Контекст – это то, что доступно вам в том месте программы, в котором вы находитесь в данный момент.
То есть, на языке программистов, когда вы в гостиной, «вы находитесь в контексте гостиной». А если вы на кухне, то «вы находитесь в контексте кухни».
Находясь в контексте гостиной, вы можете сесть в кресло и взять книгу с журнального столика. Когда вы находитесь в контексте кухни, кресло и журнальный столик вам недоступны. Но зато вы можете достать что-нибудь вкусное из холодильника или разогреть обед в духовке.
Если переменная определена в какой-то функции, то она доступна только в ней. И недоступна в других функциях. Поэтому в разных функциях вы можете создавать переменные с разными именами или с одинаковыми именами. В любом случае это будут разные переменные.
Это правило относится и к параметрам функций. Переменные, которые указаны в качестве фактического и формального параметра, могут иметь одинаковые имена. Или разные имена. Это не важно. Потому что каждая из этих переменных существует только в контексте «своей» процедуры или функции.
Если опять вернуться к гостиной и кухне: обратите внимание, что и там, и там есть телевизор. Эти телевизоры разные. Кухонный телевизор не видно из гостиной. А с кухни не видно тот телевизор, который находится в гостиной (рис. 3.162 и 3.163). Но показывают они одну и ту же программу.
Этим они очень похожи на фактический и формальный параметры. Телевизор в гостиной – это переменная, указанная в качестве фактического параметра. Телевизор на кухне – это переменная, указанная в качестве формального параметра. Когда вы уходите из гостиной и переходите на кухню, вы оказываетесь в другом контексте. Но с помощью формального параметра (кухонный телевизор), вы можете смотреть ту же передачу, что и в гостиной. Но уже в другом контексте.
ПРИМЕЧАНИЕ На самом деле понятие контекста во встроенном языке гораздо шире. В этом примере речь идет о локальном контексте. Локальный контекст – это только одна из частей, входящих в понятие «контекст». Но об этом я расскажу позже. |
Теперь познакомьтесь с другим термином, который часто используется при написании программ. Это область видимости.
Область видимости чего-то – это область конфигурации, откуда это что-то видно и доступно. Если вернуться на бытовой уровень, то область видимости холодильника – это кухня, а область видимости дивана – гостиная. |
Про переменные я уже рассказывал, что их область видимости ограничивается той функцией или процедурой, внутри которой они созданы.
Если быть совсем точным, то область видимости переменной начинается с инструкции присваивания, в которой она создается, и заканчивается концом функции или процедуры (рис. 3.164).
Рис. 3.164. Область видимости переменной «НомерДняНедели»
Ради развлечения попробуйте использовать переменную НомерДняНедели в самом начале процедуры. Например, так, как на рисунке 3.165.
Рис. 3.165. Попытка использовать процедуру до ее определения
Если вы попробуете запустить такую программу, то получите вполне ожидаемую ошибку (рис. 3.166).
Рис. 3.166. Сообщение об ошибке
Действительно, в третьей строке переменная НомерДняНедели еще не определена. И платформа о ней ничего не знает. Эта переменная появится только двумя строками ниже.
ПРИМЕЧАНИЕ Область видимости переменных может быть и шире. Но эти возможности находятся за рамками этой книги, поэтому о них я говорить не буду. |
У процедур и функций тоже есть своя область видимости. Это весь модуль, в котором они определены. Именно поэтому и существует возможность вызвать функцию или процедуру из любого места модуля. Например, как в вашем примере, из другой процедуры.
Если вспомнить, что каждую функцию вы сравнивали с комнатой, то можно сказать тогда, что модуль целиком – это квартира. Когда вы заходите в какую-то комнату (функцию) вы видите мебель (переменные). А на стене висит план всей квартиры. На котором написано, какие еще комнаты (процедуры и функции) есть в квартире (модуле) (рис. 3.167).
Рис. 3.167. План квартиры
ПРИМЕЧАНИЕ Область видимости процедур и функций может быть и шире. С этим вы познакомитесь в следующих разделах книги. |
3.29. Задание простое Создайте функцию, которая получает значение типа Дата. А возвращает эта функция текстовое представление месяца и года этой даты. Для формирования текстового представления используйте функцию ПредставлениеПериода(). Ее описание вы найдете в синтакс-помощнике в ветке Глобальный контекст – Функции форматирования. |
3.30. Задание сложное Возьмите программу из задания 3.19 (см. в этом разделе). Преобразуйте ее в функцию, которая получает две даты, а возвращает их разность в виде количества часов, минут и секунд. |
Процедуры
Теперь, когда вы умеете создавать и использовать функции, можно заняться изучением процедур.
Процедуры очень похожи на функции. Есть только одно отличие. Процедура ничего не возвращает. Она просто выполняет инструкции, которые находятся в ее теле.
Во всем остальном процедуры выглядят точно так же, как функции, которые вам уже хорошо известны. Вместо слова Функция используется Процедура, а вместо КонецФункции используется КонецПроцедуры (рис. 3.168).
Рис. 3.168. Пример процедуры
В этом примере у процедуры нет параметров, но если нужно, вы можете их указать так же, как и в функции.
Напишите в своей конфигурации этот пример. Процедура в этом примере проверяет, какой сейчас день недели. Если номер дня недели равен 7 (воскресенье), она выводит на экран напоминание о том, что завтра нужно идти в школу.
Запустите этот пример и посмотрите, как выглядит это напоминание. Но не забывайте, что оно появится только в воскресенье. Если вы читаете книгу не в воскресенье, то вместо 7 напишите номер вашего текущего дня недели.
Оповещение появится в небольшом окне в правой нижней части экрана, а затем постепенно пропадет (рис. 3.169).
Рис. 3.169. Оповещение пользователя
Для вывода такого оповещения вы использовали встроенную процедуру ПоказатьОповещениеПользователя(). Вы о ней ничего не знаете, просто написали так, как было на рисунке. Но наверняка вы хотите узнать, для чего нужна эта процедура и как ею пользоваться.
В этом вам поможет синтакс-помощник. Причем найти в нем эту процедуру очень просто.
Когда в тексте программы вам попадается незнакомая процедура или функция встроенного языка, вы можете просто установить на нее курсор и нажать сочетание клавиш Ctrl + F1. Откроется синтакс-помощник, и в его нижнем окне будет показано описание процедуры или функции (рис. 3.170).
Рис. 3.170. Описание процедуры в синтакс-помощнике
Если вы захотите узнать, какие еще есть похожие процедуры и функции, нажмите кнопку Найти текущий элемент в дереве на командной панели (рис. 3.171).
Рис. 3.171. Кнопка «Найти текущий элемент в дереве»
В верхнем окне синтакс-помощник раскроет дерево и отметит в нем вашу процедуру.
Если вы пролистаете дерево вверх, то увидите, что есть еще большое количество процедур и функций, предназначенных для интерактивной работы. То есть для «общения» с пользователем (рис. 3.172).
Рис. 3.172. Процедуры и функции интерактивной работы
3.31. Задание простое Пример из задания 3.29 (см. в этом разделе) преобразуйте в процедуру. Текстовое представление месяца и года переданной даты показывайте пользователю с помощью функции ПоказатьОповещениеПользователя(). |
3.32. Задание простое Пример из задания 3.30 (см. в этом разделе) преобразуйте в процедуру. Представление периода показывайте пользователю с помощью функции ПоказатьОповещениеПользователя(). |