Е. Ю. Хрусталева «1С:Предприятие.Элемент». Возможности встроенного языка Электронная книга в формате pdf; fpBN 978-5-9S77-3O55-3. Электронный аналог печатного издания «"NС:Предприятие.Элемент". Возможности встроенного языка» (fpBN 978-5-9S77-3O54-S, М.: ООО «NС-Паблишинг»; артикул печатной книги по прайс-листу фирмы «NС»: 4SMN54SN4S939); по вопросам приобретения печатных изданий издательства «NС-Паблишинг» обращайтесь к партнеру «NС»I обслуживающему вашу организациюI или к другим партнерам фирмы «NС»I в магазины «NС Интерес»I а также в книжные и интернет-магазины). Эта книга адресована специалистам, разрабатывающим прикладные решения на платформе «1С:Предприятие 8». Она содержит сжатое описание особенностей нового языка разработки, который используется в технологии «1С:Предприятие.Элемент». Основная цель издания – помочь максимально быстро начать разработку на новом языке, овладев новыми возможностями, подходами и не упустив при этом ничего важного. Книга содержит значительное количество коротких и простых примеров, которые позволят быстрее и легче понять особенности нового языка. Для создания примеров использовалась версия O.M технологии «1С:Предприятие.Элемент». Книга выпущена под редакцией Максима Радченко. Оглавление Введение . ...........................................................................................................................................7 Термины, используемые в книге..........................................................................................................9 Глава 1. Синтаксические отличия...................................................................................................... 11 Ввод английских символов без переключения раскладки клавиатуры....................................... 12 Регистрозависимый синтаксис..................................................................................................................... 13 Особенности именования переменных в языке «Элемента»........................................................... 14 Ключевые слова................................................................................................................................................ 14 Многострочные комментарии...................................................................................................................... 16 Упрощенные инструкции................................................................................................................................ 17 Простые инструкции......................................................................................................................................17 Составные инструкции..................................................................................................................................17 «Лишние» слова в составных инструкциях............................................................................................18 Процедуры и функции называются методами....................................................................................... 19 Текучий интерфейс........................................................................................................................................... 20 Глава 2. Типизация данных, переменные, константы. Передача параметров............................. 23 Статическая типизация.................................................................................................................................... 24 Пример объявления переменной..............................................................................................................24 Пример объявления типов параметров..................................................................................................25 Пример объявления типов возвращаемых значений........................................................................25 Пример использования обобщенного типа...........................................................................................25 Пример использования функционального типа..................................................................................26 Динамическая типизация............................................................................................................................... 27 Иерархия типов................................................................................................................................................. 28 Составные типы................................................................................................................................................. 30 Особенности обращения к членам выражений составного типа..................................................32 Объявление переменных............................................................................................................................... 33 Модификаторы.................................................................................................................................................33 Имя переменной.............................................................................................................................................34 Тип........................................................................................................................................................................34 Начальное значение......................................................................................................................................34 Инициализатор.................................................................................................................................................35 Ограничения.....................................................................................................................................................35 Константы............................................................................................................................................................. 36 3 «1С:Предприятие.Элемент». Возможности встроенного языка Методы.................................................................................................................................................................. 37 Типы параметров.............................................................................................................................................37 Значения по умолчанию...............................................................................................................................37 Передача параметров по значению.........................................................................................................39 Позиционные и именованные аргументы..............................................................................................41 Перегрузка методов.......................................................................................................................................43 Разрешение неоднозначности при использовании именованных аргументов.......................... 46 Глава 3. Операции, инструкции, типы............................................................................................... 49 Операции............................................................................................................................................................. 50 Арифметические операции.........................................................................................................................50 Логические операции....................................................................................................................................52 Тернарная операция «?»...............................................................................................................................53 Операция «это»................................................................................................................................................54 Операция «как»................................................................................................................................................55 Операции для работы со значением «Неопределено».....................................................................56 Настойчивая операция.................................................................................................................................... 56 Операция «Безопасный доступ»...................................................................................................................57 Операция «Умолчание»................................................................................................................................... 58 Инструкции.......................................................................................................................................................... 59 «если»..................................................................................................................................................................59 «выбор»..............................................................................................................................................................59 Стандартные типы............................................................................................................................................. 61 Строка..................................................................................................................................................................61 Экранирование символов.............................................................................................................................. 61 Интерполяция строк......................................................................................................................................... 62 Многострочные литералы............................................................................................................................... 63 Методы.................................................................................................................................................................. 63 Число...................................................................................................................................................................65 Литералы.............................................................................................................................................................. 65 Форматирование............................................................................................................................................... 65 Методы.................................................................................................................................................................. 70 ДатаВремя.........................................................................................................................................................70 Литералы.............................................................................................................................................................. 70 Конструкторы...................................................................................................................................................... 71 Форматирование............................................................................................................................................... 71 Методы.................................................................................................................................................................. 73 Длительность.....................................................................................................................................................74 Коллекции..........................................................................................................................................................75 Массив................................................................................................................................................................... 76 Соответствие........................................................................................................................................................ 79 Множество............................................................................................................................................................ 82 Собственные типы............................................................................................................................................ 84 Перечисление...................................................................................................................................................84 Структура............................................................................................................................................................86 Исключения.......................................................................................................................................................88 Инструкция «попытка»..................................................................................................................................... 90 4 Оглавление Инструкция «выбросить»................................................................................................................................ 92 Стандартные типы исключений.................................................................................................................... 93 Обобщенные типы............................................................................................................................................ 94 Обобщенные системные методы................................................................................................................ 96 Статические системные методы................................................................................................................... 97 Типы-одиночки.................................................................................................................................................. 98 Функциональные типы.................................................................................................................................... 99 Лямбда-выражения.....................................................................................................................................101 Ссылки на методы........................................................................................................................................102 Примеры использования функциональных типов...........................................................................102 Хранение метода в переменной................................................................................................................102 Ссылка на системный метод........................................................................................................................103 Вызов системного метода с параметром функционального типа..................................................103 Передача метода в другой метод..............................................................................................................104 Рекомендации при написании кода.........................................................................................................105 Регулярные выражения................................................................................................................................106 Образец........................................................................................................................................................... 107 Совпадение....................................................................................................................................................110 Примеры использования регулярных выражений...........................................................................110 Пример 1............................................................................................................................................................110 Пример 2............................................................................................................................................................111 Пример 3............................................................................................................................................................112 Пример 4............................................................................................................................................................113 Пример 5............................................................................................................................................................113 Глава 4. Создание прикладных решений в «Элементе»............................................................... 115 Ключевое слово «этот».................................................................................................................................116 Аннотации..........................................................................................................................................................116 Аннотации видимости................................................................................................................................ 117 Аннотации окружения................................................................................................................................118 Аннотация «ИменованныеПараметры»...............................................................................................119 Аннотация «ВыполнятьПриЗагрузкеДанных»....................................................................................119 Модульная разработка..................................................................................................................................120 Видимость языковых конструкций.........................................................................................................121 Квалифицированное имя элемента......................................................................................................122 Импорт пространств имен.........................................................................................................................124 Исполнение модуля.......................................................................................................................................124 Статические методы элементов проекта.............................................................................................126 Передача исполнения с клиента на сервер........................................................................................ 127 Запросы..............................................................................................................................................................128 Использование литерала запроса..........................................................................................................128 Обход результата запроса........................................................................................................................129 Явное указание типа строки.....................................................................................................................129 Параметры запроса.....................................................................................................................................130 Загрузка данных..............................................................................................................................................131 5 6 Введение Встроенный язык технологии «1С:Предприятие.Элемент» – это новый язык разработки, который базируется на встроенном языке платформы «1С:Предприятие 8», но имеет ряд существенных отличий от него. Например: ■■ язык является статически типизированным; ■■ в языке присутствует иерархия типов; ■■ нет разделения на функции и процедуры – используется единое ключевое слово «метод»; ■■ поддерживается перегрузка методов; ■■ поддерживаются пользовательские и исключения и т. д. структуры, перечисления Далеко не всегда у вас есть возможность спокойно и вдумчиво изучить всю документацию. Чаще всего хочется сразу же попробовать те или иные возможности нового языка, о которых вы уже где-то когда-то слышали. Именно для этого и предназначена книга, которую вы держите в руках. С одной стороны, не вдаваясь в глубокие подробности, она рассказывает о новых возможностях языка. С другой стороны, в книге описаны важные и заметные изменения, с которыми вам придется столкнуться буквально с первых шагов в новом языке. 7 «1С:Предприятие.Элемент». Возможности встроенного языка Простые и короткие примеры позволят вам быстрее и легче понять особенности нового языка. Вся информация в книге сгруппирована по нескольким разделам, от простого к сложному: от элементарных синтаксических отличий – к сложным функциональным типам и запросам. 8 Термины, используемые в книге В книге будут использоваться следующие термины и понятия: ■■ Значение – этот термин используется в общепринятом смысле: элемент данных, являющийся одним из возможных членов типа данных, который может соответствовать некоторому состоянию переменной или константе соответствующего типа. ■■ Тип – это множество допустимых значений и контракт. ■■ Экземпляр – это значение типа. ■■ Контракт – набор свойств и методов, присущих тому или иному типу, а также поведение этих свойств и методов. ■■ Переменная – это ссылка на область памяти, которая хранит значение какого-либо типа. Для идентификации переменной служит ее имя. ■■ Метод – это фрагмент кода на встроенном языке, к которому можно обратиться из другого места модуля или из другого модуля. О том, что метод что-либо возвращает, можно судить по тому, что у метода описан тип возвращаемого значения. ■■ Параметр – это имя переменной, через которую тело метода получает доступ к значению, которое предоставляется методу во время его вызова (аргумент). 9 «1С:Предприятие.Элемент». Возможности встроенного языка ■■ Операция – этот термин используется в общепринятом смысле: конструкция в языках программирования, аналогичная по записи математическим операциям, то есть специальный способ записи некоторых действий. Наиболее часто применяются арифметические, логические и строковые операции. Операция выполняется над одним или несколькими операндами. ■■ Операнд – это значение, над которым выполняется операция. ■■ Инструкция – это наименьшая автономная часть встроенного языка; команда или набор команд. Программа обычно представляет собой последовательность инструкций. Например, инструкцию присваивания можно представить строкой: А = 4 + 2. ■■ Выражение – это математическая, логическая или строковая формула, по которой вычисляется значение. Выражение может состоять из констант, переменных и вызовов методов, связанных символами логических, арифметических и других операций. ■■ Ключевое слово – это слово, которое нельзя использовать в качестве имени переменной или метода. Оно зарезервировано для использования только в синтаксических конструкциях языка. Например: если, возврат и т. д. ■■ Литерал – это значение, записанное прямо в тексте программы. ■■ Язык «1С:Предприятия» – это встроенный язык платформы «1С:Предприятие 8». Он позволяет разработчику описывать собственные алгоритмы функционирования прикладного решения. ■■ Язык «Элемента» – это встроенный язык «1С:Предприятие.Элемент». Он используется: технологии ○○ для написания скриптов, автоматизирующих администрирование систем, основанных на платформе «1С:Предприятие 8»; ○○ для решения алгоритмических задач, возникающих при создании и модификации приложений, использующих технологию «1С:Предприятие.Элемент». 10 ГЛАВА 1 Синтаксические отличия 11 «1С:Предприятие.Элемент». Возможности встроенного языка Ввод английских символов без переключения раскладки клавиатуры В языке «1С:Предприятия» использовались символы, которые обычно расположены в английской раскладке клавиатуры. Это, например, такие символы: < и > – логические операции «меньше» и «больше», например: Если ТекСтрока > ВсегоСтрок Тогда | – символ продолжения текстового литерала, например: Запрос.Текст = "ВЫБРАТЬ | Наименование |ИЗ | Справочник.Товары"; [ и ] – обращение к элементу коллекции по индексу или имени, например: Возврат ВыделенныеЭлементы[0]; ' – одинарные кавычки – обрамляли литералы даты, например: НачалоПериода = ‘20170323104525’; & – амперсанд – использовался в директивах компиляции, например: &НаКлиенте # – решетка – использовалась в инструкциях препроцессора, например: #Если ВебКлиент Тогда Для ввода этих символов приходилось переключаться на английскую раскладку клавиатуры, что было неудобно. Теперь в средах разработки, использующих язык «Элемента», реализована возможность вводить символы из английской раскладки, не переключаясь на нее, – так называемый Alt-ввод. Во всех случаях, где это возможно, используется одно и то же правило. Чтобы ввести английский символ, удерживайте клавишу Alt и нажмите ту клавишу, на которой находится нужный вам английский символ. Такая возможность реализована не для всех английских символов, а только для тех, которые используются в языке «Элемента». 12 Глава 1. Синтаксические отличия Например: ■■ Для ввода вертикальной черты |, которая используется, например, при перечислении типов, используйте Alt + \; пер ПеременнаяСоставногоТипа: Число|Булево = 3 ■■ Для ввода фигурных скобок { и }, которые используются, например, при включении в строковый литерал вычисляемых выражений, используйте Alt + 9 и Alt + 0; пер ТекстСообщения = "Объем %{100*50*70/2} литров" ■■ Для ввода угловых скобок < и >, которые используются, например, в логических выражениях, используйте Alt + б и Alt + ю; ; если Счетчик < 7 возврат ■■ Для ввода квадратных скобок [ и ], которые используются, например, в литерале массива, используйте Alt + х и Alt + ъ, а для указания типа элементов массива – Alt + б и Alt + ю; пер МассивЧисел = <Число>[0, 1, 2] ■■ Кроме перечисленных символов есть и другие, которые вы можете ввести аналогичным образом: ○○ амперсанд & – Alt + 7; ○○ коммерческое at (собака) @ – Alt + 2; ○○ апостроф ' – Alt + э; ○○ слеш / – Alt + . Регистрозависимый синтаксис В языке «1С:Предприятия» можно было писать имя переменной в разных регистрах. Компилятор воспринимал оба варианта написания как одну и ту же переменную. Например: ИмяДокумента = "Доходы" Имядокумента = "Расходы" Теперь в языке «Элемента» переменные, отличающиеся регистром букв, будут являться разными переменными. Например, переменная ИмяДокумента, объявленная выше и отличающаяся регистром одной буквы, – это другая переменная (рис. 1.1). 13 «1С:Предприятие.Элемент». Возможности встроенного языка Рис. 1.1. Неправильное написание имени переменной Поэтому в третьей строке будет получена ошибка – «Переменная "Имядокумента" не определена», так как там происходит обращение к переменной Имядокумента, которая еще не объявлена. Особенности именования переменных в языке «Элемента» В языке «Элемента» нельзя объявить две переменные, имена которых отличаются только регистром букв. При попытке сделать это вы получите ошибку «Переменная с именем "Имядокумента" уже определена». Например, (рис. 1.2): Рис. 1.2. Неправильное объявление имени переменной Ключевые слова В языке «1С:Предприятия» в ключевых словах можно было использовать как строчные, так и прописные буквы. Несмотря на то что писать можно было как угодно, для повышения «читабельности» ключевые слова обычно писали в стиле CamelCase. Это значит, что если имя состоит из одного слова, то оно пишется с прописной буквы, остальные буквы – строчные. Если имя состоит из нескольких слов, – они пишутся слитно без пробелов, при этом каждое слово внутри пишется с прописной буквы. Например, ключевые слова Если, Возврат и КонецЕсли: Если Счетчик < 7 Тогда Возврат; КонецЕсли; Теперь в языке «Элемента» все ключевые слова нужно писать строчными буквами. Например: если Счетчик < 7 возврат ; 14 Глава 1. Синтаксические отличия Если вы попробуете написать слово «Возврат» с прописной буквы, то получите ошибку «Переменная "Возврат" не определена» (рис. 1.3). Рис. 1.3. Неправильное написание ключевого слова Это говорит о том, что среда разработки не воспринимает слово «Возврат» (написанное с прописной буквы) как ключевое слово. Она думает, что это переменная, которую вы забыли определить. Почему в языке «Элемента» принято писать ключевые слова строчными буквами? Дело в том, что пока вы работаете с текстом программы в среде разработки, он раскрашивается, и преимущество того, что ключевые слова пишутся строчными буквами, вам не очень заметно (рис. 1.4). Рис. 1.4. Подсвеченный фрагмент кода в среде разработки 15 «1С:Предприятие.Элемент». Возможности встроенного языка Но как только вы столкнетесь с системами контроля версий или другими инструментами, в которых подсветка языка «Элемента» отсутствует, вы увидите, что ключевые слова в нижнем регистре значительно упрощают чтение программы (рис. 1.5). Рис. 1.5. Неподсвеченный фрагмент кода Многострочные комментарии В языке «1С:Предприятия», чтобы закомментировать несколько строк, идущих подряд, нужно было установить символ комментария в начале каждой строки. Например: // Начало комментариев // Вторая строка комментариев // Конец комментариев Это можно было сделать вручную, установив комментарий в каждой строке, или с помощью команд меню, выделив блок кода, а затем установив или сняв комментарии одной командой. Если блок комментируемого кода был большой, то такая операция была не очень удобна. 16 Глава 1. Синтаксические отличия Теперь в языке «Элемента» существуют отдельные служебные символы, которые позволяют комментировать блок кода. Это символы «/*» в начале и «*/» в конце. Например: /* Начало комментариев Вторая строка комментариев Конец комментариев */ Таким образом, если нужно закомментировать большой фрагмент кода, вы ставите в его начале «/*», а потом просто пролистываете до нужного места и ставите в конце «*/». Все, что находится между этими символами, будет оформлено как комментарий. Упрощенные инструкции Простые инструкции В языке «1С:Предприятия» любая инструкция всегда заканчивалась символом «;». Например: Результат = Переменная1 + Переменная2; Результат2 = Результат - Переменная3; Теперь в языке «Элемента» окончание простой инструкции никак обозначать не нужно, компилятор сам «разберется», где кончается одна и где начинается другая. Например: пер Результат = Переменная1 + Переменная2 пер Результат2 = Результат – Переменная3 При этом простая инструкция может располагаться на нескольких строках, но начинаться инструкция должна на новой строке. Например: пер Результат = Переменная1 + Переменная2 пер Результат2 = Результат – Переменная3 Составные инструкции В языке «1С:Предприятия» составная инструкция всегда заканчивалась «собственным» ключевым словом и символом «;». Например: КонецЕсли;, КонецЦикла;: Если Счетчик < 7 Тогда Возврат; КонецЕсли; 17 «1С:Предприятие.Элемент». Возможности встроенного языка Окончание блока инструкций (операторные скобки) также обозначалось собственным ключевым словом: КонецПроцедуры, КонецФункции и так далее. Например: Процедура МояПроцедура() Переменная1 = 4; КонецПроцедуры Теперь в языке «Элемента» окончание составной инструкции, а также окончание блока инструкций (операторные скобки) обозначаются одним и тем же символом «;», который обязательно должен находиться на новой строке. Например: если Счетчик < 7 возврат ; метод МойМетод() пер Переменная1 = 4 ; «Лишние» слова в составных инструкциях В языке «1С:Предприятия» многие составные инструкции содержали избыточные ключевые слова, без которых теперь в языке «Элемента» можно обойтись. Например, в инструкции Если не нужно использовать ключевое слово Тогда: // Язык "1С:Предприятия" Если Счетчик < 7 Тогда Возврат; КонецЕсли; // Язык "Элемента" если Счетчик < 7 возврат ; В инструкции Для…по не нужно использовать ключевое слово Цикл: // Язык "1С:Предприятия" Для Счетчик = 1 по 5 Цикл ЗагрузитьЭлемент(Счетчик); КонецЦикла; // Язык "Элемента" для Счетчик = 1 по 5 ЗагрузитьЭлемент(Счетчик) ; 18 Глава 1. Синтаксические отличия В инструкции Пока не нужно использовать ключевое слово Цикл: // Язык "1С:Предприятия" Счетчик = 1; Пока Счетчик < 5 Цикл ЗагрузитьЭлемент(Счетчик); Счетчик = УвеличитьСчетчик(Счетчик); КонецЦикла; // Язык "Элемента" пока Счетчик = 1 по 5 ЗагрузитьЭлемент(Счетчик) Счетчик = УвеличитьСчетчик(Счетчик) ; В инструкции Для…из не нужно использовать ключевое слово Каждого и Цикл: // Язык "1С:Предприятия" Для Каждого Элемент Из МассивЭлементов Цикл ОбработатьЭлемент(Элемент); КонецЦикла; // Язык "Элемента" для Элемент из МассивЭлементов ОбработатьЭлемент(Элемент) ; Процедуры и функции называются методами В языке «1С:Предприятия» многократно используемые блоки кода назывались функциями, если они возвращали какое-то значение, и процедурами, если они ничего не возвращали. Например: Процедура МояПроцедура() Результат = 2 + 6; КонецПроцедуры Функция МояФункция() Возврат 8; КонецФункции Теперь в языке «Элемента» и процедуры, и функции называются методами. Например: метод МойМетод1() пер Результат = 2 + 6 ; метод МойМетод2(): Число возврат 8 ; 19 «1С:Предприятие.Элемент». Возможности встроенного языка О том, что метод МойМетод2() что-то возвращает, понятно по тому, что у него описан тип возвращаемого значения – «: Число». Соответственно, метод МойМетод1() ничего не возвращает, так как у него тип возвращаемого значения не описан (подробнее см. раздел «Пример объявления типов возвращаемых значений»). Текучий интерфейс В языке «1С:Предприятия» практически нигде не было возможности получить объект как результат выполнения его метода. Например, для того чтобы создать XML с определенным содержимым, нужно было сохранить в переменной объект записи, а затем снова и снова вызывать методы от этой переменной. В результате такой код выглядел довольно громоздким. Например: Процедура ЗаписьXml() Запись = Новый ЗаписьXML; Запись.ОткрытьФайл("C:\test\test.xml"); Запись.ЗаписатьНачалоЭлемента("product"); Запись.ЗаписатьАтрибут("code", "138"); Запись.ЗаписатьНачалоЭлемента("description"); Запись.ЗаписатьТекст("Холодильник"); Запись.ЗаписатьКонецЭлемента(); Запись.ЗаписатьНачалоЭлемента("price"); Запись.ЗаписатьТекст("30000"); Запись.ЗаписатьКонецЭлемента(); Запись.ЗаписатьНачалоЭлемента("count"); Запись.ЗаписатьТекст("20"); Запись.ЗаписатьКонецЭлемента(); Запись.ЗаписатьКонецЭлемента(); КонецПроцедуры Теперь в языке «Элемента» для некоторых типов реализован текучий интерфейс (Fluent API). Его суть заключается в том, что методы возвращают контекст своего вызова, благодаря чему упрощается множественный вызов методов одного экземпляра. Внешне это выглядит как цепочка методов, вызываемых последовательно. Например, чтобы выполнить предыдущий пример, создается экземпляр записи XML и от него через точку в каждой новой строке вызываются соответствующие методы. 20 Глава 1. Синтаксические отличия Такая запись выглядит более простой и легче читается: метод Скрипт() исп ПотокЗаписи = новый Файл("C:\\test\\test.xml").ОткрытьПотокЗаписи() пер Запись = новый ЗаписьXml(ПотокЗаписи) Запись.ЗаписатьНачалоЭлемента("product") .ЗаписатьАтрибут("code", "138") .ЗаписатьНачалоЭлемента("description") .ЗаписатьТекст("Холодильник") .ЗаписатьКонецЭлемента() .ЗаписатьНачалоЭлемента("price") .ЗаписатьТекст("30000") .ЗаписатьКонецЭлемента() .ЗаписатьНачалоЭлемента("count") .ЗаписатьТекст("20") .ЗаписатьКонецЭлемента() .ЗаписатьКонецЭлемента() ; 21 «1С:Предприятие.Элемент». Возможности встроенного языка 22 ГЛАВА 2 Типизация данных, переменные, константы. Передача параметров 23 «1С:Предприятие.Элемент». Возможности встроенного языка Статическая типизация В языке «1С:Предприятия» использовалась динамическая типизация. Типы переменных, параметров, значений, возвращаемых функциями, и т. п. определялись динамически в момент исполнения программы. Если в некоторую процедуру передавалось значение такого типа, на работу с которым эта процедура не рассчитана, то обнаруживалось это только во время выполнения программы. В процессе написания и компиляции программы автоматически обнаружить это было невозможно. Поэтому о наличии таких ошибок зачастую можно было узнать только от недовольных пользователей, что не есть хорошо. Теперь в языке «Элемента» используется статическая типизация. Это значит, что при объявлении переменной, параметра или метода, возвращающего значение, сразу должен быть указан тип. В результате еще в момент компиляции проверяется соответствие типов переменных, параметров и т. д. и присваиваемых им значений. То есть вы не можете в переменную, описанную с типом Число, записать значение типа Строка. Таким образом, статическая типизация языка «Элемента» позволяет увидеть и исправить многие ошибки еще на стадии компиляции программы, что является несомненным преимуществом языка «Элемента». Ниже приводятся примеры объявления переменных, параметров методов, типов значений, возвращаемых методами, и коллекций в языке «1С:Предприятия», где указывать тип не требуется, и в языке «Элемента», где тип нужно указывать обязательно. Эти примеры имеют ознакомительный характер. Ниже все эти объявления будут рассмотрены более подробно. Пока лишь поясним, что типы элементов коллекций указываются в угловых скобках («<» и «>»), в остальных случаях типы указываются с помощью символов «: » (двоеточие без пробела справа от имени переменной, параметра и т. п., затем пробел и имя типа). Пример объявления переменной В языке «1С:Предприятия»: Перем ИмяСотрудника; ИмяСотрудника = "Сергей"; 24 //явное объявление //неявное объявление Глава 2. Типизация данных, переменные, константы. Передача параметров В языке «Элемента»: пер ИмяСотрудника: Строка пер ИмяСотрудника = "Сергей" //объявление с указанием типа //объявление с указанием значения Пример объявления типов параметров В языке «1С:Предприятия»: Процедура УзнатьПлощадь(Длина, Ширина) Площадь = Длина * Ширина; КонецПроцедуры В языке «Элемента»: метод УзнатьПлощадь(Длина: Число, Ширина: Число) пер Площадь = Длина * Ширина ; Пример объявления типов возвращаемых значений В языке «1С:Предприятия»: Функция УзнатьПлощадь(Длина, Ширина) Возврат Длина * Ширина; КонецФункции В языке «Элемента»: метод УзнатьПлощадь(Длина: Число, Ширина: Число): Число возврат Длина * Ширина ; Пример использования обобщенного типа В языке «1С:Предприятия» не использовались обобщенные типы, то есть коллекции значений были не типизированными. Например, в массив можно было записать значения разных типов, и тип элементов массива никак не контролировался. Например: Массив = Новый Массив(); Массив.Добавить(1); Массив.Добавить(3); Массив.Добавить("пять"); Массив.Добавить(7); Массив.Добавить(Ложь); Теперь в языке «Элемента» все коллекции являются типизированными. Для их объявления используются обобщенные типы. 25 «1С:Предприятие.Элемент». Возможности встроенного языка ПОДРОБНЕЕ Подробнее про обобщенные типы будет рассказано в 3-й главе в разделе «Обобщенные типы». При создании экземпляра коллекции с помощью конструктора тип элементов коллекции указывается в угловых скобках после имени типа без пробела. Например: пер МассивЧисел = новый Массив<Число>() МассивЧисел = [11, 55, 33] //в этом массиве могут быть только числа При этом в коллекцию нельзя записать элемент иного типа, чем тот, с которым она объявлена. При создании экземпляра коллекции с помощью литерала тип элементов коллекции можно явно указать слева от списка элементов без пробела, а можно и не указывать, если он вычисляется из списка элементов. Причем этот тип может быть составным. Например: пер Строки = ["один", "два", "три"] пер Строки = <Строка>["один", "два", "три"] пер ЧислаИСтроки = <Число|Строка>["один", 2, "три"] //тип элементов массива - Строка //тип элементов массива - Строка //тип элементов массива – Строка или Число Пример использования функционального типа В языке «1С:Предприятия» не использовались функциональные типы. Теперь в языке «Элемента» существуют функциональные типы, значениями которых являются методы. Функциональные типы позволяют хранить методы в переменных, передавать их в другие методы как аргументы и возвращать как результат. ПОДРОБНЕЕ Подробнее про функциональные типы будет рассказано в 3-й главе в разделе «Функциональные типы». В следующем примере в переменную ДлинаСтроки присваивается значение метода Длина() базового типа Строка: 26 // Первый вариант - ссылка на метод знч МетодДлина = &Строка.Длина() пер ДлинаСтроки = МетодДлина("функциональный тип") //ДлинаСтроки = 18 // Второй вариант - лямбда выражение знч ЛямбдаДлина = (Строка: Строка) -> Строка.Длина() ДлинаСтроки = ЛямбдаДлина("выражение") //ДлинаСтроки = 9 Глава 2. Типизация данных, переменные, константы. Передача параметров Динамическая типизация В языке «Элемента» помимо вышеописанной статической типизации данных существует возможность динамической типизации в стиле «1С:Предприятия». Для этого в описании типа нужно использовать ключевое слово неизвестно. В этом случае все проверки кода с момента написания переносятся на момент его выполнения. В следующем примере переменная Значение принимает сначала значение типа Строка, а затем – типа Число. Тип переменной определяется динамически на этапе исполнения программы, и на этапе компиляции ошибок не возникнет: пер Значение: неизвестно Значение = "строка" Значение = 32 Если при объявлении нетипизированной переменной (описанной с ключевым словом неизвестно) отсутствует значение инициализации, то она инициализируется значением Неопределено. При описании типов параметров и типов возвращаемых значений методов также можно использовать ключевое слово неизвестно, чтобы отключить проверку типов компилятора до момента исполнения. Например: //Объявление метода с параметрами неизвестного типа метод УзнатьПлощадь(Длина: неизвестно, Ширина: неизвестно) пер Площадь = Длина * Ширина ; //Объявление метода, возвращающего значениие неизвестного типа метод УзнатьПлощадь(Длина: неизвестно, Ширина: неизвестно): неизвестно возврат Длина * Ширина ; Однако пользоваться динамической типизацией стоит лишь опытным разработчикам и только в тех случаях, когда это действительно необходимо. 27 «1С:Предприятие.Элемент». Возможности встроенного языка Иерархия типов В языке «1С:Предприятия» все типы были независимы друг от друга, между ними не существовало никаких связей. Теперь в языке «Элемента» все типы имеют строгую иерархию. В основании иерархии типов лежит тип Объект. Этот тип является базовым для всех типов, кроме типа Неопределено. При этом потомок какого-либо типа наследует контракт своего предка (набор операций, которые можно выполнять над данными, принадлежащими этому типу), но каким-либо образом расширяет или допустимые значения, или контракт, или оба этих параметра. Таким образом, если какой-то тип является потомком типа Обходимое, то значения такого типа можно обходить (например в цикле для…из). Если тип является потомком типа Сравнимое, то значения такого типа могут участвовать в операциях сравнения, и т. д. Предка какого-либо типа также можно назвать его базовым типом, а потомка от него – производным типом. У одного типа может быть несколько базовых типов. Для определения и сравнения типов, а также для получения информации о иерархии типов в языке «Элемента» существует специальный тип Тип. У каждого из производных типов существует метод ПолучитьТип(), который возвращает значение типа Тип. Чтобы получить список базовых типов конкретного типа, у экземпляра типа Тип используется свойство БазовыеТипы. Например: пер БазовыеТипы = СобратьПредков(Тип<Число>) метод СобратьПредков(Значение: Тип, Предки: Множество<Тип> = {}): Множество<Тип> для БазовыйТип из Значение.БазовыеТипы Предки.Добавить(БазовыйТип) СобратьПредков(БазовыйТип, Предки) ; возврат Предки ; 28 Глава 2. Типизация данных, переменные, константы. Передача параметров У типа Число список базовых типов будет иметь вид (рис. 2.1): Рис. 2.1. Список базовых типов у типа «Число» У типа Булево список базовых типов будет иметь вид (рис. 2.2): Рис. 2.2. Список базовых типов у типа «Булево» У типа Массив<Число> список базовых типов будет иметь вид (рис. 2.3): Рис. 2.3. Список базовых типов у типа «Массив<Число>» Переменной базового типа можно присвоить значение производного типа, но обратное присваивание невозможно. 29 «1С:Предприятие.Элемент». Возможности встроенного языка Например: пер Переменная1: Сравнимое<Число> = 33 пер Переменная2: Число = 11 Переменная1 = Переменная2 При вызове системного обобщенного метода в угловых скобках также можно опционально указать, что параметр метода может быть наследником определенного типа. В следующем примере указывается, например, что параметры метода Мин() могут быть только наследниками типа Сравнимое: пер Переменная1 = Мин<Сравнимое<Число>>(11, 7, 13) пер Переменная2 = Мин<Сравнимое<Строка>>("90", "66", "82") пер Переменная3 = Мин<Сравнимое<Булево>>(Ложь, Истина) //результат = 7 //результат = "66" //результат = false ПОДРОБНЕЕ Подробнее про обобщенные методы будет рассказано в 3-й главе в разделе «Обобщенные системные методы». Составные типы В языке «1С:Предприятия» составной (как и любой другой) тип данных указать было нельзя. Набор составных типов можно было задать только на этапе конфигурирования свойств прикладных объектов. Например, реквизиту справочника можно было указать составной тип Строка, Число. Тогда в модуле объекта переменная, соответствующая этому реквизиту, имела составной тип (рис. 2.4). Теперь в языке «Элемента» можно указать, что переменная, параметр и т. п. будут принимать значение одного из нескольких типов. Для этого при объявлении им присваивается составной тип. Для задания составного типа используется синтаксис перечисления типов, разделенных символом «|» без пробелов с обеих сторон от вертикальной черты. Например, чтобы указать, что переменная может принимать значения типов Строка, Число или Булево, ее нужно объявить следующим образом: пер Переменная1: Строка|Число|Булево = 7 Одним из перечисляемых типов может быть тип Неопределено. 30 Глава 2. Типизация данных, переменные, константы. Передача параметров Рис. 2.4. Составной тип данных у реквизита справочника Если в составном типе есть тип Неопределено, то переменная инициализируется значением Неопределено. А если нет типа Неопределено, то тогда обязательно должен быть указан инициализатор переменной (литерал либо выражение, значение которого будет иметь объявляемая переменная). В приведенном выше примере переменная инициализирована значением 7 – литералом типа Число. Если в составном типе присутствует тип Неопределено, то в списке типов его явно указывать не нужно – вместо него лучше использовать сокращение «?», которое рекомендуется писать: ■■ слитно с предыдущим типом, если типов всего два: //Переменная может принимать значения типа Строка или Неопределено пер Переменная1: Строка? ■■ через символ «|», если типов больше двух: //Переменная может принимать значения типа Строка, Число или Неопределено пер Переменная1: Строка|Число|? 31 «1С:Предприятие.Элемент». Возможности встроенного языка Составной тип также может быть указан в качестве типа параметра метода и типа возвращаемого методом значения. Например: //Объявление метода с параметрами составного типа метод МойМетод1(Парам1: Число|Строка, Парам2: Число?) …… ; //Объявление метода, возвращающего значениие составного типа метод МойМетод2(Парам1: Число, Парам2: Число): Число|Строка пер Результат = Парам1 + Парам2 возврат Результат ; Особенности обращения к членам выражений составного типа В языке «Элемента» существуют некоторые ограничения на обращение к выражениям составного типа, которые нужно учитывать. ■■ У экземпляров составного типа нельзя вызывать методы и обращаться к их свойствам, за исключением случаев, когда в наборе типов содержится тип Неопределено. Например, при компиляции следующего кода будет получена ошибка – «Обращение к членам составных типов недопустимо»: пер Переменная1: Строка|Число = 7 пер ПредставлениеЧисла = Переменная1.ВСтроку() Тогда как следующий код не вызовет ошибки: пер Переменная1: Число? = 7 пер ПредставлениеЧисла = Переменная1.ВСтроку() ■■ Запрещено присвоение переменной составного типа A значения переменной B, если типы A не включают в себя все типы B. Например: пер А: Число|Строка = "тест" пер В: Число|Строка|Булево = "пример" А = В //ошибка - тип Булево не может быть присвоен в Число|Строка Исключением является вариант, когда в составном типе В содержится тип Неопределено. Например, следующий код не вызовет ошибки: пер А: Число|Строка = "тест" пер В: Число|Строка|? = "пример" А=В 32 Глава 2. Типизация данных, переменные, константы. Передача параметров Возможен также следующий вариант: пер А: Число = 33 пер В: Число? = 55 А=В Объявление переменных В языке «1С:Предприятия» переменные можно было объявлять, а можно было не объявлять. Обычно их не объявляли, а использовали неявное объявление переменных в инструкции присваивания. Например: МояПеременная = "Сергей" ; Вместе с этим существовала инструкция явного объявления переменных, например: Перем МояПеременная Экспорт; Она использовалась тогда, когда нужно было сделать переменную доступной из других модулей, например. Теперь в языке «Элемента» все переменные должны быть объявлены явно. Причем из этого объявления должны быть однозначно понятны тип и начальное значение переменной. Модификаторы При объявлении переменной используются три модификатора: ■■ пер – переменная, доступная для записи и для чтения. Например: пер Переменная1: Строка ■■ знч – переменная, доступная только для чтения. Например: знч Исполняемый = Ложь // тип файла ■■ исп – переменная, тип которой является потомком типа Закрываемое. Такая переменная доступна только для чтения. Переменные, объявленные таким образом, обычно хранят значения, удерживающие системные ресурсы (порты, файлы, и т. д.) и контексты. При выходе из области видимости для такой переменной будет автоматически вызван метод Закрыть(). Например: исп ВременныйПотокЗаписи = ВременныйФайл.ОткрытьПотокЗаписи() 33 «1С:Предприятие.Элемент». Возможности встроенного языка Имя переменной После модификатора пишется имя переменной. Имя переменной рекомендуется писать в стиле CamelCase. При этом если имя состоит из одного слова, то оно пишется с прописной буквы, остальные буквы – строчные. Если имя состоит из нескольких слов, то они пишутся слитно без пробелов, при этом каждое слово внутри пишется с прописной буквы. Тип После имени переменной может быть указано описание типа. От имени переменной оно отделяется двоеточием и пробелом. Если тип один, то просто указывается имя типа. Например: пер Переменная1: Число Если тип составной (см. раздел «Составные типы»), то все имена типов указываются друг за другом через символ «|». Например: пер Переменная1: Строка|Число|Булево Если в составном типе есть тип Неопределено, то он обозначается символом «?» и пишется в конце. Причем если типов всего два, то пишется слитно с именем типа, а если типов три и больше, то пишется через «|» от последнего типа. Например: пер Переменная1: Строка? пер Переменная1: Строка|Число|? Начальное значение Начальное значение переменной вычисляется из описания типа. Если тип переменной имеет значение по умолчанию, то переменная будет иметь это значение. Например: пер Переменная1: Число //начальное значение переменной будет равно 0 Если тип – Неопределено или в качестве типа указано ключевое слово неизвестно, то переменная будет иметь значение Неопределено. Если в составном типе есть тип Неопределено, то переменная тоже будет иметь значение Неопределено. 34 Глава 2. Типизация данных, переменные, константы. Передача параметров Инициализатор Если тип переменной не имеет значения по умолчанию или если в составном типе нет типа Неопределено, то в этом случае необходимо указать инициализатор. Инициализатор – это литерал или выражение, которые пишутся после знака равенства. Это то значение, которое будет иметь переменная. Например: пер Переменная1: Строка|Число = "пример" пер Переменная1: Строка|Число = 330 / 5 * 3 Другая цель использования инициализатора – упрощение записи. Если указан инициализатор, то тип переменной можно не указывать. В этом случае тип переменной будет автоматически вычислен из типа инициализатора. Например: пер Переменная1 = 22 //переменная будет иметь тип Число Не следует явно указывать типы переменных, инициализируемых литералами или конструкторами. Например: //Правильно пер Переменная1 = Истина пер МассивЧисел = новый Массив<Число>() //Неправильно пер Переменная1: Булево = Истина пер МассивЧисел: Массив<Число> = новый Массив<Число>() Ограничения Объявление переменной может располагаться в любом месте метода. При этом нужно учитывать следующие ограничения: ■■ Нельзя объявить сразу несколько переменных в одной инструкции. ■■ Переменная не может быть объявлена дважды в одной области видимости. ■■ Имя переменной не может совпадать с именем параметра метода. ■■ Переменная не может быть использована в собственном инициализаторе. ■■ Не поддерживается объявление переменной без указания типа или явного значения инициализации. 35 «1С:Предприятие.Элемент». Возможности встроенного языка Константы В языке «1С:Предприятия» константы создать было нельзя. Они создавались на этапе конфигурирования с определенным именем и типом и были доступны во всем прикладном решении. И затем из встроенного языка можно было получить или изменить значение конкретной константы. Например: // Получить значение константы РасчетЗарплаты РасчетЗП = Константы.РасчетЗарплаты.Получить(); Сообщить(РасчетЗП); //да // Установить значение константы РасчетЗарплаты Константы.РасчетЗарплаты.Установить(Ложь); РасчетЗП = Константы.РасчетЗарплаты.Получить(); Сообщить(РасчетЗП); //нет Имена констант писались в стиле CamelCase, о котором говорилось в предыдущем разделе. Теперь в языке «Элемента» константу можно создать и объявить на уровне отдельного модуля с произвольным именем и проинициализировать значением, которое в дальнейшем нельзя будет изменить. Константа объявляется обычно в начале модуля, вне методов. Описание константы состоит из модификатора конст, имени константы (которое принято писать прописными буквами) и инициализатора. При объявлении константы обязательно должно присутствовать значение инициализации, вычисление которого выполняется во время компиляции модуля. Например: конст ИМЯ_АРХИВА = "myZip.zip" конст ОБЪЕМ = 22 В отличие от имен переменных, имена констант пишутся прописными буквами. Если имя состоит из нескольких слов, то между ними ставится символ «_» (нижнее подчеркивание). 36 Глава 2. Типизация данных, переменные, константы. Передача параметров Методы Типы параметров В языке «1С:Предприятия 8» в объявлениях процедур и функций не нужно было указывать типы формальных параметров и возвращаемых значений. Например: Процедура УзнатьПлощадь(Длина, Ширина) Площадь = Длина * Ширина; КонецПроцедуры Функция УзнатьПлощадь(Длина, Ширина) Возврат Длина * Ширина; КонецФункции Теперь в языке «Элемента» типы параметров и возвращаемых значений нужно указывать обязательно. Например: метод УзнатьПлощадь(Длина: Число, Ширина: Число) пер Площадь = Длина * Ширина ; метод УзнатьПлощадь(Длина: Число, Ширина: Число): Число возврат Длина * Ширина ; Значения по умолчанию В языке «1С:Предприятия 8» для любого формального параметра можно было указать значение по умолчанию. В следующем примере начальные значения указаны для параметров Пар2 и Пар4: Процедура Тест(Пар1, Пар2=5, Пар3, Пар4=8) КонецПроцедуры Таким образом, все фактические параметры делились на две категории: ■■ Обязательные – которым соответствует формальный параметр без значения по умолчанию. ■■ Необязательные – которым соответствует формальный параметр со значением по умолчанию. И обязательные, и необязательные фактические параметры можно было указывать или не указывать. 37 «1С:Предприятие.Элемент». Возможности встроенного языка Если обязательный фактический параметр не был указан, то формальный параметр получал значение Неопределено. В следующем примере при вызове процедуры Тест()опущен второй обязательный фактический параметр. В результате соответствующий ему формальный параметр Пар2 имеет значение Неопределено: Тест(1, ); Процедура Тест(Пар1, Пар2) // Пар2 = Неопределено КонецПроцедуры При этом если не указывался фактический параметр, расположенный в середине списка, то вместо него ставилась запятая. Если такой параметр находился в конце списка, то и запятую можно было не ставить. В следующем примере при вызове процедуры Тест() опущены второй и четвертый необязательные фактические параметры и не указан третий обязательный фактический параметр (вместо него поставлена запятая): Тест(1, , ); Процедура Тест(Пар1, Пар2=5, Пар3, Пар4=8) // Пар1 = 1 // Пар2 = 5 // Пар3 = Неопределено // Пар4 = 8 КонецПроцедуры В языке «Элемента» точно так же можно указать параметру значение по умолчанию. В следующем примере при объявлении процедуры Тест() начальные значения указаны для параметров Пар2 и Пар4: метод Тест(Пар1: Число, Пар2 = 5, Пар3: Число, Пар4 = 8) ; Однако при вызове методов не указывать можно только те необязательные аргументы, которые расположены в конце списка после последнего обязательного. Все остальные аргументы нужно указывать, даже если они необязательные, как второй аргумент в примере. 38 Глава 2. Типизация данных, переменные, константы. Передача параметров // Теперь нет смысла параметр с значением по умолчанию ставить в середине, т. к. все равно // нужно будет указать соответствующие им аргументы Тест(1, 2, 3) метод Тест(Пар1: Число, Пар2 = 5, Пар3: Число, Пар4 = 8) // Пар1 = 1 // Пар2 = 2 // Пар3 = 3 // Пар4 = 8 ; Из этого следует правило, что параметры со значениями по умолчанию имеет смысл размещать только в конце списка. Если вы разместите их в середине списка, вы обязаны будете указать соответствующие им аргументы, тем самым значение по умолчанию использовать не удастся. Это правило справедливо тогда, когда вы используете только позиционные аргументы. Если вы используете именованные аргументы или и те и другие, то параметры со значениями по умолчанию могут иметь любое расположение (подробнее см. раздел «Позиционные и именованные аргументы»). Передача параметров по значению В языке «1С:Предприятия» параметры можно было передавать в методы как по значению, так и по ссылке. Если в описании процедуры или функции перед параметром стояло ключевое слово Знач, то параметр передавался по значению. При этом изменение значения формального параметра внутри процедуры или функции не приводило к изменению значения фактического параметра. Например: Процедура МояПроцедура() Переменная1 = 30; Метод1(Переменная1); // Переменная1 будет равна 30 КонецПроцедуры Процедура Метод1(Знач Перем1) Перем1 = 100; КонецПроцедуры 39 «1С:Предприятие.Элемент». Возможности встроенного языка Если ключевое слово Знач перед параметром не стояло, то параметр передавался по ссылке. При этом изменение значения формального параметра внутри процедуры или функции приводило к изменению значения фактического параметра. Например: Процедура МояПроцедура() Переменная1 = 30; Метод1(Переменная1); // Переменная1 будет равна 100 КонецПроцедуры Процедура Метод1(Перем1) Перем1 = 100; КонецПроцедуры Теперь в языке «Элемента» аргументы можно передавать в методы только по значению. Это значит, что изменение значения параметра при выполнении метода никак не повлияет на аргумент. Например: метод МойМетод() пер Переменная1 = 30 Метод1(Переменная1) // Переменная1 будет равна 30 ; метод Метод1(Перем1: Число) Перем1 = 100 ; В то же время, как и в языке «1С:Предприятия», можно изменять состояние экземпляров, переданных через параметры, с помощью методов этих экземпляров. Например: метод МойМетод() пер Массив1 = <Число>[1] Метод3(Массив1) // В переменной Массив1 будет содержаться два элемента. ; метод Метод3(Парам: Массив<Число>) Парам.Добавить(4) ; 40 Глава 2. Типизация данных, переменные, константы. Передача параметров Позиционные и именованные аргументы В языке «1С:Предприятия» параметры можно было передавать в методы только по порядку их описания в определении этих методов, то есть использовались только позиционные фактические параметры. Например: Процедура МояПроцедура() Переменная = МояФункция(55, "Ок", Ложь); Сообщить(Переменная); //Переменная: 55 КонецПроцедуры Функция МояФункция(Парам1, Парам2, Парам3) Если Парам3 = Истина Тогда Возврат Парам2; Иначе Возврат Парам 1; КонецЕсли; КонецФункции Теперь в языке «Элемента» можно использовать как позиционные аргументы, как и именованные. То есть аргументы можно перечислять не только по порядку следования параметров, но и по имени параметров. Форма записи именованного аргумента состоит из имени аргумента, символа равенства и самого аргумента. Например: Парам3 = Ложь. Причем порядок именованных аргументов не важен. Например: метод МойМетод() // Позиционная форма Результат = Метод5(33, "!!!", Истина) //Опускание последнего параметра Результат = Метод6(44, "+++") ; //Результат: 33 //Результат: 44 // Именованная форма Результат = Метод5(Парам3 = Ложь, Парам1 = 77, Парам2 = "+++") //Результат: "+++" //Опускание последнего параметра Результат = Метод6(Парам2 = "+++", Парам1 = 111) //Результат: 111 метод Метод5(Парам1: Число, Парам2: Строка, Парам3: Булево): Число|Строка если Парам3 возврат Парам1 иначе возврат Парам2 ; 41 «1С:Предприятие.Элемент». Возможности встроенного языка ; метод Метод6(Парам1: Число, Парам2: Строка, Парам3 = Истина): Число|Строка если Парам3 возврат Парам1 иначе возврат Парам2 ; ; Можно смешивать позиционные и именованные аргументы, при этом все именованные аргументы должны идти после позиционных. Например, в следующем примере при вызове метода Метод5() первый аргумент –позиционный, остальные – именованные: метод МойМетод() ; // Смешанная форма Результат = Метод5(55, Парам3 = Истина, Парам2 = "+++") //Результат: 55 метод Метод5(Парам1: Число, Парам2: Строка, Парам3: Булево): Число|Строка если Парам3 возврат Парам1 иначе возврат Парам2 ; ; В языке «1С:Предприятия», если необязательный параметр находился в списке вызова между других обязательных параметров, то пропускать его было нельзя, но можно было не указывать его значение – вместо него ставилась запятая. Например: Процедура МояПроцедура() Переменная = МояФункция(22, , Истина); Сообщить(Переменная); //Переменная: 22 КонецПроцедуры Функция МояФункция(Парам1, Парам2 = 0, Парам3) Если Парам3 = Истина Тогда Возврат Парам1; Иначе Возврат Парам2; КонецЕсли; КонецФункции Теперь в языке «Элемента» пропуск необязательных позиционных аргументов допускается только в том случае, если они идут в конце списка. При использовании именованных аргументов или и тех и других пропускать необязательные аргументы в середине списка 42 Глава 2. Типизация данных, переменные, константы. Передача параметров можно. Если используются и те и другие, то за пропущенными аргументами должны следовать только именованные. Например, в следующем примере при вызове метода Метод7() первый параметр – позиционный, второй опущен, а третий – именованный: метод МойМетод() ; // Смешанная форма Результат = Метод7(77, Парам3 = "???") //Результат: "???" метод Метод7(Парам1: Число, Парам2 = Истина, Парам3: Строка): Число|Строка если Парам2 возврат Парам3 иначе возврат Парам1 ; ; Именованные аргументы могут быть использованы для вызова как собственных методов, так и системных методов, а также конструкторов экземпляров. Кроме того, можно перед описанием метода или конструктора использовать аннотацию @ИменованныеПараметры. Это значит, что запрещается вызывать метод с позиционными аргументами (допускаются только именованные аргументы). Например: метод МойМетод() Тест(Параметр = 123) ; @ИменованныеПараметры метод Тест(Параметр: Число) ; Перегрузка методов В языке «1С:Предприятия» нельзя было объявить процедуру/функцию с тем же именем, которое уже существовало у другой процедуры/ функции, даже если у них было разное количество параметров. Теперь в языке «Элемента» можно повторно определить метод с тем же именем, но с разным составом (типом и/или количеством) параметров. Такие методы называются перегруженными. 43 «1С:Предприятие.Элемент». Возможности встроенного языка При этом нужно учитывать, что любой вызов перегруженного метода должен позволять компилятору однозначно определить, какой вариант метода необходимо использовать в данном случае. Перегруженные методы не могут различаться только типом возвращаемого значения. Они должны различаться также и количеством и/или типом параметров. Например, перегруженный метод (вариант 2) по сравнению с уже существующим (вариант 1) может возвращать значение того же типа Строка, но содержать два параметра вместо одного: метод МойМетод() ; // 1-й вариант Результат = Метод1("Ок") //Результат: "Ок" // 2-й вариант Результат = Метод1(7, "Ок") //Результат: "Ок" // 1-й вариант метод Метод1(Парам1: Строка): Строка возврат Парам1 ; // 2-й вариант метод Метод1(Парам1: Число, Парам2: Строка): Строка возврат Парам2 ; Или же перегруженный метод (вариант 3) может отличаться от существующего (вариант 1) и типом возвращаемого значения (Число вместо Строка), и количеством параметров (два вместо одного): метод МойМетод() ; // 1-й вариант Результат = Метод1("Ок") //Результат: "Ок" // 3-й вариант Результат = Метод1(7, "Ок") //Результат: 7 // 1-й вариант метод Метод1(Парам1: Строка): Строка возврат Парам1 ; // 3-й вариант метод Метод1(Парам1: Число, Парам2: Строка): Число возврат Парам1 ; 44 Глава 2. Типизация данных, переменные, константы. Передача параметров Можно также определить перегруженный метод (вариант 2), который будет отличаться от существующего (вариант 1) не количеством, а только типом параметров (Число вместо Строка): метод МойМетод() // 1-й вариант Метод1("Ок") ; // 2-й вариант Метод1(7) // 1-й вариант метод Метод1(Парам1: Строка) //Парам1 = "Ок" ; // 2-й вариант метод Метод1(Парам1: Число) //Парам1 = 7 ; Если определить используемый вариант метода во время компиляции не представляется возможным, произойдет ошибка компиляции. Например, нельзя создать перегруженный метод, у которого тип одного параметра совпадает с типом параметра исходного метода, а второй параметр имеет значение по умолчанию. При компиляции будет получена ошибка неоднозначности, в этом случае любой из методов можно вызвать, указав только один параметр: //ошибка компиляции – перегрузка метода допускает неоднозначный вызов метод Метод1(Парам1: Строка) метод Метод1(Парам1: Строка, Парам2 = 22) Также нельзя создать перегруженный метод, у которого тип параметра (Строка) является наследником типа параметра исходного метода (Объект): //ошибка компиляции – перегрузка метода допускает неоднозначный вызов метод Метод1(Парам1: Объект) метод Метод1(Парам1: Строка) 45 «1С:Предприятие.Элемент». Возможности встроенного языка Также нельзя создать перегруженный метод, у которого параметр описан с использованием составного типа, при этом в каждом варианте метода в типе параметра присутствует один и тот же тип (Строка): //ошибка компиляции – перегрузка метода допускает неоднозначный вызов метод Метод1(Парам1: Строка|Булево) метод Метод1(Парам1: Строка) или метод Метод1(Парам1: Строка|Булево) метод Метод1(Парам1: Строка|Число) Как уже говорилось, нельзя, чтобы перегруженные методы отличались только типом возвращаемого значения: //ошибка компиляции – перегрузка метода допускает неоднозначный вызов метод Метод1(Парам1: Число): Строка метод Метод1(Парам1: Число): Число Вы можете создать не только перегруженные методы, но и собственные структуры, которые могут иметь несколько конструкторов, различающихся только количеством параметров. Разрешение неоднозначности при использовании именованных аргументов Все вышеописанные способы переопределения методов хорошо работают для позиционных аргументов. Но с именованными аргументами может произойти путаница, в результате будет получена ошибка неоднозначности. Например, метод перегружен следующим образом: // 1-й вариант метод Метод1(Парам1: Строка, Парам2: Число) // 2-й вариант метод Метод1(Парам2: Число, Парам1: Строка) С позиционными аргументами ошибки не возникнет – при вызове будет однозначно выбран первый вариант определения метода Метод1(). метод МойМетод() Метод1("тест", 11) ; 46 Глава 2. Типизация данных, переменные, константы. Передача параметров А с именованными аргументами возникнет ошибка неоднозначности, так как параметры передаются по именам, а не по порядку вызова. В результате для именованных аргументов подходят оба варианта определения метода Метод1(). метод МойМетод() //ошибка компиляции – неоднозначный вызов метода с именованными параметрами Метод1(Парам1 = "тест", Парам2 = 11) ; При этом, если есть несколько перегрузок, подходящих для именованных аргументов, и среди них существует такая, что общее число ее аргументов меньше, чем у всех остальных, – будет выбрана она. Например, в следующем примере для двух именованных аргументов метода Метод2() будет выбран второй вариант определения метода, так как в нем описаны два параметра, а не три, как в первом варианте: метод МойМетод() Метод2(Парам1 = 22, Парам3 = Ложь) ; // 1-й вариант метод Метод2(Парам1: Число, Парам2 = "тест", Парам3 = Истина) // 2-й вариант метод Метод2(Парам1: Число, Парам3: Булево) 47 «1С:Предприятие.Элемент». Возможности встроенного языка 48 ГЛАВА 3 Операции, инструкции, типы 49 «1С:Предприятие.Элемент». Возможности встроенного языка Операции Арифметические операции В языке «Элемента», так же как и в языке «1С:Предприятия», поддерживается стандартный набор арифметических операций: сложение (+), вычитание (-), умножение (*), деление (/), возведение в степень (**), смена знака (унарный минус) и получение остатка от деления (%). В языке «Элемента» операция сложения (+) может выполняться над следующими типами данных: ■■ Строка + Объект? = Строка; ■■ Число + Число = Число; ■■ Длительность + Длительность = Длительность; ■■ ДатаВремя + Длительность = ДатаВремя; ■■ Дата + Длительность = Дата; ■■ Время + Длительность = Время; ■■ Момент + Длительность = Момент. Операция вычитания (-) может выполняться над следующими типами данных: ■■ Число - Число = Число; ■■ Длительность - Длительность = Длительность; ■■ ДатаВремя - Длительность = ДатаВремя; ■■ ДатаВремя - ДатаВремя = Длительность; ■■ Дата - Длительность = Дата; ■■ Дата - Дата = Длительность; ■■ Время - Длительность = Время; ■■ Время - Время = Длительность; ■■ Момент - Длительность = Момент; ■■ Момент - Момент = Длительность. Операция умножения (*) может выполняться над следующими типами данных: ■■ Число * Число = Число; ■■ Длительность * Число = Длительность. 50 Глава 3. Операции, инструкции, типы Операция деления (/) может выполняться над следующими типами данных: ■■ Число / Число = Число; ■■ Длительность / Число = Длительность. Операция получения остатка от деления (%) может выполняться над следующими типами данных: ■■ Число % Число = Число. Операция возведения в степень (**) может выполняться над следующими типами данных: ■■ Число ** Число = Число. Операция смены знака (унарный минус) может выполняться над следующими типами данных: ■■ - Число; ■■ - Длительность. Кроме этого, язык «Элемента» позволяет использовать инструкции присваивания, совмещенные с арифметическими операциями. Например, если требуется увеличить левое значение на какое-то значение, то сделать это можно или с помощью выражения: <значение> = <значение> + <Выражение> или с помощью выражения: <значение> += <Выражение> В языке «Элемента» допустимы следующие операции: +=, -=, *=, /=. Увеличение значения переменной выглядит следующим образом: // Язык "1С:Предприятия" Счетчик = 2; Счетчик = Счетчик + 1; //Счетчик = 3 // Язык "Элемента" пер Счетчик = 2 Счетчик += 1 //Счетчик = 3 51 «1С:Предприятие.Элемент». Возможности встроенного языка Уменьшение значения переменной выглядит следующим образом: // Язык "1С:Предприятия" Счетчик = 5; Счетчик = Счетчик - 2; //Счетчик = 3 // Язык "Элемента" пер Счетчик = 5 Счетчик -= 2 //Счетчик = 3 Умножение значения переменной выглядит следующим образом: // Язык "1С:Предприятия" Счетчик = 5; Счетчик = Счетчик * 3; //Счетчик = 15 // Язык "Элемента" пер Счетчик = 5 Счетчик *= 3 //Счетчик = 15 Деление значения переменной выглядит следующим образом: // Язык "1С:Предприятия" Счетчик =20; Счетчик = Счетчик / 4; //Счетчик = 5 // Язык "Элемента" пер Счетчик = 20 Счетчик /= 4 //Счетчик = 5 Логические операции В языке «1С:Предприятия» операция сравнения на равенство значений обозначалась знаком одинарного равенства (=). Например: Переменная1 = 8; Если Переменная1 = 20 Тогда ….. КонецЕсли; Теперь в языке «Элемента» операция сравнения на равенство значений обозначается знаком двойного равенства (==). Например: пер Переменная1 = 8 если Переменная1 == 20 ….. ; 52 Глава 3. Операции, инструкции, типы В языке «1С:Предприятия» операция сравнения на неравенство значений обозначалась знаком двойного неравенства (<>). Например: Переменная1 = 8; Если Переменная1 <> 20 Тогда ….. КонецЕсли; Теперь в языке «Элемента» операция сравнения на неравенство значений обозначается знаком «!=». Например: пер Переменная1 = 8 если Переменная1 != 20 ….. ; Следует учитывать, что в языке «Элемента» операции сравнения на равенство (==) / неравенство (!=) значений возможны между любыми типами данных. А операции на больше/меньше (<, <=, >, >=) возможны только для одинаковых типов, являющихся потомками типа Сравнимое. Тернарная операция «?» В языке «1С:Предприятия» существовала возможность вычислить выражение по условию с помощью операции «?». Например: Переменная1 = 8; Переменная2 = ?(Переменная1 > 10, "много", "мало" ); //Переменная2 = "мало" Теперь в языке «Элемента» для этого существует аналогичная ей по сути тернарная операция «?». Тернарная операция «?» используется тогда, когда нужно сделать бинарный выбор: или одно значение (или выражение), или другое. Она возвращает один из своих операндов (второй или третий) в зависимости от значения логического выражения, заданного первым операндом. Сначала вычисляется условие, заданное в логическом выражении. Если условие истинно, то операция возвращает результат вычисления выражения, заданного вторым операндом. Если условие ложно, то операция возвращает результат вычисления выражения, заданного третьим операндом. Например: пер Переменная1 = 8 пер Переменная2 = Переменная1 > 10 ? "много" : "мало" //Переменная2 = "мало" 53 «1С:Предприятие.Элемент». Возможности встроенного языка Операция «это» В языке «1С:Предприятия» для определения принадлежности типов значения какому-то типу сначала с помощью функции ТипЗнч() получался тип значения и проверялся на равенство/неравенство с идентификатором типа, возвращаемым функцией Тип(). Например: Значение = 56; Если ТипЗнч(Значение) <> Тип("Строка") Тогда Сообщить("Это не строка") КонецЕсли; Значение = "тест"; Если ТипЗнч(Значение) = Тип("Строка") Тогда Сообщить("Это строка") КонецЕсли; Теперь в языке «Элемента» это делается с помощью операции это, которая проверяет, что список типов выражения является присваиваемым в список типов, перечисленных в правой части операции. В результате возвращается Истина или Ложь. Например: пер Значение: Число|Строка = 56 если Значение это не Строка Сообщить("Это не строка") ; Значение = "тест" если Значение это Строка Сообщить("Это строка") ; Если типов в проверяемом списке несколько, они перечисляются через символ «|». Например: пер Значение = 121 если Значение это Строка|Число|Булево Сообщить("Это базовый тип") иначе Сообщить("Это не базовый тип") ; При этом вместо отрицания результата проверки рекомендуется использовать более понятную операцию проверки с отрицанием. Например: если Значение это не Строка А не: если не (Значение это Строка) 54 Глава 3. Операции, инструкции, типы Операция «как» В языке «1С:Предприятия» составной тип значения одного реквизита (который задавался на этапе конфигурирования) можно было привести к одному или нескольким возможным типам с помощью метода ПривестиЗначение() объекта ОписаниеТипов. Например: ОписаниеТипа = Новый ОписаниеТипов("СправочникСсылка.Сотрудники"); Объект.Реквизит2 = ОписаниеТипа.ПривестиЗначение(Объект.Реквизит1); Теперь в языке «Элемента» это делается с помощью операции как, которая приводит тип значения выражения слева к типу, указанному справа. Тип, к которому приводится выражение, должен быть одним из возможных типов для результата вычисления выражения. Например, при выполнении следующего кода в 3-й и 4-й строке будет получена ошибка компиляции, потому что тип ДатаВремя отсутствует в составе типов переменной Переменная: пер Переменная: Строка|Число|Булево = 123 пер Переменная1 = (Переменная как Строка|Число) пер Переменная2 = (Переменная как ДатаВремя) пер Переменная3 = (Переменная как Строка|ДатаВремя) пер Переменная4 = (Переменная как Число) //ошибка компиляции //ошибка компиляции С помощью операции как нельзя выполнить преобразование типов, то есть нельзя преобразовать значение типа Число в значение типа Строка. Используйте операцию как в тех случаях, когда значение выражения, тип которого нужно привести, имеет составной тип, а нужно, чтобы оно было одного конкретного типа. Например, чтобы получить длину строки переменной составного типа (Строка или Число), она приводится к типу Строка, заключается в скобки, и от нее через точку вызывается метод Длина() этого типа: пер Переменная1: Строка|Число = "тест" пер ДлинаСтроки = (Переменная1 как Строка).Длина() Если вы не приведете переменную к одному из ее возможных типов, то получите ошибку компиляции, так как нельзя вызывать методы и свойства у экземпляров составных типов. 55 «1С:Предприятие.Элемент». Возможности встроенного языка Операции для работы со значением «Неопределено» В языке «1С:Предприятия» не было специальных операций для работы со значением Неопределено. Теперь в языке «Элемента» существуют операции, облегчающие работу с Неопределено. Это настойчивая операция, операция безопасного доступа и операция умолчания, о которых будет рассказано ниже. Настойчивая операция Если вы уверены, что выражение в момент выполнения программы не может иметь значение Неопределено, то после этого выражения можно поставить символ «!» (восклицательный знак). Смысл этой операции заключается только в том, чтобы убрать из описания типа тип Неопределено, если известно, что его там точно быть не может. Проиллюстрировать это можно на примере структур (подробнее о структурах рассказывается в разделе «Собственные типы – Структура»). Допустим, есть две структуры: Сотрудник и ПочтовыйАдрес. структура Сотрудник пер ФИО: Строка пер Адрес: ПочтовыйАдрес? пер Телефон: Строка? конструктор (ФИО) конструктор (ФИО, Адрес) ; структура ПочтовыйАдрес пер Страна: Строка? пер Город: Строка пер Улица: Строка? пер Дом: Строка? конструктор (Город) ; Структура Сотрудник имеет поля ФИО, Адрес и Телефон. В поле Адрес содержится, в свою очередь, экземпляр другой структуры – ПочтовыйАдрес. Она имеет поля Страна, Город, Улица и Дом. 56 Глава 3. Операции, инструкции, типы Сотрудник имеет два конструктора: можно указать только ФИО или ФИО и Адрес. ПочтовыйАдрес имеет конструктор, в котором можно указать только Город. Например, в программном коде создается экземпляр сотрудника, и точно известно, что у него есть адрес. Если просто присвоить этот адрес переменной АдресСотрудника, то она будет иметь составной тип ПочтовыйАдрес? (рис. 3.1). пер Стажер = новый Сотрудник("Иванов", новый ПочтовыйАдрес("Владимир")) пер АдресСотрудника = Стажер.Адрес Рис. 3.1. Тип переменной «АдресСотрудника» Но если точно известно, что в данном случае в переменной АдресСотрудника не может быть значения Неопределено, то можно использовать эту операцию, чтобы убрать тип Неопределено из описания типов. пер Стажер = новый Сотрудник("Иванов", новый ПочтовыйАдрес("Владимир")) пер АдресСотрудника = Стажер.Адрес! Переменная АдресСотрудника будет иметь тип ПочтовыйАдрес (рис. 3.2). Рис. 3.2. Тип переменной «АдресСотрудника» Операция «Безопасный доступ» Эту операцию можно проиллюстрировать на примере тех же структур Сотрудник и ПочтовыйАдрес, которые были рассмотрены выше. Например, заранее неизвестно, заполнен ли адрес у сотрудника. Если в такой ситуации не предпринять никаких действий, то следующий код приведет к ошибке во время работы приложения (рис. 3.3): пер Менеджер = новый Сотрудник("Иванов") пер СтранаСотрудника = Менеджер.Адрес.Страна 57 «1С:Предприятие.Элемент». Возможности встроенного языка Рис. 3.3. Ошибка времени выполнения В переменной Адрес находится Неопределено, и «Элемент» не может найти у него свойство Страна. Чтобы этого не случилось, можно использовать операцию безопасного доступа, с помощью которой выполняется доступ через точку (или вызов метода), только если источник вызова не Неопределено, иначе результат всей цепочки становится Неопределено. Для осуществления безопасного доступа после источника вызова ставится символ «?.». пер Менеджер = новый Сотрудник("Иванов") пер СтранаСотрудника = Менеджер.Адрес?.Страна Тогда, если адрес не указан, ошибки не возникнет, а все выражение будет иметь значение Неопределено, которое можно обработать в алгоритме. Например, оповестить ответственного о том, что необходимо заполнить адрес сотрудника (рис. 3.4). Рис. 3.4. Операция безопасного доступа Операция «Умолчание» Эта операция возвращает значение правого выражения, если значение левого выражения Неопределено. Эту операцию можно проиллюстрировать на предыдущем примере. Например, если адрес не задан, не нужно никого оповещать, а нужно просто написать, что данных нет (рис. 3.5). 58 Глава 3. Операции, инструкции, типы Рис. 3.5. Операция умолчания Инструкции «если» В языке «1С:Предприятия» для выполнения различных фрагментов кода в зависимости от выполнения условия использовалась инструкция Если … ИначеЕсли …Иначе … КонецЕсли. В ветке условия Иначе располагался код, который выполнялся в том случае, если условие ложно. В этой ветке могло проверяться другое условие, при этом ключевое слово ИначеЕсли писалось слитно. Например: Если Перем1 > 5 Тогда Перем2 = "пять"; ИначеЕсли Перем2 = "" Тогда Перем1 = 0; Иначе Перем1 = 5; Перем2 = "пять"; КонецЕсли; Теперь в языке «Элемента» в блоке условной инструкции если … иначе если … иначе … ; ключевые слова иначе если пишутся раздельно и не пишется ключевое слово тогда. Например: если Перем1 > 5 Перем2 = "пять" иначе если Перем2 == "" Перем1 = 0 иначе Перем1 = 5 Перем2 = "пять" ; «выбор» В языке «1С:Предприятия» не было условной инструкции выбора, какой фрагмент кода исполнять в зависимости от выполнения условия, кроме вышеописанной инструкции Если. 59 «1С:Предприятие.Элемент». Возможности встроенного языка Например: Переменная1 = 8; Если Переменная1 = 1 Тогда Сообщить("1"); ИначеЕсли Переменная1 = 2 ИЛИ Переменная1 = 3 Тогда Сообщить("2 или 3"); ИначеЕсли Переменная1 > 4 Тогда Сообщить("больше 4"); Иначе Сообщить("все остальное: " + Переменная1); КонецЕсли; Теперь в языке «Элемента» для этого существует специальная инструкция выбор, которая является аналогом инструкции switch из других языков программирования. Например, показанный выше фрагмент с помощью этой инструкции можно переписать следующим образом: пер Переменная1 = 8 выбор Переменная1 когда 1 Сообщить("1") когда 2, 3 Сообщить("2 или 3") когда > 4 Сообщить("больше 4") иначе Сообщить("все остальное: " + Переменная1) ; В кратком виде написания инструкции выбор допускается также выбор из значений перечисления без упоминания имени самого перечисления (имени типа). Например: перечисление ОперационныеСистемы Linux, macOS, Windows умолчание ; метод МойМетод() пер ИспользуемаяОС: ОперационныеСистемы ; 60 выбор ИспользуемаяОС когда Windows // делаем что-то в случае Windows когда Linux, macOS // делаем что-то, если macOS или Linux ; Глава 3. Операции, инструкции, типы Стандартные типы В языке «1С:Предприятия» значения примитивных типов (Число, Строка, Булево) были простыми значениями. Теперь в языке «Элемента» это экземпляры со своими конструкторами, свойствами и методами. Строка Экранирование символов В языке «1С:Предприятия» для включения в строку символа " (кавычка) необходимо было записать две кавычки подряд. Например: Фраза = "Язык ""Элемента"""; // В переменной Фраза будет значение "Язык "Элемента"" Теперь в языке «Элемента», чтобы экранировать некоторые специальные символы, используется обратный слеш (\). С помощью обратного слеша экранируются следующие символы: ■■ обратный слеш (\\), ■■ двойные кавычки (\"), ■■ символ процента (\%), ■■ символ доллара (\$). пер Фраза = "Язык \"Элемента\"" пер РабочийКаталог = "C:\\test\\" пер Ответ = "20\%" пер Цена = "55\$" // В переменной Фраза будет значение "Язык "Элемента"" // В переменной РабочийКаталог будет значение "C:\test\" // В переменной Ответ будет значение "20%" // В переменной Цена будет значение "55$" Кроме того, в строковых литералах с помощью обратного слеша задаются следующие управляющие последовательности: ■■ \н – новая строка, ■■ \в – возврат каретки, ■■ \т – табуляция. Например: Рис. 3.6. Управляющие символы в строковых литералах 61 «1С:Предприятие.Элемент». Возможности встроенного языка Интерполяция строк В языке «1С:Предприятия» интерполяция строк не поддерживалась. Вместо этого использовалась конкатенация строк. Например: Ответ1 = "Площадь"; Ответ2 = Строка(100*20); сообщить(Ответ1 + " = " + Ответ2 + " кв.м."); //результат: "Площадь = 2000 кв.м." Теперь в языке «Элемента» существует возможность интерполяции строк, которая позволяет встроить в строковые константы значение переменной или выражение. Например: пер Ответ1 = "Площадь" пер Ответ2 = 100*20 Сообщить("%Ответ1 = %Ответ2 кв.м") //результат: "Площадь = 2000 кв.м." Другими словами – это более понятный и удобный синтаксис для конкатенации строк, совмещенный с возможностями форматирования значений. При интерполяции выражений вы можете использовать краткий вариант синтаксиса, когда после символа «%» указывается имя переменной (как в предыдущем примере). В этом случае для преобразования значения неявно используется метод ВСтроку(). Или же при интерполяции выражений можно использовать полный вариант, когда после символа «%» в фигурных скобках ({}) указывается более сложное выражение. Например: Сообщить("Площадь = %{100*20} кв.м.") //результат: "Площадь = 2000 кв.м." Кроме того, допускается использование форматной строки в том случае, если результат вычисления выражения имеет тип, одним из предков которого является тип Форматируемое. Форматная строка отделяется от выражения символом «|». Перед выражением ставится символ «$». В этом случае для преобразования значения неявно используется метод Представление(). Например: Сообщить("Сейчас ${Время.Сейчас()|ЧЧ:мм}") //результат: "Сейчас 17:10" ПОДРОБНЕЕ Подробнее про форматирование значений типа Число и ДатаВремя будет рассказано в разделах «Число – Форматирование» и «ДатаВремя – Форматирование». 62 Глава 3. Операции, инструкции, типы Чтобы записать такое выражение в языке «1С:Предприятия», нужно было использовать конкатенацию строк и форматирование с помощью функции Формат(). Например: Сообщить("Сейчас " + Формат(ТекущаяДата(), "ДФ=ЧЧ:мм")); //результат: "Сейчас 17:10" Многострочные литералы В языке «1С:Предприятия» для написания многострочного литерала использовался символ переноса строк (вертикальная черта «|»), который писался в начале каждой подстроки. Например: СтрокаXml = "<note> | <heading>Описание объектной модели</heading> | <body>В основании всей иерархии типов лежит тип Объект.</body> |</note>"; Теперь в языке «Элемента» многострочные литералы полностью сохраняют форматирование по открывающей кавычке, и нет необходимости писать символ переноса строк. Например: знч СтрокаXml = "<note> <heading>Описание объектной модели</heading> <body>В основании всей иерархии типов лежит тип Объект.</body> </note>" При этом, в отличие от языка «1С:Предприятия», открывающая кавычка в многострочном литерале обязательно должна находиться на новой строке. Методы В языке «1С:Предприятия» значения типа Строка не имели методов, для работы с ними использовались функции глобального контекста. Например, чтобы заменить символы в переменной ПутьКФайлу типа Строка, в языке «1С:Предприятия» вызывалась функция глобального контекста СтрЗаменить(): ПутьКФайлу = СтрЗаменить(ПутьКФайлу, "\\", "/"); В языке «Элемента» у переменной ПутьКФайлу для этого вызывается метод Заменить(), который доступен у всех экземпляров типа Строка: ПутьКФайлу = ПутьКФайлу.Заменить("\\", "/") 63 «1С:Предприятие.Элемент». Возможности встроенного языка В языке «1С:Предприятия» нумерация символов в строке начиналась с единицы. Для получения конкретного символа в строке использовалась функция Сред(). Например: МояСтрока = "Моя строка текста"; ТретийСимвол = Сред(МояСтрока, 3,1); Теперь в языке «Элемента» строку можно представить в виде массива символов. Индексация символов начинается с нуля. Для получения конкретного символа в строке можно использовать доступ к элементам строки по индексу с помощью квадратных скобок []. Например: пер МояСтрока = "Моя строка текста" пер ТретийСимвол = МояСтрока[2] Чтобы вычленить из строки фрагменты, разделенные символом разделителя, использовались функции СтрНайти(), Лев(), Сред() и СтрДлина(). Например: Строки = "первый;второй"; Разделитель = СтрНайти(Строки, ";"); Первый = Лев(Строки, Разделитель - 1); Второй = Сред(Строки, Разделитель + 1, СтрДлина(Строки) - Разделитель); Теперь в языке «Элемента» у экземпляра типа Строка для этого вызываются методы Найти(), Подстрока() и ПодстрокаСначала(). Например: пер Строки = "первый;второй" пер Разделитель = Строки.Найти(";") пер Первый = Строки.ПодстрокаСНачала(Разделитель) пер Второй = Строки.Подстрока(Разделитель + 1) Все методы экземпляров типа Строка приводятся в документации. ПОДРОБНЕЕ Документация: https://1cmycloud.com/console/help/executor/2.0/docs/script/topics/script00014.html Синтакс-помощник: https://1cmycloud.com/console/help/executor/2.0/api/executor/ru/Std/String_ru.html 64 Глава 3. Операции, инструкции, типы Число Литералы В языке «1С:Предприятия» значение типа Число могло быть задано только десятичным литералом. В качестве разделителя целой и дробной части использовалась точка. Например: пер Объем = 100.27 пер Коэффициент = -3 Теперь в языке «Элемента» экземпляр типа Число может быть задан не только десятичным, но и двоичным или шестнадцатеричным литералом. Например, число, заданное шестнадцатеричным литералом, имеет вид: знч Цвет = 0xFF0000 Число, заданное двоичным литералом, имеет вид: знч Маска = 0b11111100100 Двоичные и шестнадцатеричные числа могут быть только целыми. Форматирование В языке «1С:Предприятия» значение типа Число можно было отформатировать с помощью функции Формат(). В форматной строке в кавычках указывались имена параметров форматирования, знак равенства и значение параметров форматирования, разделенные символом двоеточия. Например, чтобы вывести число 9.49 с длиной целой части – 2 знака (ЧЦ=2), длиной дробной части – 1 знак (ЧДЦ=1) и округлением в большую сторону (т. е. получить 9,5), нужно написать следующую форматную строку: Сообщить(Формат(9.49,"ЧЦ=2 ; ЧДЦ=1")); //результат: 9,5 Теперь в языке «Элемента», чтобы отформатировать число, нужно либо указать форматную строку в качестве аргумента метода Представление(), либо указать ее в выражении интерполяции после выражения, которое нужно отформатировать, через «|». А перед этим выражением указать символ «$». 65 «1С:Предприятие.Элемент». Возможности встроенного языка Например: пер Переменная = 123.456 //1-й вариант Сообщить(Переменная.Представление("’6.2")) //2-й вариант Сообщить("${100/3|7.2}") //результат: "123,46" //результат: " 33,33" Сама форматная строка состоит из 3 частей, следующих друг за другом непрерывно (без каких-либо символов разделителей): ■■ префикс; ■■ обязательная непустая из четырех подчастей: форматирующая часть, состоящая ○○ флаги, ○○ ширина, ○○ точность, ○○ специальные флаги; ■■ суффикс. Вся форматная строка выделяется двойными кавычками. Префикс и суффикс указываются в отдельных одинарных кавычках. Префикс и суффикс являются необязательными частями форматной строки (могут не указываться). Префикс – это непосредственно текст (какой-либо набор символов), который должен быть вставлен перед отформатированным числом. При использовании символа «'» (одинарная кавычка) в префиксе его необходимо экранировать: «''» (две подряд идущие одинарные кавычки). Например: пер Переменная = 123.456 Сообщить(Переменная.Представление("’Значение=’10")) Сообщить(Переменная.Представление("’’’руб’’=’7")) //результат: "Значение= 123,456" //результат: "‘руб’=123,456" Флаги позволяют управлять форматом строки с обрабатываемым числом. Флаги влияют на свободное место (количество символов, которого не хватает в отформатированном числе до указанной ширины) слева или справа от числа, знак, выводимый перед числом, и т. п.: ■■ "0" – свободное место будет заполнено нулями слева (не совместим с флагом "-"); ■■ "-" – свободное место будет заполнено пробелами справа (не совместим с флагом "0"); 66 Глава 3. Операции, инструкции, типы ■■ "+" – положительные числа выводятся со знаком "+"; ■■ "_" – группировка целой части по 3 цифры, начиная с младшего разряда (по умолчанию разделителем групп является символ неразрывного пробела " "); ■■ "(" – отрицательные числовые значения заключаются в скобки и берутся по модулю (пишутся без знака -). Если необходимо указать несколько флагов, они указываются в форматной строке в любом порядке друг за другом без разделительных символов. Флаги могут не указываться в форматной строке. Например: пер Переменная = 123456 Сообщить(Переменная.Представление("+­_")) //результат: "+123 456" Ширина форматной строки контролирует общую итоговую ширину вывода форматируемого числа (в данном значении не учитывается текст, идущий на префиксе и суффиксе, – он отдельно приписывается до и после строки, содержащей отформатированное число, соответственно). Ширина включает разделитель дробной и целой части. Если указанной ширины не хватает для вывода числа с соблюдением всех флагов, а также специальных флагов или ширина вообще не указана, то она динамически расширяется до минимально необходимой для вывода отформатированного числа. Если же ширина больше необходимой для вывода отформатированного числа, то свободное место заполняется в соответствии с указанными флагами. По умолчанию свободное место заполняется пробелами слева. Например: пер Переменная = 123456 Сообщить(Переменная.Представление("10")) //результат: " 123456" (перед числом 4 пробела) Сообщить(Переменная.Представление("1")) //результат: "123456" (перед числом нет пробелов) Сообщить(Переменная.Представление("_")) //результат: "123 456" Точность – это часть форматной строки, которая выводится через точку от ширины. Она задает, сколько цифр должно выводиться в дробной части числа. Если указанное количество цифр меньше, чем в исходном числе, то значение округляется (по умолчанию 1.5→2). Режим округления задается при помощи соответствующего специального флага (ОК). Если указанное количество цифр больше, дробная часть дополняется нулями с конца. 67 «1С:Предприятие.Элемент». Возможности встроенного языка Например: пер Переменная = 12.36 Сообщить(Переменная.Представление("4.1")) //результат: "12.4" Сообщить(Переменная.Представление("4.4")) //результат: "12.3600" Если данный параметр не указывается, то выводится столько знаков после запятой, сколько было в исходном числе. Специальные флаги влияют на режим округления форматируемого числа, разделитель дробной и целой части и т. п. Как и обычные флаги, они могут указываться в произвольном порядке, но обязательно должны отделяться друг от друга (а также от предыдущей части форматной строки) символом «;» (точка с запятой). Имена специальных флагов можно отделять пробелом от разделителей («;») и знака равенства, а значения этих флагов – нет. То есть подряд последовательно должны идти знак присваивания (=), значение специального флага и знак-разделитель (;). Специальные флаги могут иметь вид: ■■ "РГ=X" – Ввод знака-разделителя групп в целой части (вместо X ожидается какой-либо символ (либо код символа в формате \uкод)). Данный специальный флаг ожидается только вместе с флагом "_", включающим разделение по группам. ■■ "РД=X" – Ввод знака-разделителя между целой и дробной частью (вместо X ожидается какой-либо символ (либо код символа в формате \uкод)). ■■ "ОК=РЕЖИМ" – Флаг-режим округления. Если флаг не указан, по умолчанию округление имеет значение ПоловинаВверх. Имеет 4 режима, которые совпадают с режимами перечисления ВидОкругления: ○○ "ОК=ВН" – округление вниз (1.9->1); ○○ "ОК=ВВ" – округление вверх (1.1->2); ○○ "ОК=ПВН" – округление половина – вниз (1.5->1); ○○ "ОК=ПВВ" – округление половина – вверх (1.5->2). Специальные флаги могут не указываться в форматной строке. 68 Глава 3. Операции, инструкции, типы Например: пер Переменная = 123.57 Сообщить(Переменная.Представление("-10.1; РД =.; ОК =ВН;")) Сообщить(Переменная.Представление("-10.1; РД =.; ОК =ВВ;")) Сообщить(Переменная.Представление("-10.1; РД =.;")) //результат: "123.5 //результат: "123.6 //результат: "123.6 " " " Суффикс – это отдельная часть форматной строки, добавляемая в итоговой отформатированной строке после отформатированного числа. При использовании символа «'» (одинарная кавычка) в суффиксе его необходимо экранировать: «''» (две подряд идущие одинарные кавычки). Например: Сообщить(Переменная.Представление("-10.2’$’")) Сообщить(Переменная.Представление("-10.2’$’’’")) //результат: "123,12 $" //результат: "123,12 $’" Для упрощения работы с форматными строками существуют также именованные стандартные форматы, которые заменяют часть с описанием форматирования числа и упрощают написание форматных строк. Существуют следующие именованные форматы: ■■ "Деньги" Например: пер Переменная = 123.525 Сообщить(Переменная.Представление("Деньги’ руб’")) //результат: "123,53 руб" ■■ "Процент" Например: пер Переменная = 0.52567 Сообщить(Переменная.Представление("Процент")) //результат: "52,57%" ■■ "ОснованиеХХ" Например: пер Переменная = 10 Сообщить(Переменная.Представление("Основание16")) //результат: "а" Основание переводит число из десятеричной системы счисления в другую. Например, символ перевода строки в таблице ASCII имеет десятичный код 10, а шестнадцатеричный код A. Если в переменной есть десятеричный код этого символа, можно сразу получить его шестнадцатеричный код. 69 «1С:Предприятие.Элемент». Возможности встроенного языка Методы В языке «1С:Предприятия» для работы со значениями типа Число использовались функции глобального контекста. Например, чтобы найти целую часть от числа, использовалась функция Цел(): Длина = 12345; Километров = Цел(Длина / 1000); Метров = Длина % 1000; Теперь в языке «Элемента» у экземпляра типа Число для этого вызывается метод ЦелаяЧасть(). Например: знч Длина = 12345 пер Километров = (Длина / 1000).ЦелаяЧасть() пер Метров = Длина % 1000 Все методы экземпляров типа Число приводятся в документации. ПОДРОБНЕЕ Документация: https://1cmycloud.com/console/help/executor/2.0/docs/script/topics/script00012.html Синтакс-помощник: https://1cmycloud.com/console/help/executor/2.0/api/executor/ru/Std/Number_ru.html ДатаВремя В языке «1С:Предприятия» для работы с датой и временем использовалось значение типа Дата. Теперь в языке «Элемента» существует тип ДатаВремя. Экземпляры этого типа позволяют работать с локальными датой и временем одновременно с помощью своих свойств и методов. В отличие от языка «1С:Предприятия» объекты этого типа содержат время с точностью до миллисекунд. Литералы В языке «1С:Предприятия» значение типа Дата можно было задать с помощью литерала вида: 'ГГГГММДДччммсс' (строки цифр, заключенной в одинарные кавычки). 70 Глава 3. Операции, инструкции, типы Например: МояДата = ‘20220617201030’; //результат: 17.06.2022 20:10:30 Теперь в языке «Элемента» экземпляр типа ДатаВремя можно создать с помощью литерала вида: ДатаВремя{гггг-ММ-ддTЧЧ:мм(:сс(.ССС)}. Например: пер МояДатаВремя = ДатаВремя{2022-06-17T15:25:55.777} //результат: 2022-06-17T15:25:55.777 Конструкторы В языке «1С:Предприятия» конструкторов объектов типа Дата не было, но можно было получить значение этого типа с помощью функции Дата(), в которую передавались либо строка вида "ГГГГММДДччммсс" (в двойных кавычках), либо отдельные составляющие даты и времени в качестве параметров. Например: МояДата = Дата("20220617201030"); МояДата = Дата(2022, 06, 17, 20, 10, 30); //результат: 17.06.2022 20:10:30 //результат: 17.06.2022 20:10:30 Теперь у типа ДатаВремя существуют четыре конструктора новый ДатаВремя(), в которые можно передавать следующие аргументы: ■■ Строку вида: гггг-ММ-ддTЧЧ:мм(:сс(.ССС)); ■■ дату и время; ■■ год, месяц и день; ■■ год, месяц, день, час, минуту, секунду и миллисекунду. Например: пер МояДатаВремя = новый ДатаВремя("2022-06-17 15:25:55.001") пер МояДатаВремя = новый ДатаВремя(2022, 06, 17, 15, 25, 55, 002) пер МояДатаВремя = новый ДатаВремя(2022, 06, 17) пер МояДатаВремя = новый ДатаВремя(Дата{2022-06-17}, Время{15:25:55.003}) Форматирование В языке «1С:Предприятия» значение типа Дата можно было отформатировать с помощью функции Формат(). В форматной строке в кавычках указывались имена параметров форматирования, знак равенства и значение параметров форматирования, разделенные символом двоеточия. Например, чтобы вывести локальную дату 71 «1С:Предприятие.Элемент». Возможности встроенного языка с указанием даты и времени, нужно написать следующую форматную строку: Сообщить(Формат(‘20220521201545’, "ДЛФ=ДВ")); //результат: 21.05.2022 20:15:45 Теперь в языке «Элемента», чтобы отформатировать значение типа ДатаВремя, нужно либо указать форматную строку в качестве аргумента метода Представление(), либо указать ее в выражении интерполяции после выражения, которое нужно отформатировать, через «|». А перед этим выражением указать символ «$». Например: пер МояДатаВремя = ДатаВремя{2022-06-17T15:25:55.777} //1-й вариант Сообщить(МояДатаВремя.Представление("дд.ММ.гг ЧЧ:мм:сс")) //результат:17.06.22 15:25:55 //2-й вариант Сообщить("${МояДатаВремя|дд.ММ.гггг’, сегодня - ‘дддд}") //результат: 17.06.2022, сегодня - пятница Форматная строка представляет собой строку из следующих элементов: ■■ г – краткий номер года без лидирующего нуля; ■■ гг – краткий номер года с лидирующим нулем; ■■ гггг – полный номер года; ■■ К – порядковый номер квартала в году; ■■ М – номер месяца в диапазоне от 1 до 12; ■■ ММ – номер месяца в диапазоне от 01 до 12 (с лидирующим нулем); ■■ МММ – краткое название месяца, например «янв.» вместо «январь»; ■■ ММММ – полное название месяца; ■■ д – день месяца (цифрами) без лидирующего нуля; ■■ дд – день месяца (цифрами) с лидирующим нулем; ■■ ддд – краткое название дня недели; ■■ дддд – полное название дня недели; ■■ Д – порядковый номер дня в году; ■■ ч – час в 12-часовом варианте без лидирующих нулей; ■■ чч – час в 12-часовом варианте с лидирующим нулем; ■■ Ч – час в 24-часовом варианте без лидирующих нулей; ■■ ЧЧ – час в 24-часовом варианте с лидирующим нулем; ■■ м – минута без лидирующего нуля; 72 Глава 3. Операции, инструкции, типы ■■ мм – минута с лидирующим нулем; ■■ с – секунда без лидирующего нуля; ■■ сс – секунда с лидирующим нулем; ■■ С – миллисекунда с точностью до сотен; ■■ СС – миллисекунда с точностью до десятков; ■■ ССС – миллисекунда с точностью до единиц. Для экранирования символов в форматной строке (чтобы текст выводился как есть) используется символ «'» (одинарная кавычка). Методы В языке «1С:Предприятия» для работы со значениями типа ДатаВремя использовались функции глобального контекста. Например, чтобы найти начало второго дня месяца, использовались функции НачалоМесяца() и КонецДня(): Дата1 = ‘202005291653’; НачалоМесяца = НачалоМесяца(Дата1); НачалоЗавтра = КонецДня(НачалоМесяца) + 1; //результат: 02.05.2020 0:00:00 Теперь в языке «Элемента» у экземпляра типа ДатаВремя для этого вызываются методы НачалоМесяца(), НачалоДня() и ДобавитьДни(). Например: пер Дата1 = ДатаВремя{2020-05-29 16:53} пер НачалоМесяца = Дата1.НачалоМесяца() пер НачалоЗавтра = НачалоМесяца.НачалоДня().ДобавитьДни(1) //результат: 2020-05-02T00:00:00.000 Все методы экземпляров типа ДатаВремя приводятся в документации. ПОДРОБНЕЕ Документация: https://1cmycloud.com/console/help/executor/2.0/docs/script/topics/script00102.html Синтакс-помощник: https://1cmycloud.com/console/help/executor/2.0/api/executor/ru/Std/Time/DateTime_ru.html 73 «1С:Предприятие.Элемент». Возможности встроенного языка Длительность В языке «1С:Предприятия» отсутствовал тип Длительность. Теперь в языке «Элемента» существует тип Длительность, который предназначен для работы с интервалами времени. Этот тип хранит количество миллисекунд, описывающих некоторый интервал времени. Значение типа Длительность можно получить следующим способом: ■■ С помощью конструктора типа, в котором составляющие интервала вводятся отдельными параметрами конструктора. Обязательность указания параметров конструктора зависит от используемого конструктора. Например: пер Интервал = новый Длительность(5, 7, 25, 44, 111) //результат: 127:25:44.111 (в часах) пер Интервал = новый Длительность(5, 45, 22) //результат: 05:45:22.000 (в часах) ■■ С помощью литерала, описывающего длительность. Литерал имеет вид [Ад][Бч][Вм][Гс][Дмс]. В этом литерале любой элемент может быть опущен, если соответствующее значение равно нулю. Компоненты означают следующее: ○○ д – значение дней; ○○ ч – значение часов; ○○ м – значение минут; ○○ с – значение секунд; ○○ мс – значение миллисекунд. пер Интервал = 5д14ч30м //результат: 134.30.00.000 (в часах) Для значений типа Длительность поддерживаются стандартные арифметические операции. Значение типа Длительность может участвовать в качестве одного из операндов в операциях сложения и вычитания для значений типа Дата, Время, Момент, ДатаВремя. Значение типа Длительность получается в результате вычитания значений типа Дата, Время, Момент, ДатаВремя. Например: Сообщить("%{Дата{2022-06-14} - Дата{2022-06-13}}") //результат: 24:00.00.000 Сообщить("%{Время{15:25:55} - Время{12:20:05}}") //результат: 03:05:50.000 Сообщить("%{Дата{2022-06-14} + 2д}") //результат: 2022-06-16 Сообщить("%{Время{15:25:55} - 3ч5м50с}") //результат: 12:20:05.000 Сообщить("%{Момент{2020-10-25 13:35:55 Z} - Момент{2020-10-22 12:30:55 Z}}") //результат 73:05:00.000 Сообщить("%{Момент{2020-10-25 13:35:55 Z} - 3д1ч5м}") //результат: 2020-10-22T12:30:55.000Z 74 Глава 3. Операции, инструкции, типы С помощью свойств и методов экземпляров типа Длительность можно легко выделять различные интервалы. А также представить значение типа Длительность в читаемом формате. Например: пер Интервал = новый Длительность(7, 25, 44) Сообщить("%{Интервал.Часы} ч. %{Интервал.Минуты} м. %{Интервал.Секунды} с.") // Результат: 7 ч. 25 м. 44 с. Интервал = новый Длительность( 127, 25, 44) Сообщить("%{Интервал.Дни} д. %{Интервал.Часы} ч. %{Интервал.Минуты} м. %{Интервал.Секунды} с.") // Результат: 5 д. 7 ч. 25 м. 44 с. ПОДРОБНЕЕ Документация: https://1cmycloud.com/console/help/executor/2.0/docs/script/topics/script00099.html Синтакс-помощник: https://1cmycloud.com/console/help/executor/2.0/api/executor/ru/Std/Time/Duration_ru.html Коллекции В языке «1С:Предприятия» существовали коллекции значений: Массив и Соответствие. Теперь в языке «Элемента» также есть коллекции Массив и Соответствие, кроме этого, есть новая коллекция – Множество. ■■ Массив – изменяемая коллекция, представляющая собой список элементов, без контроля уникальности. Коллекция поддерживает доступ по индексу. ■■ Соответствие – изменяемая коллекция, представляющая собой словарь, список пар «ключ-значение». В коллекции поддерживается уникальность по ключу и доступ по индексу. ■■ Множество – изменяемая коллекция, представляющая собой список уникальных элементов. Не поддерживается доступ по индексу. В основе всей иерархии типов, предназначенных для работы с коллекциями, лежит тип Обходимое. Это значит, что элементы коллекций можно обходить в цикле. Коллекцию Множество можно обходить только в цикле для…из. Ниже об этих коллекциях будет рассказано подробнее и будут показаны их отличия от языка «1С:Предприятия». 75 «1С:Предприятие.Элемент». Возможности встроенного языка Массив Типизация В языке «1С:Предприятия» можно было объявить массив без указания его типа и затем добавить в массив значения разных типов. При этом тип элементов массива никак не контролировался. Например: Массив = Новый Массив(); Массив.Добавить(1); Массив.Добавить(3); Массив.Добавить("пять"); Массив.Добавить(7); Массив.Добавить(Ложь); Теперь в языке «Элемента» тип Массив<> – это обобщенный тип (подробнее см. раздел «Обобщенные типы»). При этом в массив нельзя записать элемент иного типа, чем тот, с которым он объявлен. При использовании конструктора тип элемента массива указывается в угловых скобках после имени типа без пробела. Например: пер МассивЧисел = новый Массив<Число>() МассивЧисел = [11, 55, 33] //в этом массиве могут быть только числа При использовании литерала тип элемента массива можно явно указать слева от списка элементов в угловых скобках без пробела, если в массив нужно добавлять элементы, типы которых отличаются от перечисленных в литерале. Причем этот тип может быть составным. Например: пер Строки = ["один", "два", "три"] //тип элементов массива - Строка В следующем примере в массив добавлены строки, но можно добавлять и числа тоже: пер ЧислаИСтроки = <Число|Строка>["один", "три"] //тип элементов массива – Строка или Число Кроме того, можно создать пустой массив с помощью пустого литерала. Например, пустой массив строк: пер МассивСтрок = <Строка>[] 76 Глава 3. Операции, инструкции, типы Литерал В языке «1С:Предприятия» наполнить массив элементами можно было только с помощью методов Добавить() и Вставить(). Например: ИменаПолей = новый Массив; ИменаПолей.Добавить("Идентификатор"); ИменаПолей.Добавить("Размер"); ИменаПолей.Добавить("Цвет"); ИменаПолей.Вставить(3, "Вес"); Теперь в языке «Элемента» для создания экземпляра массива можно использовать литерал массива. Элементы массива заключаются в квадратные скобки «[]»). Например: пер ИменаПолей = ["Идентификатор", "Размер", "Цвет"] Таким образом, массив одновременно создается и заполняется элементами. Такая запись более компактна и понятна. И, хотя заполнить массив элементами по-прежнему можно с помощью методов Добавить() и Вставить(), рекомендуется использовать литералы. Кроме того, можно использовать литералы и при вызове методов. То есть, не объявляя массив заранее, указать литерал массива в качестве аргумента метода. Например: метод МойМетод() ОбработатьПоля(["Идентификатор", "Размер", "Цвет"]) ; метод ОбработатьПоля(Поля: Массив<Строка>) ; Или, например, при обходе элементов массива использовать его литерал: для Элемент из [55, "сто", 3] Сообщить("%Элемент") ; //результат – три элемента массива: 55, "сто", 3 Сравнение массивов В языке «1С:Предприятия» нельзя было сравнить друг с другом массивы целиком. Надо было обходить массивы в цикле и сравнивать их поэлементно. Теперь в языке «Элемента» можно сравнивать массивы на равенство (или неравенство). Два массива являются равными, если равны их 77 «1С:Предприятие.Элемент». Возможности встроенного языка размеры и каждый элемент первого массива содержится во втором массиве. При этом порядок следования элементов массива друг за другом важен. Например: пер Массив1 = ["один", 22, 333] пер Массив2 = ["один", 22, 333] если Массив1 == Массив2 Сообщить("массивы равны") иначе Сообщить("массивы не равны") ; пер Массив1 = ["один", 22, 333] пер Массив2 = ["один", 333, 22] если Массив1 == Массив2 Сообщить("массивы равны") иначе Сообщить("массивы не равны") ; //выводится сообщение о равенстве массивов //выводится сообщение о неравенстве массивов Метод «СортироватьПо» В языке «1С:Предприятия» нельзя было отсортировать элементы массива. В языке «Элемента» можно отсортировать содержимое массива с помощью метода СортироватьПо(). Этот метод имеет первый параметр функционального типа, в который вы должны передать свое лямбда-выражение. Это выражение должно вернуть то свойство элемента массива, по которому массив нужно отсортировать. Например, можно просто отсортировать массив чисел по возрастанию его элементов: знч Числа =[5, 1, 7, 3] Числа.СортироватьПо(Элемент->Элемент) // Массив Числа содержит [1, 3, 5, 7] Если элементы массива содержат структуру, то с помощью лямбдавыражения можно задать поле этой структуры, по которому нужно отсортировать массив. Например, массив структур Сотрудники, состоящий из элементов структуры Сотрудник, сортируется по полю Возраст этой структуры: структура Сотрудник знч ФИО: Строка знч Возраст: Число ; 78 Глава 3. Операции, инструкции, типы метод Пример() знч Сотрудники = [новый Сотрудник("Стрельцов",44), новый Сотрудник("Малахова", 22), новый Сотрудник("Королев",33)] Сотрудники.СортироватьПо(ПарамСотрудник->ПарамСотрудник.Возраст) ; ПОДРОБНЕЕ Подробнее про функциональные типы будет рассказано в 3-й главе в разделе «Функциональные типы». ПОДРОБНЕЕ Синтакс-помощник: https://1cmycloud.com/console/help/executor/2.0/api/executor/ru/Std/Collections/Array_ru.html Соответствие Литералы и конструктор В языке «1С:Предприятия» у соответствия не было литерала. Теперь в языке «Элемента» у соответствия есть три литерала (литерал с указанием типов пар ключей и значений, литерал без указания типов и литерал пустого соответствия). Литералы в языке «Элемента» можно использовать при создании экземпляра соответствия, в качестве аргумента при вызове метода, а также при обходе соответствия в цикле. Элементы соответствия заключаются в фигурные скобки («{}»). Сами элементы являются парами «ключ-значение». Пары разделяются запятой («,»). Значение ключа отделяется от собственно значения двоеточием («:»). Например: // Использование литерала при создании соответствия. пер КурсыВалют = {"RUB": 1, "BYN": 31.01} // Использование литерала при вызове метода. ОбработатьВалюты({"RUB": 1, "BYN": 31.01}) // Использование литерала при обходе соответствия. для Элемент из {"1-й этап": 120, "2-й этап": "3 часа", "3-й этап":310} ; 79 «1С:Предприятие.Элемент». Возможности встроенного языка Типы ключей и значений соответствия, которые перечисляются через запятую в угловых скобках, также можно явно указать перед списком элементов, если в соответствие нужно добавлять элементы, типы которых отличаются от перечисленных в литерале. Например: // В качестве значения соответствия можно указывать еще и процент выполнения работы числом пер СрокиРаботы = <Дата, Число|Строка>{Дата{2022-07-03} : "Выполнено", Дата{2022-08-15} : "Планируется"} Соответствие можно создать также с помощью конструктора соответствия с указанием типов ключей и значений, которые перечисляются через запятую в угловых скобках после имени типа. Причем типы ключа и/или значения могут быть составными. Например: пер ЭтапыРаботы = новый Соответствие<Строка|Дата, Число|Строка>() ЭтапыРаботы.Вставить("1-й этап", 120) ЭтапыРаботы.Вставить(Дата{2022-07-01}, "2 часа") ЭтапыРаботы.Вставить("3-й этап", 310) Кроме того, можно создать пустое соответствие с помощью пустого литерала. Например: пер ЭтапыРаботы = <Строка, Число>{:} Методы «Вставить()» и «ВставитьЕслиОтсутствует()» В языке «1С:Предприятия» вставить в соответствие пару Ключ и Значение можно было только методом Вставить(). Если пара с указанным значением ключа уже существовала, то его значение заменялось на новое, в противном случае в соответствие добавлялся новый элемент. Теперь в языке «Элемента» для вставки элементов в соответствие есть еще один полезный метод ВставитьЕслиОтсутствует(), который позволяет вставить какую-либо пару значений только в том случае, если этой пары еще нет в соответствии. Если же ключ в соответствии уже есть, то метод ВставитьЕслиОтсутствует() не будет изменять существующую пару. При выполнении проверки анализируется только значение ключа. Например: пер С1 = {"1-й этап": 120, "2-й этап": "3 часа", "3-й этап":310} Сообщить("%С1") //результат: {1-й этап: 120, 2-й этап: 3 часа, 3-й этап: 310} С1.Вставить("3-й этап", 33) Сообщить("%С1") //результат: {1-й этап: 120, 2-й этап: 3 часа, 3-й этап: 33} 80 Глава 3. Операции, инструкции, типы С1.ВставитьЕслиОтсутствует("3-й этап", 20) Сообщить("%С1") //результат: {1-й этап: 120, 2-й этап: 3 часа, 3-й этап: 33} С1.ВставитьЕслиОтсутствует("4", 4) Сообщить("%С1") //результат: {1-й этап: 120, 2-й этап: 3 часа, 3-й этап: 33, 4: 4} Сравнение соответствий В языке «1С:Предприятия» нельзя было сравнить друг с другом соответствия целиком. Надо было обходить соответствия в цикле и сравнивать попарно ключи и значения. Теперь в языке «Элемента» можно сравнивать соответствия на равенство (или неравенство). Два соответствия будут считаться равными, если размеры этих соответствий совпадают, ключи одного соответствия являются ключами другого, а также попарно совпадают все значения одинаковых ключей. При этом порядок следования пар ключей и значений друг за другом не имеет значения. Например: пер С1 = {"1-й этап": 120, "2-й этап": "3 часа", "3-й этап":310} пер С2 = {"1-й этап": 120, "2-й этап": "3 часа", "3-й этап":310} если С1 == С2 Сообщить("соответствия равны") //выводится сообщение о равенстве соответствий иначе Сообщить("соответствия не равны") ; пер С1 = {"1-й этап": 120, "2-й этап": "3 часа", "3-й этап":310} пер С2 = {"3-й этап":310, "1-й этап": 120, "2-й этап": "3 часа"} если С1 == С2 Сообщить("соответствия равны") //выводится сообщение о равенстве соответствий иначе Сообщить("соответствия не равны") ; пер С1 = {"1-й этап": 120, "2-й этап": "3 часа", "3-й этап":310} пер С2 = {"1-й этап": 120, "2-й этап": "3 часа", "3-й этап":310, "4-й этап": 4} если С1 == С2 Сообщить("соответствия равны") иначе Сообщить("соответствия не равны") //выводится сообщение о неравенстве соответствий ; ПОДРОБНЕЕ Синтакс-помощник: https://1cmycloud.com/console/help/executor/2.0/api/executor/ru/Std/Collections/Map_ru.html 81 «1С:Предприятие.Элемент». Возможности встроенного языка Множество В языке «1С:Предприятия» множеств не было. Теперь в языке «Элемента» есть коллекция, называемая Множество. Это изменяемая коллекция, которая содержит только уникальные элементы. Это обеспечивает быструю проверку вхождения элемента в коллекцию. Множество позволяет хранить элементы произвольных типов. Литералы Литерал в языке «Элемента» можно использовать при создании экземпляра множества, в качестве аргумента при вызове метода, а также при обходе множества в цикле. Элементы множества заключаются в фигурные скобки («{}»). Например: // Использование литерала при создании множества. пер МножествоСДанными = {1, 2, 3} // Использование литерала при вызове метода. ОбработатьДанные({1, 2, 3}) // Использование литерала при обходе множества. для Элемент из {1, 2, 3} ; Типы элементов множества также можно явно указать перед списком элементов в угловых скобках, если в множество нужно добавлять элементы, типы которых отличаются от перечисленных в литерале. Например: // В следующее множество можно добавлять и строки тоже пер МножествоСДанными = <Число|Строка>{1, 2} Множество можно создать также с помощью конструктора множества с указанием типов его элементов в угловых скобках после имени типа. Причем типы элементов могут быть составными. Например: пер МножествоСДанными = новый Множество<Число|Строка>() МножествоСДанными.Добавить(1) МножествоСДанными.Добавить(2) МножествоСДанными.Добавить("три") Кроме того, можно создать пустое множество с помощью пустого литерала. Например: пер МножествоЧисел = <Число>{} 82 Глава 3. Операции, инструкции, типы Методы для выполнения специальных операций над множествами Важной особенностью множеств является возможность выполнять над ними специальные операции: ■■ Проверка на равенство. Два множества являются равными, если равны их размеры и каждый элемент первого множества содержится во втором множестве. При этом порядок следования элементов множества друг за другом не важен. ■■ Объединение множеств (метод Объединение()). В этом случае формируется множество, которое содержит все уникальные значения двух исходных множеств. Например: пер Множество1 = {1, 2, 3, 4} пер Множество2 = {3, 4, 5, 6} // Результат объединения: {1, 2, 3, 4, 5, 6} пер Объединение = Множество1.Объединение(Множество2) ■■ Пересечение множеств (метод Пересечение()). В этом случае формируется множество, которое содержит только те элементы, которые присутствуют одновременно в обоих множествах. Например: пер Множество1 = {1, 2, 3, 4} пер Множество2 = {3, 4, 5, 6} // Результат пересечения: {3, 4} пер Пересечение = Множество1.Пересечение(Множество2) ■■ Разность множеств (методы Разность() и СимметрическаяРазность()). Простая разность формирует результирующее множество, содержащее только те элементы исходного множества, которые отсутствуют во множестве, являющемся параметром метода. Симметрическая разность формирует результирующее множество, содержащее только те элементы, которые уникальны в каждом множестве. Другими словами, результат работы метода не будет включать в себя значения, которые есть одновременно в обоих множествах. 83 «1С:Предприятие.Элемент». Возможности встроенного языка Например: пер Множество1 = {1, 2, 3, 4} пер Множество2 = {3, 4, 5, 6} // Результат разности: {1, 2} пер Разность = Множество1.Разность(Множество2) // Результат симметрической разности: {1, 2, 5, 6} пер СимРазность = Множество1.СимметрическаяРазность(Множество2) ПОДРОБНЕЕ Синтакс-помощник: https://1cmycloud.com/console/help/executor/2.0/api/executor/ru/Std/Collections/Set_ru.html Собственные типы Перечисление В языке «1С:Предприятия» можно было создать перечисление только на этапе конфигурирования в дереве метаданных. Для этого использовался объект конфигурации Перечисление. Например: Рис. 3.7. Создание перечисления в конфигурации 84 Глава 3. Операции, инструкции, типы После указания значений перечисления можно было использовать его в коде конфигурации. Теперь в языке «Элемента» вы можете создать свой собственный тип перечисления на основе стандартного типа Перечисление, а затем можете использовать элементы своего перечисления в коде приложения. Чтобы объявить перечисление, нужно с помощью инструкции перечисление объявить тип своего перечисления в теле модуля вне методов. Например: перечисление ВидСообщения Важное, Обычное умолчание, Второстепенное ; В этом примере описано перечисление с именем ВидСообщения с тремя элементами: Важное, Обычное и Второстепенное. Элемент Обычное отмечен как элемент по умолчанию. В составе перечисления должно быть минимум одно значение. Перечисление может обладать единственным значением по умолчанию или вовсе не иметь значения по умолчанию. Значение по умолчанию будет использоваться в том случае, если переменная описывается с типом создаваемого перечисления и для этой переменной не указывается значение инициализации. Значением по умолчанию может быть любой элемент перечисления. Для обращения к элементу перечисления следует указать имя самого перечисления и, через точку, требуемый элемент перечисления. Например: // в переменной Важность будет значение Обычное перечисления ВидСообщения пер Важность: ВидСообщения //используется значение по умолчанию // в переменной Важность будет значение Важное перечисления ВидСообщения пер Важность: ВидСообщения.Важное //значение перечисления указано явно Допускается также использование значения перечисления без упоминания имени самого перечисления (имени типа). Это возможно в кратком виде написания инструкции выбор с выбором из значений перечисления. 85 «1С:Предприятие.Элемент». Возможности встроенного языка Например: перечисление ОперационныеСистемы Linux, macOS, Windows умолчание ; метод МойМетод() пер ИспользуемаяОС: ОперационныеСистемы ; выбор ИспользуемаяОС когда Windows // делаем что-то в случае Windows когда Linux, macOS // делаем что-то, если macOS или Linux ; Структура В языке «1С:Предприятия» можно было создать экземпляр типа Структура и тут же заполнить его ключами и значениями, в том месте, где этот экземпляр создается. Например: Товар = Новый Структура("Наименование, Артикул, Цена", "Холодильник", "М50", 5300); Товар.Наименование = "Утюг"; Товар.Цена = "хорошая"; Товар = Новый Структура("Вес, Рост", 80, 180); Заранее в таком типе не было никаких ключей. Такую структуру было неудобно использовать, особенно в разных местах кода. Например, если в одном из мест вы решили добавить в структуру новое поле, то потом было сложно поддерживать ее актуальность. Теперь в языке «Элемента» вы можете с помощью инструкции структура создать собственный тип данных и указать, например, что в этой структуре будут два поля: Фамилия и Оценка. Это будет тип Студент. А также можете создать другую структуру типа Адрес с полями Город, Улица, Дом и т. п. Соответственно, теперь в разных местах программы вы можете создавать и использовать экземпляры этих типов, они сразу же будут иметь нужный набор полей. структура Товар знч Наименование: Строка пер Артикул: Строка пер Цена: Число 86 Глава 3. Операции, инструкции, типы ; конструктор(Наименование) конструктор(Наименование, Артикул, Цена) метод МойМетод() пер ПервыйТовар = новый Товар("Холодильник", "М50", 5300) пер ВторойТовар = новый Товар("Пылесос") ; ВторойТовар.Артикул = "VC20" ВторойТовар.Цена = 5000 В отличие от языка «1С:Предприятия» состав полей структуры и их типы определяются в момент разработки программы. Во время исполнения программы ни состав полей, ни типы полей измениться уже не могут. Поэтому такую структуру нет необходимости документировать, кроме того, для нее существует контекстная подсказка. Каждое поле структуры объявляется аналогично обычной переменной в модуле. Оно начинается с ключевого слова пер или знч, затем следуют имя поля, его тип и необязательное значение инициализации. Если описание поля структуры начинается с модификатора пер, то значение такого поля может быть изменено путем присваивания значения. Если описание поля структуры начинается с модификатора знч, то для такого поля значение может быть установлено только во время создания экземпляра структуры с помощью конструктора. Имена полей должны соответствовать общим требованиям к именам языка. Они должны быть уникальны в рамках одной структуры. Поле структуры не может иметь тип самой определяемой структуры. Значение инициализации описывает, какое значение будет принимать поле структуры при создании объекта. В качестве инициализатора может выступать любое выражение, которое вычислимо во время компиляции. Например: структура Сотрудник знч ФИО: Строка знч Возраст: Число = 33 конструктор (ФИО) конструктор (ФИО, Возраст) ; метод МойМетод() пер Директор = новый Сотрудник("Иванов") //Директор = {ФИО=Иванов, Возраст = 33} ; 87 «1С:Предприятие.Элемент». Возможности встроенного языка Экземпляр структуры создается с помощью конструктора, который может быть указан после блока описания полей с помощью ключевого слова конструктор при объявлении структуры. Если конструктор не указан, то при создании экземпляра структуры используется автоматический конструктор, который включает в себя все поля структуры в том порядке, как они описаны в самой структуре. Конструкторов может быть несколько. Они должны отличаться числом аргументов. В качестве аргументов конструктора должны быть указаны имена полей, инициализация которых будет выполняться при создании экземпляра структуры, то есть поля структуры, типы которых не обладают значениями по умолчанию и для которых не указаны данные инициализации. Для параметров конструктора не допускается указание значений по умолчанию. Порядок полей в конструкторе может не совпадать с порядком полей в описании структуры. Кроме того, можно использовать именованную форму передачи аргументов в конструктор. Например: структура Сотрудник знч ФИО: Строка знч Возраст: Число конструктор (ФИО) конструктор (ФИО, Возраст) ; метод МойМетод() пер Менеджер = новый Сотрудник(Возраст = 22, ФИО = "Мохов") ; Исключения В языке «1С:Предприятия» нельзя было создать и обработать собственное исключение – событие, которое возникает во время ошибки при исполнении кода программы. Теперь в языке «Элемента» вы можете создать свой собственный тип исключения на основе стандартного типа Исключение и затем использовать его в коде приложения: ■■ создать экземпляр исключения; ■■ выбросить его; 88 Глава 3. Операции, инструкции, типы ■■ поймать его в другом месте программы с помощью инструкции попытка-поймать; ■■ обработать свое исключение. Например: @Сервер исключение ИсключениеНеверныйФорматФайла пер ИмяФайла: Строка ; @Сервер статический метод МойМетод() попытка // безопасный код ПрочитатьФайл("path\\file.txt") поймать Искл1: ИсключениеНеверныйФорматФайла // обработка исключения типа ИсключениеНеверныйФорматФайла ОбработатьИсключение(Искл1) ; ; @Сервер статический метод ПрочитатьФайл(Путь: Строка) ... // Здесь выясняется, что формат файла неправильный // Создать экземпляр исключения и выбросить его выбросить новый ИсключениеНеверныйФорматФайла("Неверный формат файла", "path\\file.txt") ; @Сервер статический метод ОбработатьИсключение(Искл: ИсключениеНеверныйФорматФайла) //… ; Чтобы объявить исключение, нужно с помощью инструкции исключение объявить тип своего исключения в теле модуля вне методов. Например: исключение ИсключениеЧтенияФайла пер ИмяФайла: Строка ; В некотором смысле описание типа исключения подобно описанию структуры: каждый тип исключения может содержать поля, которые будут содержать информацию, специфическую для этого типа исключения. Следует помнить, что при описании исключения не допускаются значения инициализации. 89 «1С:Предприятие.Элемент». Возможности встроенного языка Теперь для того, чтобы создать экземпляр этого исключения, следует написать следующий код: пер Искл = новый ИсключениеЧтенияФайла("Ошибка чтения файла", "path\file.txt") Экземпляр исключения создается с помощью конструктора, в котором первым аргументом передается текстовое представление ошибки, затем идут столько значений, сколько полей указано у вашего исключения, и последним, необязательным аргументом указывается исключение, которое явилось причиной выбрасываемого исключения. И затем это исключение можно выбросить с помощью инструкции выбросить: выбросить Искл Инструкция «попытка» В языке «1С:Предприятия» для обработки исключений использовалась конструкция Попытка – Исключение – КонецПопытки. Сама обработка ошибок времени выполнения выполнялась в блоке операторов Исключение – КонецПопытки. При этом не предусматривалась возможность обработки собственных исключений. Например: Процедура МояПроцедура() Попытка Файл = новый ЧтениеТекста("C:\test\test.txt"); ТекстФайла = Файл.Прочитать(); Исключение ОбработатьИсключение(ИнформацияОбОшибке()); КонецПопытки; КонецПроцедуры Процедура ОбработатьИсключение(Инфо) //… КонецПроцедуры Теперь в языке «Элемента» для обработки исключений предназначена специальная конструкция попытка – поймать. Здесь вместо ключевого слова Исключение используется поймать. При этом можно поймать и обработать отдельно все описанные вами ранее типы исключений, а также обработать все остальные типы исключений, для которых не нашлось обработчика (т. к. все собственные типы исключений являются наследниками базового типа Исключение). 90 Глава 3. Операции, инструкции, типы Кроме этого конструкция имеет дополнительный блок вконце. В этом блоке можно поместить код, который должен выполнить какие-то действия вне зависимости от того, удачно или неудачно завершился блок попытка. Блок вконце выполняется даже в том случае, если в блоках попытка и поймать используются инструкции возврат, прервать или продолжить. Например, если ранее вы определили собственные типы исключений: ИсключениеНеверныйФорматФайла, ТипИсключения1, ТипИсключения2, то обработка ошибочных ситуаций может выглядеть следующим образом: @Сервер исключение ИсключениеНеверныйФорматФайла пер ИмяФайла: Строка ; @Сервер исключение ТипИсключения1 пер ИмяФайла: Строка ; @Сервер исключение ТипИсключения2 пер ИмяФайла: Строка ; @Сервер метод МойМетод() попытка // безопасный код пер Файл = новый Файл("C:\\test\\test.txt") исп Поток = Файл.ОткрытьПотокЧтения() пер ТекстФайла = Поток.ПрочитатьКакСтроку() поймать Искл1: ИсключениеНеверныйФорматФайла // обработка исключения типа ИсключениеНеверныйФорматФайла ОбработатьИсключение(Искл1) поймать Искл2: ТипИсключения1| ТипИсключения2 // обработка исключений с типом ТипИсключения1 или ТипИсключения2 поймать Искл3: Исключение // обработка других исключений ; вконце // завершающая секция ; @Сервер метод ОбработатьИсключение(Искл: ИсключениеНеверныйФорматФайла) //… ; 91 «1С:Предприятие.Элемент». Возможности встроенного языка В результате работы данной конструкции если в тексте модуля, отмеченного комментарием «// безопасный код», произойдет ошибка, приводящая к выбрасыванию исключения, то будет определен тип исключения. Для него будет подобран подходящий обработчик исключений (тот, в котором тип исключения обработчика совпадает с типом обрабатываемого исключения), расположенный после конструкции поймать ИмяПеременной: ТипИсключения. В обработчик для типа Исключение управление будет передаваться для всех исключений, которые не были перехвачены ранее. Это произойдет потому, что тип Исключение является базовым типом для любого исключения. Надо заметить, что, поскольку работа с файлами возможна только на сервере, приведенный выше пример должен выполняться в серверной процедуре с аннотацией @Сервер. И, соответственно, типы ваших исключений должны быть описаны с такой же аннотацией. Например: @Сервер исключение ИсключениеНеверныйФорматФайла пер ИмяФайла: Строка ; Инструкция «выбросить» В языке «1С:Предприятия» можно было вызвать исключение в тех случаях, когда, несмотря на отработку исключительной ситуации, необходимо прервать выполнение модуля с ошибкой времени выполнения. Для этого использовался оператор ВызватьИсключение, который мог быть помещен только в блоке операторов Исключение – КонецПопытки. Например: Попытка Файл = новый ЧтениеТекста("C:\test\test.txt"); ТекстФайла = Файл.Прочитать(); Исключение ВызватьИсключение "Файл не существует"; КонецПопытки; Теперь в языке «Элемента» существует преемник инструкции ВызватьИсключение – это инструкция выбросить. Эта инструкция позволяет вам самостоятельно выбросить исключение указанного типа. В отличие от языка «1С:Предприятия»: ■■ вы можете выбрасывать исключения не только внутри блока Исключение – КонецПопытки; 92 Глава 3. Операции, инструкции, типы ■■ вы можете выбрасывать исключения как стандартных, так и собственных типов. Например: исключение ИсключениеЧтенияФайла пер ИмяФайла: Строка ; метод МойМетод() пер Файл = новый Файл("C:\\test\\test.txt") если не Файл.Существует() выбросить новый ИсключениеЧтенияФайла("Файл не существует", "C:\\test\\test.txt") ; исп Поток = Файл.ОткрытьПотокЧтения() пер ТекстФайла = Поток.ПрочитатьКакСтроку() ; В качестве параметра данной инструкции выступает экземпляр, описывающий исключение. Тип такого экземпляра является потомком типа Исключение. Этот экземпляр может быть создан с помощью конструктора или получен в обработчике какого-либо исключения. Стандартные типы исключений Можно создавать и выбрасывать исключения не только собственных, но и стандартных типов. Экземпляр исключения стандартного типа можно создать с помощью одного из конструкторов: ■■ Без параметров. ■■ Только описание. ■■ Только причина исключения вложенное исключение). (при необходимости создать ■■ Описание и причина исключения. Например, вы можете выбросить исключение стандартного типа ИсключениеИндексВнеГраниц: выбросить новый ИсключениеИндексВнеГраниц("Выход за границы индекса") 93 «1С:Предприятие.Элемент». Возможности встроенного языка Обобщенные типы В языке «1С:Предприятия» не использовались обобщенные типы. Теперь в языке «Элемента» применяются обобщенные типы, чтобы типизировать элементы коллекций. То есть при объявлении коллекций указывается тип содержащихся в них элементов. Зачем нужно типизировать содержимое коллекций? Например, в языке «1С:Предприятия» было известно, что в метод придет массив чисел. Соответственно, алгоритм этого метода рассчитан на то, что в массиве числа. Но вдруг пришел массив, в котором есть строки, и на этом приложение выдаст ошибку во время выполнения. Теперь же в языке «Элемента» в тексте программы указано, что массив должен состоять из чисел. И если компилятор обнаружит, что в какой-то ветке алгоритма в этом массиве появляются строки, он сразу же выдаст ошибку еще до начала выполнения приложения. Причем информация о типах-параметрах обобщенного типа сохраняется до времени выполнения приложения. Например, объявляется массив, состоящий из чисел: пер МассивЧисел: Массив<Число> Это означает, что в массиве будут храниться числа. И уже не получится добавить в этот массив строки (МассивЧисел.Добавить("333")) – будет получена ошибка несоответствия типа аргумента. Или, например, можно написать: пер СуммаЧисел = 3 + МассивЧисел[0] Компилятор поймет, что в массиве МассивЧисел только числа, и не потребует преобразования МассивЧисел[0] к числу. При создании экземпляра коллекции с помощью конструктора тип элементов коллекции указывается в угловых скобках после имени типа, без пробела. Причем элемент коллекции может иметь составной тип. Например: // Создание экземпляра массива пер МассивЧисел = новый Массив<Число>() // Создание экземпляра соответствия 94 Глава 3. Операции, инструкции, типы пер ЭтапыРаботы = новый Соответствие<Строка|Дата, Число|Строка>() // Создание экземпляра множества пер МножествоСДанными = новый Множество<Число|Строка>() При создании экземпляра коллекции с помощью литерала тип элементов коллекции можно явно указать слева от списка элементов в угловых скобках без пробела, если в коллекцию нужно добавлять элементы, типы которых отличаются от перечисленных в литерале. Например: // Создание экземпляра массива с помощью литерала пер Строки = ["один", "два", "три"] // В следующий массив можно добавлять и числа тоже пер ЧислаИСтроки = <Число|Строка>["один", "три"] // Создание экземпляра соответствия с помощью литерала пер КурсыВалют = {"RUB": 1, "BYN": 31.01} // В качестве значения соответствия можно указывать еще и процент выполнения работы числом пер СрокиРаботы = <Дата, Число|Строка>{Дата{2022-07-03} : "Выполнено", Дата{2022-08-15} : "Планируется"} // Создание экземпляра множества с помощью литерала пер МножествоСДанными = {1, 2, 3} // В следующее множество можно добавлять и строки тоже пер МножествоСДанными = <Число|Строка>{1, 2} Тип элементов коллекций определяется следующим образом: ■■ если тип указан явно в параметрах обобщенного типа (в угловых скобках), используется указанный тип: пер Массив1 = <Число>[1] пер ТипМассива = Массив1.ПолучитьТип() // Тип: Массив<Число> ■■ иначе используется тип переменной, которой присваивается значение литерала, если он известен: пер Массив2: ЧитаемыйМассив<Число> Массив2 = [1] ТипМассива = Массив2.ПолучитьТип() // Тип: ЧитаемыйМассив<Число> ■■ иначе тип определяется как объединение типов элементов коллекции: пер Массив3 = [1, Истина] ТипМассива = Массив3.ПолучитьТип() // Тип: Массив<Булево|Число> 95 «1С:Предприятие.Элемент». Возможности встроенного языка Кроме того, можно создать пустую типизированную коллекцию с помощью пустого литерала. Например: // Пустой массив пер МассивСтрок = <Строка>[] // Пустое соответствие пер ЭтапыРаботы = <Строка, Число>{:} // Пустое множество пер МножествоЧисел = <Число>{} Сравнение экземпляров обобщенных типов не учитывает параметры обобщенного типа. Например: пер Соответствие1 = новый Соответствие<Объект, Объект>() Соответствие1.Вставить(1, 2) пер Соответствие2 = новый Соответствие<Число, Число>() Соответствие2.Вставить(1, 2) если Соответствие1 == Соответствие2 Сообщить("истина") //соответствия равны ; Обобщенные системные методы В языке «1С:Предприятия» не использовались обобщенные системные методы. Теперь в языке «Элемента» применяются обобщенные системные методы – это методы, имеющие тип-параметр, влияющий на типизацию метода. Тип параметра метода накладывает опциональное ограничение на тип аргумента, с которым вызывается метод. То есть метод может быть вызван для параметра (параметров), типы которых определяются типом-параметром метода. Таким же образом тип результата метода может быть связан с типом параметра метода. При вызове системного обобщенного метода тип-параметр указывается в угловых скобках после имени метода без пробела. Причем этот тип может быть составным. Если тип метода может быть выведен из контекста (по параметрам), то, по аналогии с обобщенными типами, его явно указывать не требуется. Например: пер Переменная1 = Макс<Число>(11, 7, 13) пер Переменная2 = Макс<Строка|Число>("90", "66", "82") пер Переменная3 = Макс("сто", "три", "двадцать") 96 //результат = 13 //результат = "90" //результат = "три" Глава 3. Операции, инструкции, типы Нужно учитывать, что на момент написания данной книги нет возможности создавать собственные обобщенные методы. Обобщенные методы могут быть только в системных экземплярах. В приведенном выше примере это метод глобального контекста Макс(). Можно привести еще следующие примеры обобщенных системных методов: ЧитаемоеСоответствие<тип-ключа, тип-значения> .ПолучитьИлиУмолчание<ТипУмолчания>( Ключ: тип-ключа, Умолчание: тип-значения|ТипУмолчания ): тип-значения|ТипУмолчания Здесь тип-параметр ТипУмолчания определяет тип значения, которое будет возвращено в том случае, если читаемое соответствие не содержит указанного ключа. ЗапланированныеЗадания .Создать<Type1, Type2 >( Обработчик: (Type1, Type2)->ничто, Параметр1: Type1, Параметр2: Type2 ) Здесь типы-параметры Type1, Type2 и т. д. определяют типы значений параметров, которые передаются в метод, который будет вызван для выполнения запланированного задания. ФоновыеЗадания .Выполнить<Type1, Type2 >( Обработчик: (Type1, Type2)->ничто, Параметр1: Type1, Параметр2: Type2 ) Здесь типы-параметры Type1, Type2 и т. д. определяют типы значений параметров, которые передаются в метод, который будет вызван для выполнения фонового задания. Статические системные методы В языке «1С:Предприятия» не использовались статические системные методы. Теперь в языке «Элемента» у некоторых типов существуют статические системные методы, к которым вы можете обратиться, не создавая 97 «1С:Предприятие.Элемент». Возможности встроенного языка экземпляр типа. Такие методы в документации предваряются описанием «статический». Таким образом, статический метод – это метод типа, а не экземпляра. Обычно, чтобы обратиться к свойствам и методам типа, вы должны сначала создать экземпляр этого типа. Например, с помощью конструктора вы создаете экземпляр типа ЧасовойПояс, а затем вызываете метод ТекущееСмещение() для этого экземпляра: пер МойЧасовойПояс = новый ЧасовойПояс("Europe/Moscow") пер Смещение = МойЧасовойПояс.ТекущееСмещение() // Смещение = 03:00:00.000 Но, кроме того, у типа ЧасовойПояс есть статический метод Текущий(). И к этому методу вы можете обратиться сразу через точку, не создавая экземпляр типа. Например: пер ТекущийЧасовойПояс = ЧасовойПояс.Текущий() // ТекущийЧасовойПояс = Etc/Gmt-3 Нужно понимать, что это не настоящее обращение через точку, а просто такая форма записи обращения к статическому системному методу, когда пишутся имя типа, точка и имя статического метода. При настоящем обращении через точку сначала было бы вычислено значение ЧасовойПояс. Но это невозможно, так как это не типодиночка. Типы-одиночки Тип-одиночка – это тип, у которого может быть только один экземпляр (соответственно, нет конструкторов). Этот тип не может быть обобщенным. Такие типы помечаются в синтакс-помощнике как «Одиночка». Экземпляр типа-одиночки можно получить через синтаксис: <ИмяТипаОдиночки>. Можно сказать, что тип-одиночка порождает неявное свойство глобального контекста, называющееся как тип-одиночка, с единственным экземпляром этого типа. Например, типы ФоновыеЗадания, Файлы – это типы-одиночки. Чтобы получить его экземпляр, достаточно написать: пер МенеджерФоновыхЗаданий = ФоновыеЗадания пер МенеджерФайлов = Файлы 98 Глава 3. Операции, инструкции, типы Функциональные типы В языке «1С:Предприятия» не использовались функциональные типы. Теперь в языке «Элемента» существуют функциональные типы. Функциональный тип – это тип, значениями которого являются методы. Функциональные типы позволяют хранить методы в переменных, передавать их в другие методы как аргументы и возвращать как результат. Зачем нужны функциональные типы? Их появление обусловлено тем, что язык «Элемента» стремится максимальным образом типизировать все элементы программы и прикладного решения. Так, например, в языке «1С:Предприятия» обработчик события являлся просто строкой, содержащей имя процедуры. Если параметры этой процедуры не соответствовали тому, что ожидает платформа, то обнаружить это можно было только в момент выполнения программы. Теперь в языке «Элемента» обработчик события – это значение функционального типа, как правило, ссылка на существующий метод. Компилятор знает, какие параметры должны быть переданы в этот метод, и контролирует их правильность еще на этапе написания кода. Другой случай – когда требуется типизация функциональным типом, это передача одного метода в другой метод. Например, в языке «1С:Предприятия» такая ситуация возникала с описаниями оповещения: Оповещение = Новый ОписаниеОповещения("ПодборЗавершение", ЭтотОбъект); ПоказатьВопрос(Оповещение, "Подобрать номенклатуру в документ?", РежимДиалогаВопрос.ДаНет); Здесь в процедуру ПоказатьВопрос() передается, грубо говоря, имя процедуры, которая должна быть выполнена после интерактивного ответа на вопрос. В языке «Элемента» в таких случаях используются значения функционального типа. Например, в методе Мультимедиа.СканироватьШтрихкоды(): Мультимедиа.СканироватьШтрихкоды("Просканируйте товары чтобы добавить их в заказ", ВидШтрихкода.Двумерный, (штрихкод) -> ОбработатьШтрихкод(штрихкод)) Здесь третьим параметром передается метод ОбработатьШтрихкод(), который будет вызван при сканировании. 99 «1С:Предприятие.Элемент». Возможности встроенного языка ПОДРОБНЕЕ Документация: https://1cmycloud.com/console/help/executor/2.0/docs/script/topics/script100007.html Имя функционального типа содержит типы параметров и возвращаемого значения, разделенные символом лямбда-операции ->. Ниже приведены примеры описания значений функционального типа: ■■ Значением типа является метод, принимающий два параметра типа Число и возвращающий значение типа Строка: знч Результат: (Число, Число)->Строка ■■ Значением типа является метод, принимающий два параметра типа Число и возвращающий значение составного типа (Строка или Неопределено): знч Результат: (Число, Число)->Строка? ■■ Значением типа является метод с одним параметром составного типа (Число или Неопределено), возвращающий значение составного типа (Строка или Число): знч Результат: (Число?)->Строка|Число ■■ Значением типа является метод без параметров, возвращающий значение типа Строка: знч Результат: ()->Строка ■■ Значением типа является метод с одним параметром типа Строка, не возвращающий ничего: знч Результат: (Строка)->ничто Функциональный тип может являться частью составного типа. В этом случае имя функционального типа должно быть заключено в скобки, иначе все, что следует за лямбда-операцией ->, будет считаться составным типом результата. Например: ■■ Составной тип, значением которого является либо Неопределено, либо метод с одним параметром типа Число, возвращающий значение типа Строка: знч Результат: ((Число)->Строка)? 100 Глава 3. Операции, инструкции, типы ■■ Составной тип, значением которого является либо Булево, либо метод с одним параметром типа Число, возвращающий значение типа Строка: знч Результат: ((Число)->Строка)|Булево Значения функционального типа могут записываться двумя способами: ■■ С помощью лямбда-выражения, например: (Строка1, Строка2) -> Строка1.Длина() < Строка2.Длина(). ■■ С помощью ссылки на существующий метод, например: &СравнитьНаМеньше. Обратите внимание на разницу в написании имени функционального типа и лямбда-выражении: В имени функционального типа не рекомендуется обрамлять пробелами лямбда-операцию ->: (Число)->Число (Число) -> Число //Правильно //Неправильно В лямбда-выражении, наоборот, рекомендуется обрамлять пробелами лямбда-операцию ->: x -> x + 1 x->x + 1 //Правильно //Неправильно Лямбда-выражения Лямбда-выражение состоит из параметров, лямбда-операции -> и тела лямбда-выражения. Например: Операнд -> Операнд + 1 (ПервыйПараметр, ВторойПараметр) -> ПервыйПараметр * ВторойПараметр Лямбда-выражение – это анонимная функция, то есть для нее не требуется указывать имя, и в системе она не привязана к идентификатору. Анонимность и компактность лямбда-выражений позволяют записывать весь метод целиком (и параметры, и результат) непосредственно в список параметров другого метода или в тело другого метода как возвращаемое значение. 101 «1С:Предприятие.Элемент». Возможности встроенного языка Например: пер Результат = СравнитьСтроки(ПерваяСтрока, ВтораяСтрока, (Строка1, Строка2) -> Строка1.Длина() < Строка2.Длина()) метод СравнитьСтроки(Стр1: Строка, Стр2: Строка, Рез: (Строка, Строка)->Булево) ; Ссылки на методы Значение функционального типа также можно записать в виде ссылки на существующий метод. Такая ссылка состоит из символа & (амперсанд), названия метода и аргументов, например: Скрипт(1, 5, &МойМетод) метод МойМетод(Пар1: Число, Пар2: Строка) ; метод Скрипт(Пар1: Число, Пар2: Число, Пар3: (Число, Строка)->ничего) ; Ссылка на метод может передаваться как переменная, параметр или возвращаемое значение. Ссылка на метод также может ссылаться на лямбда-выражение, если этому лямбда-выражению было присвоено имя. Примеры использования функциональных типов Хранение метода в переменной Значение функционального типа можно присвоить переменной и использовать его в дальнейшем. Например, это может быть лямбдавыражение, преобразующее полученную строку в верхний регистр. В следующем примере в переменной МетодСтрокаПрописью сохраняется значение метода ВВерхнийРегистр(): знч МетодСтрокаПрописью = (СтрокаТекста: Строка) -> СтрокаТекста.ВВерхнийРегистр() После этого можно использовать переменную МетодСтрокаПрописью, которая вернет значение метода ВВерхнийРегистр() для строки «моя строка»: пер СтрокаПрописью = МетодСтрокаПрописью("моя строка") 102 Глава 3. Операции, инструкции, типы Таким образом, переменная СтрокаПрописью будет содержать строку «МОЯ СТРОКА». Также это может быть ссылка на метод, в данном случае на метод ПреобразоватьСтроку, который возвращает значение метода ВВерхнийРегистр() для полученной строки: знч МетодСтрокаПрописью = &ПреобразоватьСтроку пер СтрокаПрописью = МетодСтрокаПрописью("моя строка") метод ПреобразоватьСтроку(СтрокаТекста: Строка): Строка возврат СтрокаТекста.ВВерхнийРегистр() ; Таким образом, переменная СтрокаПрописью будет содержать строку «МОЯ СТРОКА». Ссылка на системный метод Вы можете ссылаться не только на собственные методы, но и на системные. Например, можно сослаться на метод Строка.ВВерхнийРегистр(): знч МетодСтрокаПрописью = &Строка.ВВерхнийРегистр пер СтрокаПрописью = МетодСтрокаПрописью("моя строка") Таким образом, переменная СтрокаПрописью будет содержать строку «МОЯ СТРОКА». Вызов системного метода с параметром функционального типа Некоторые системные методы имеют параметры функционального типа. Например, метод СортироватьПо() коллекции Массив имеет первый параметр функционального типа, в который вы должны передать свое лямбда-выражение. Это выражение должно вернуть то свойство элемента массива, по которому массив нужно отсортировать. Например, массив структур Сотрудники, состоящий из элементов структуры Сотрудник, сортируется по полю Возраст этой структуры: структура Сотрудник знч ФИО: Строка знч Возраст: Число ; 103 «1С:Предприятие.Элемент». Возможности встроенного языка метод Пример() знч Сотрудники = [новый Сотрудник("Стрельцов",44), новый Сотрудник("Малахова", 22), новый Сотрудник("Королев",33)] Сотрудники.СортироватьПо(ПарамСотрудник->ПарамСотрудник.Возраст) ; Передача метода в другой метод Допустим, в разных методах вашего алгоритма есть необходимость каким-то образом сравнить два переданных числа. В методе Пример() нужно узнать, делится ли первое число на второе без остатка. В другом методе, например, нужно просто узнать, какое из чисел больше. Для выполнения такой задачи вы можете во всех случаях сравнения двух чисел вызывать один и тот же собственный метод СравнитьДваЧисла(). А передавать в него три аргумента: два числа и значение функционального типа, которое описывает тот алгоритм сравнения, который вам нужен в конкретном случае. Это можно сделать с помощью лямбда-выражения или с помощью ссылки на метод. Использование лямбда-выражения метод Пример(Делимое: Число, Делитель: Число) ; пер Результат = СравнитьДваЧисла(Делимое, Делитель, (Число1, Число2) -> Число1%Число2 == 0) метод СравнитьДваЧисла(Делимое: Число, Делитель: Число, Разделить: (Число, Число)->Булево): Булево ; возврат Разделить(Делимое, Делитель) Здесь в вызове метода СравнитьДваЧисла() написано лямбда-выражение: (Число1, Число2) -> Число1%Число2 > 0 Оно означает, что передается метод с двумя параметрами. Этот метод определяет остаток от деления первого числа на второе и сравнивает его с нулем. 104 Глава 3. Операции, инструкции, типы В объявлении метода СравнитьДваЧисла() указано, что его третий параметр имеет функциональный тип: Разделить: (Число, Число)->Булево Имя этого параметра – Разделить, в него будет передан метод, который принимает два параметра типа Число и возвращает значение типа Булево. В теле метода СравнитьДваЧисла() написан вызов значения функционального типа: Разделить(Делимое, Делитель) Это вызывается метод, переданный в третьем параметре Разделить. Ему передаются два числа, которые пришли в метод в первом и втором параметрах. Использование ссылки на метод Вместо лямбда-выражений можно использовать ссылки на существующие методы. Например, если алгоритм сравнения уже описан в методе ОстатокОтДеления(), то вместо лямбда-выражения можно использовать ссылку на этот существующий метод. метод Пример(Делимое: Число, Делитель: Число) ; пер Результат = СравнитьДваЧисла(Делимое, Делитель, &ОстатокОтДеления) метод ОстатокОтДеления(Число1: Число, Число2: Число): Булево возврат Число1%Число2 == 0 ; метод СравнитьДваЧисла(Делимое: Число, Делитель: Число, Разделить: (Число, Число)->Булево): Булево ; возврат Разделить(Делимое, Делитель) Чтобы написать ссылку на метод, перед именем метода нужно поставить амперсанд &. Рекомендации при написании кода Если тело лямбды однострочное, то лучше использовать синтаксис лямбды выражения (тело лямбды является выражением): знч Результат = (ПарСтрока: Строка) -> ПарСтрока.Длина() 105 «1С:Предприятие.Элемент». Возможности встроенного языка Если тело лямбды содержит от двух до пяти строк, то лучше использовать синтаксис лямбды инструкции (тело лямбды является последовательностью инструкций): знч Результат = метод(ТекущийДеньНедели: ДеньНедели) -> выбор ТекущийДеньНедели когда Суббота, Воскресенье возврат "Сегодня выходной" ; ; Если тело лямбды больше пяти строк, то лучше записывать тело лямбды как метод и использовать ссылку на этот метод: знч Результат = &ОписаниеДня метод ОписаниеДня(ТекущийДеньНедели: ДеньНедели): Строка пер СообщениеДня: Строка выбор ТекущийДеньНедели когда Суббота, Воскресенье СообщениеДня = "Сегодня выходной" когда Пятница СообщениеДня = "Сегодня предвыходной день" иначе СообщениеДня = "Сегодня будний день" ; возврат СообщениеДня ; Регулярные выражения В языке «1С:Предприятия» не поддерживалась работа с регулярными выражениями. Теперь в языке «Элемента» можно использовать так называемые образцы, созданные на основе регулярных выражений, и применять их к различным строкам. Таким образом, для этих строк можно находить совпадения с образцом, разделять их на части, заменять символы в строке в соответствии с образцом и т. д. Для решения различных задач, использующих регулярные выражения, в языке «Элемента» используются типы Образец и Совпадение. Для простых случаев у типа Строка существуют методы Содержит(), Разделить() и т. д. Ниже они будут рассмотрены на конкретных примерах. 106 Глава 3. Операции, инструкции, типы Кроме того, использование регулярных выражений поддерживается в языке запросов. ПОДРОБНЕЕ Синтакс-помощник: https://1cmycloud.com/console/help/executor/2.0/api/executor/ru/Std/RegularExpressions/ Образец Тип Образец предназначен для описания собственно самих регулярных выражений. Экземпляр этого типа можно создать с помощью литерала или конструктора. Например: // Создание регулярного выражения с помощью литерала пер РегВыр1 = ‘(\ц{2}-){2}’ // Создание регулярного выражения с помощью конструктора пер РегВыр2 = новый Образец("(\\ц{2}-){2}") При использовании литерала строка, задающая конкретный образец, заключается в одинарные кавычки и содержит специальные конструкции, приведенные ниже. Экранирование в литерале выполняется с помощью символа «\» (обратный слеш). Экранировать необходимо только сам обратный слеш («\») и одинарную кавычку «'». При использовании конструктора образец создается из строки, содержащей регулярное выражение и заключенной в двойные кавычки. Чтобы записать в строку, из которой создается регулярное выражение, обратный слеш «\», его необходимо экранировать с помощью еще одного символа «\». пер РегВыр = новый Образец("(\\ц{2}-){2}") пер СтрокаОбразца = РегВыр.ВСтроку() //СтрокаОбразца = (\ц{2}-){2} В обоих случаях при создании образца в случае некорректности регулярного выражения выбрасывается исключение ИсключениеНекорректноеРегулярноеВыражение. 107 «1С:Предприятие.Элемент». Возможности встроенного языка Для создания регулярного выражения могут использоваться следующие конструкции: ■■ Символы: ○○ х – символ х; ○○ \ – символ обратной косой черты; ○○ \юhhhhh – код символа в Юникод с десятеричным значением hhhhh; ○○ \т – символ табуляции; ○○ \н – символ перевода строки; ○○ \в – символ возврата каретки. ■■ Классы символов: ○○ [абв] – «а», «б» или «в». Содержимое внутри квадратных скобок не должно быть пустым ([] – запрещено); ○○ [^абв] – любой символ, кроме «а», «б» или «в» (отрицание). Содержимое внутри квадратных скобок не должно быть пустым ([^] – запрещено); ○○ [а-яА-я] – символы в диапазоне от «а» до «я» или от «А» до «Я» (диапазоны). Содержимое внутри квадратных скобок не должно быть пустым ([] – запрещено). ■■ Заранее обозначенные символьные классы: ○○ . – любой символ, кроме терминаторов строк; ○○ \ц – какая-либо цифра: [0-9]; ○○ \Ц – не цифра; ○○ \п – пробельный символ; ○○ \П – не пробельный символ; ○○ \с – символ, допустимый в словах; ○○ \С – символы, не участвующие в словах. ■■ Символы соответствия границ: ○○ ^ – начало строки; ○○ $ – конец строки. ■■ Жадные квантификаторы (находят совпадения максимально возможной длины), X – некоторая исчисляемая конструкция: ○○ X? – X встречается один раз или не встречается вообще; 108 Глава 3. Операции, инструкции, типы ○○ X* – X ноль или больше раз; ○○ X+ – X один или больше раз; ○○ X{n} – X ровно n раз; ○○ X{n,} – X хотя бы n раз; ○○ X{n,m} – X хотя бы n, но не более m раз. ■■ Ленивые квантификаторы (находят совпадения минимально возможной длины), X – некоторая исчисляемая конструкция: ○○ X?? – X встречается один раз или не встречается вообще; ○○ X*? – X ноль или больше раз; ○○ X+? – X один или больше раз; ○○ X{n}? – X ровно n раз; ○○ X{n,}? – X хотя бы n раз; ○○ X{n,m}? – X хотя бы n, но не более m раз. ■■ Логические операции (X, Y – некоторая конструкция или набор конструкций): ○○ XY – X обязан следовать за Y; ○○ X|Y – либо X, либо Y (предпочтительнее X); ○○ (X) – X в качестве группы захвата. ■■ Обратные ссылки: ○○ \n – то же соответствие, что было найдено группой захвата с номером n; ○○ \и<имя> – то же соответствие, что было найдено группой захвата с именем <имя>. ■■ Экранирование: ○○ \ – экранирует следующий символ. ■■ Специальные конструкции (X – некоторая конструкция или набор конструкций): ○○ (?<имя>X) – X как именованная группа захвата с именем <имя>; ○○ (?:X) – X как не группа захвата; ○○ (?=X) – X как проверка присутствия с просмотром вперед; ○○ (?!X) – X как проверка отсутствия с просмотром вперед; ○○ (?рмо) – указывается только в конце регулярного выражения. Включает флаги-настройки поиска. 109 «1С:Предприятие.Элемент». Возможности встроенного языка Флаги-настройки поиска: ■■ р – включает режим регистронезависимого поиска. То есть при выполнении операций поиска, замены, разбиения регистр символов игнорируется; ■■ м – многострочный режим. Изменяет значение символов “^” и “$” так, что они совпадают, соответственно, с началом и концом любой строки, а не только с началом и концом всего текста; ■■ о – указывает однострочный режим. Изменяет значение точки (.) так, что она соответствует любому символу (вместо любого символа, кроме терминаторов строк). Совпадение Экземпляр типа Совпадение предназначен для хранения результатов поиска соответствий подстрок некоторому образцу. Он представляет собой описание подстроки-совпадения, полученной в результате применения некоторого образца к некоторой строке. Примеры использования регулярных выражений Существует множество задач, где могут использоваться регулярные выражения. Это и проверка строк на соответствие шаблонам (телефонные номера, электронная почта, номера договоров и т. п.), и сложный поиск в тексте документов, парсинг документов на соответствие требуемым шаблонам, и многое другое. Ниже будут рассмотрены небольшие простые примеры использования регулярных выражений. Пример 1 Допустим, вам нужно найти в некоторой строке все буквенные или цифровые символы. Для этого используется метод Образец.НайтиСовпадения(). Этот метод позволяет найти указанное количество или все совпадения с образцом в строке, указанной как аргумент метода. Метод возвращает массив совпадений – Массив<Совпадение>. 110 Глава 3. Операции, инструкции, типы Например, в переменной Данные содержится исходная строка «логин!3пароль1*27», а само регулярное выражение РегВыр задано с помощью литерала '\с+' (один или больше символов, допустимых в словах). Тогда в массиве совпадений будут находиться значения: «логин», «3пароль1», «27»: пер Данные = "логин!3пароль1*27" пер РегВыр = ‘\с+’ пер Совпадения = РегВыр.НайтиСовпадения(Данные) для ОчередноеСовпадение из Совпадения ПодСтрока = ОчередноеСовпадение.Значение() ; Для регулярного выражения '\С+' (один или больше символов, недопустимых в словах) будут найдены совпадения: «!», «*»: пер Данные = "логин!3пароль1*27" пер РегВыр = ‘\С+’ пер Совпадения = РегВыр.НайтиСовпадения(Данные) для ОчередноеСовпадение из Совпадения ПодСтрока = ОчередноеСовпадение.Значение() ; Для регулярного выражения '\ц+' (один или больше цифровых символов) будут найдены совпадения: «3», «1», «27»: пер Данные = "логин!3пароль1*27" пер РегВыр = ‘\ц+’ пер Совпадения = РегВыр.НайтиСовпадения(Данные) для ОчередноеСовпадение из Совпадения ПодСтрока = ОчередноеСовпадение.Значение() ; Пример 2 Другая распространенная задача – проверка того, что заданный строкой номер телефона соответствует некоторому образцу. Для этого используется метод Строка.ПолноеСовпадение(). Этот метод проверяет, подходит ли исходная строка под регулярное выражение (Образец), которое указывается в качестве аргумента метода. В результате возвращается Истина или Ложь. 111 «1С:Предприятие.Элемент». Возможности встроенного языка Например, в следующем примере проверяется, что номер телефона должен соответствовать образцу +7(XXX)XXX-XX-XX, где X – любая цифра от 0 до 9: пер Телефон1 = "+7(495)688-90-02" пер Телефон2 = "8 495 688 90 02" пер ОбразецТелефона = ‘\+7\(\ц{3}\)\ц{3}(-\ц{2}){2}’ пер Совпадает = Телефон1.ПолноеСовпадение(ОбразецТелефона) Совпадает = Телефон2.ПолноеСовпадение(ОбразецТелефона) // Истина // Ложь В результате под образец подходит первый вариант написания номера телефона (Телефон1). Ниже проверяется, что номер телефона должен соответствовать образцу 8 XXX XXX XX XX, где X – любая цифра от 0 до 9: пер Телефон1 = "+7(495)688-90-02" пер Телефон2 = "8 495 688 90 02" пер ОбразецТелефона = ‘8(\п\ц{3}){2}(\п\ц{2}){2}’ пер Совпадает = Телефон1.ПолноеСовпадение(ОбразецТелефона) Совпадает = Телефон2.ПолноеСовпадение(ОбразецТелефона) // Ложь // Истина В результате под образец подходит второй вариант написания номера телефона (Телефон2). Пример 3 Чтобы разбить строку по разделителям, содержащимся в регулярном выражении, используется метод Строка.Разделить(). Этот метод разделяет строку на части по подстрокам, удовлетворяющим образцу (Образец), который указывается в качестве аргумента метода. В результате возвращается массив полученных частей, исключая разделители. В следующем примере исходная строка разбивается на слова по разделителям ' ', ',', '.', '!', '?', учитывая, что между словами может стоять несколько разделителей сразу: пер ИсхСтрока = "Быть или не быть, вот в чём вопрос..." пер Разбиения = ИсхСтрока.Разделить(‘([ ,.!?]+)’) В результате массив строк Разбиения содержит элементы: «Быть», «или», «не», «быть», «вот», «в», «чем», «вопрос». 112 Глава 3. Операции, инструкции, типы Пример 4 Чтобы заменить в строке символы, соответствующие регулярному выражению Образец, используется метод Строка.Заменить(). Первым аргументом в метод передается образец, а вторым – строка замены. В строке замены могут содержаться ссылки на группы захвата, обозначенные в образце. Каждая ссылка вида $\<Имя\> (имя группы захвата) или $g (номер группы захвата) будут заменены на последнее совпадение (подстроку), найденное группой захвата с таким именем или номером. В следующем примере все вхождения подстроки «завтра» будут заменены на «послезавтра». $1 вставляет в строку замены первую и единственную группу захвата, содержащую подстроку «завтра»: пер ИсхСтрока = "Если наступит завтра, то завтра будет лучше, чем вчера." пер Результат = ИсхСтрока.Заменить(‘(завтра)’, "после$1") В результате метод вернет строку «Если наступит послезавтра, то послезавтра будет лучше, чем вчера.». Пример 5 Существует также перегрузка этого метода: Заменить(Образец: Образец, Заменитель: (Совпадение)->Строка, КоличествоЗамен: Число = 0): Строка. Второй параметр этого метода Заменитель имеет функциональный тип – в него передается метод Группа() типа Совпадение, который возвращает самую правую подстроку, захваченную группой с именем, переданным в этот метод: пер Заменитель = (ОчередноеСовпадение: Совпадение) -> ОчередноеСовпадение.Группа("замена").ВСтроку() пер ИсхСтрока = "один:1 + два:2 = три:3" пер Результат = ИсхСтрока.Заменить(‘(\с+):(?<замена>\ц)’, Заменитель) В результате исходная строка «один:1 + два:2 = три:3» будет заменена строкой «1 + 2 = 3». 113 «1С:Предприятие.Элемент». Возможности встроенного языка 114 ГЛАВА 4 Создание прикладных решений в «Элементе» 115 «1С:Предприятие.Элемент». Возможности встроенного языка Ключевое слово «этот» В языке «1С:Предприятия» существовали свойство объекта ЭтотОбъект и свойство формы ЭтаФорма. Они возвращали объект или форму для передачи их в качестве параметра в другие формы, глобальные процедуры и функции и т. д. Теперь в языке «Элемента» есть ключевое слово этот. Оно возвращает объект, к которому относится модуль, и явно квалифицирует обращение к контексту объекта. Есть две ситуации, когда удобно использовать этот. Во-первых, если имя параметра метода совпадает со свойством контекста модуля. Тогда, обращаясь к свойству модуля через этот, можно избежать неоднозначности: метод УстановитьИмя(Имя: Строка) этот.Имя = Имя ; Во-вторых, когда контекст модуля нужно передать в другой, универсальный метод. Например, в общем модуле есть метод, который определенным одинаковым образом проверяет любые элементы справочников: @проект метод ПроверитьЭлемент(КонтекстЭлемента: Справочник.Объект) ; Тогда в модуле элемента справочника можно передать его на проверку в этот метод: метод ПередЗаписью(До: Товары.Данные) ОбщийМодульСервер.ПроверитьЭлемент(этот) ; Аннотации В языке «1С:Предприятия» существовали аннотации &Перед, &Вместо, &После. Они определяли в расширении способ перехвата методов типовой конфигурации. Теперь в языке «Элемента» аннотации используются гораздо шире. Аннотация – это способ добавить к языковой конструкции инфор- 116 Глава 4. Создание прикладных решений в «Элементе» мацию, которую могут использовать другие механизмы технологии «1С:Предприятие.Элемент». Аннотация начинается с символа @, за которым следует имя аннотации, например: @Клиент метод Тест() ; Если к языковой конструкции применяется сразу несколько аннотаций, то все они пишутся в одной строке через пробел. Например: @проект @Сервер @ДоступноСКлиента статический метод МойМетод() ; Аннотации видимости Аннотации видимости в языке «Элемента» определяют, в какой области видна переменная, константа, метод, перечисление, структура или исключение: ■■ @локально – конструкция видна только в своем модуле. Это значение по умолчанию; ■■ @подсистема – конструкция видна только в подсистеме, которой принадлежит модуль; ■■ @проект – конструкция видна только в проекте, которому принадлежит модуль; ■■ @глобально – конструкция видна в других проектах. Например: @глобально статический метод ПолучитьОписание(): Строка возврат "ОК" ; @подсистема конст ПЛОЩАДЬ = 123 @проект перечисление Срочность Высокая, Обычная, Низкая ; 117 «1С:Предприятие.Элемент». Возможности встроенного языка @глобально исключение ИсключениеПриЧтенииФайла пер ИмяФайла: Строка ; @проект структура Товар знч Наименование: Строка пер Артикул: Строка пер Цена: Число ; ПОДРОБНЕЕ Об аннотациях видимости рассказывается в разделе «Модульная разработка». Если языковая конструкция описана с аннотацией @проект или @глобально, то ее можно использовать в других модулях, указав перед именем конструкции имя того модуля, где она была объявлена. Например: пер Площадь = МойМодуль.ПЛОЩАДЬ пер Срочность = МойМодуль.Срочность.Высокая пер Товар2 = новый МойМодуль.Товар("Пылесос", "222", 1000) пер Искл = новый МойМодуль.ИсключениеПриЧтенииФайла("ошибка чтения", " C:\\test\\test.txt") Без аннотации видимости языковая конструкция будет доступна только в том модуле, в котором она объявлена, и к ней можно обращаться просто по имени. Аннотации окружения Аннотации окружения в языке «Элемента» определяют, в каком программном окружении исполняются метод, структура, исключение, перечисление или константа: ■■ @Клиент. Метод или тип с такой аннотацией доступен на клиенте. При вызове с клиента метод исполняется на клиенте; ■■ @Сервер. Метод или тип с такой аннотацией доступен на сервере. При вызове с сервера метод исполняется на сервере. Эта аннотация может быть использована в паре с аннотацией 118 Глава 4. Создание прикладных решений в «Элементе» @ДоступноСКлиента, в таком случае метод исполняется на сервере, но доступен для вызова с клиента (т. е. присутствует и в клиентском, и в серверном окружениях); ■■ @ДоступноСКлиента. Эта аннотация доступности серверного метода для вызова с клиента. Может быть использована только в паре с аннотацией @Сервер. В таком случае метод исполняется на сервере, но доступен для вызова с клиента, т. е. присутствует и в клиентском, и в серверном окружениях. ПОДРОБНЕЕ Об аннотациях окружения рассказывается в разделе «Исполнение модуля». Аннотация «ИменованныеПараметры» Перед описанием метода или конструктора вы можете использовать аннотацию @ИменованныеПараметры. Это значит, что запрещается вызывать метод с позиционными аргументами (допускаются только именованные аргументы). Например: метод МойМетод() Тест(Параметр = 123) ; @ИменованныеПараметры метод Тест(Параметр: Число) ; ПОДРОБНЕЕ Об именованных параметрах рассказывается в разделе «Позиционные и именованные аргументы». Аннотация «ВыполнятьПриЗагрузкеДанных» Аннотация @ВыполнятьПриЗагрузкеДанных может быть назначена методам-обработчикам событий. Если обработчик помечен такой аннотацией, он выполняется в режиме загрузки. Непомеченные обработчики не выполняются в режиме загрузки при обмене данными. 119 «1С:Предприятие.Элемент». Возможности встроенного языка Например, метод ПриЗаписи() будет выполняться в режиме загрузки, а метод ПередЗаписью() – нет: @ВыполнятьПриЗагрузкеДанных метод ПриЗаписи() // Нужные действия выполняются в любом случае // … ; если не ОбменДанными.Загрузка ОтправитьУведомления(); ; метод ПередЗаписью() // Обработчик не будет выполняться в режиме загрузки // … ; ПОДРОБНЕЕ О режиме загрузки данных рассказывается в разделе «Загрузка данных». Модульная разработка В языке «1С:Предприятия» не было понятия «пространство имен», все типы, порождаемые конфигурацией, находились в одном «пространстве имен». Теперь в технологии «1С:Предприятие.Элемент» понятию конфигурации соответствует проект. Проект в функциональном смысле разделен на подсистемы и пакеты. Подсистемы создают верхний уровень функциональности, они не могут быть вложены друг в друга. Внутри подсистемы могут находиться пакеты, которые могут быть вложены друг в друга. Каждая подсистема или пакет создает собственное пространство имен. Элементы проекта находятся уже внутри этого пространства. Каждый элемент проекта имеет один или несколько модулей. Стандартно элементам из одной подсистемы не видны элементы из другой подсистемы. Чтобы элементы (языковые конструкции) одной подсистемы использовать в другой подсистеме, нужно настроить их видимость 120 Глава 4. Создание прикладных решений в «Элементе» на уровне проекта или глобально (описать с аннотациями @проект или @глобально). Затем нужно в другой подсистеме указать, что она использует первую подсистему, то есть в описании подсистемы указать имя первой подсистемы в свойстве Использование. После этого можно обращаться к элементам (языковым конструкциям) по квалифицированному имени (см. раздел «Квалифицированное имя элемента»). Или же можно импортировать пространство имен одной подсистемы в ту подсистему, где вы хотите использовать эти элементы (языковые конструкции). После этого можно обращаться к ним по неквалифицированному имени (см. раздел «Импорт пространств имен»). Видимость языковых конструкций Область видимости переменных, констант, методов, перечислений, структур, исключений можно задать с помощью аннотаций видимости, помещенных в модулях перед объявлением этих языковых конструкций: ■■ @локально – конструкция видна только в своем модуле. Это значение по умолчанию; ■■ @подсистема – конструкция видна только в подсистеме, которой принадлежит модуль; ■■ @проект – конструкция видна только в проекте, которому принадлежит модуль; ■■ @глобально – конструкция видна в других проектах. Например: @локально конст СЕКУНД_В_ДНЕ = 60 * 60 * 24 @подсистема перечисление ВидКнопки Круглая, Квадратная ; @проект метод ПолучитьОписание(): Строка возврат новый МодульОбъекта.ОписаниеТовара() ; 121 «1С:Предприятие.Элемент». Возможности встроенного языка Квалифицированное имя элемента Все элементы проекта порождают типы встроенного языка. Помимо «обычного», неквалифицированного имени типы имеют квалифицированные имена. Квалифицированное имя типа состоит из пространства имен и «обычного» имени, разделенных символами «::» (двойным двоеточием). Типы, порождаемые элементами проекта, принадлежат пространству имен своей подсистемы и своего пакета. Например, проект включает подсистемы КонтрольДанных и Основная, подсистема КонтрольДанных содержит пакет и справочник СправочникСотрудники, а подсистема Основная содержит модуль ОбщийМодуль и справочник СправочникТовары. Пакет, в свою очередь, включает справочник СправочникВалюты (рис. 4.1): Рис. 4.1. Структура проекта Тогда квалифицированные имена типов, порождаемых его элементами, будут выглядеть следующим образом: ■■ КонтрольДанных::Пакет::СправочникВалюты, ■■ КонтрольДанных::СправочникСотрудники, ■■ Основная::ОбщийМодуль, ■■ Основная::СправочникТовары. Нужно помнить, что в одном пространстве имен (в одной подсистеме или в одном пакете) не может быть двух элементов с одинаковыми именами. При обращении к методам элементов проекта также используются их квалифицированные имена. Например, у элементов проекта СправочникВалюты и СправочникСотрудники есть модули объекта 122 Глава 4. Создание прикладных решений в «Элементе» и менеджера, в которых определены публичные (описанные аннотациями @проект или @глобально) методы: @проект метод Метод_Менеджера() ; @проект метод Метод_Объекта() ; Пусть в рассмотренном выше проекте (см. рис. 4.1) подсистема Основная использует подсистему КонтрольДанных. То есть в описании подсистемы Основная в свойстве Использование указано: Использование: [ КонтрольДанных ]. Тогда в общем модуле ОбщийМодуль обращение к данным справочников СправочникСотрудники и СправочникВалюты может выглядеть следующим образом: @проект метод Пример1() пер Сотрудник1 = новый КонтрольДанных::СправочникСотрудники.Объект() // Обращение к атрибуту справочника Сотрудник1.Код = "0" // Вызов публичного метода элемента справочника Сотрудник1.Метод_Объекта() ; // Вызов публичного метода менеджера справочника КонтрольДанных::СправочникСотрудники.Метод_Менеджера() @проект метод Пример2() пер Валюта1 = новый КонтрольДанных::Пакет::СправочникВалюты.Объект() // Обращение к атрибуту справочника Валюта1.Код = "0" // вызов публичного метода элемента справочника Валюта1.Метод_Объекта() ; // вызов публичного метода менеджера справочника КонтрольДанных::Пакет::СправочникВалюты.Метод_Менеджера() 123 «1С:Предприятие.Элемент». Возможности встроенного языка Импорт пространств имен В любые элементы проекта и в модули можно импортировать другие пространства имен. В элементе проекта они перечисляются в свойстве Импорт, а в модуле для этого используется инструкция импорт. Например: импорт ОбщиеСтандартные импорт ПодключаемыеСтандартные импорт УведомленияСтандартные импорт ПриложениеОбщее метод ПередЗаписью() ... ; Публичные элементы проекта и конструкции языка (описанные аннотациями @проект или @глобально) из импортированных пространств вы можете использовать по неквалифицированному имени – как будто это «ваши собственные» элементы из этой же подсистемы. Импорт, выполненный в элементе проекта, не влияет на его модули. То есть пространства имен, импортированные в элемент проекта, не становятся автоматически доступны в модулях этого элемента. Если эти же пространства имен нужны вам и в модулях, то в каждый модуль их нужно импортировать отдельно. Исполнение модуля В языке «1С:Предприятия» использовались директивы компиляции &НаКлиенте, &НаСервере, &НаКлиентеНаСервереБезКонтекста, &НаКлиентеНаСервере, чтобы указать, в каком окружении будет исполняться тот или иной модуль. Теперь в языке «Элемента» аннотации окружения выполняют те же функции, но состав аннотаций отличается. Модуль существует в том же окружении, что и тип, к которому относится модуль: на клиенте, на сервере или и на клиенте, и на сервере. Однако методы и типы, объявленные в модуле, могут существовать и исполняться в разных окружениях. 124 Глава 4. Создание прикладных решений в «Элементе» Есть стандартные окружения, в которых существуют типы и исполняются методы модуля. Они используются тогда, когда окружение не указано в явном виде. Окружения зависят от вида элемента проекта: ■■ HttpСервис – все методы этого типа исполняются на сервере; ■■ КлючДоступа – все методы этого типа исполняются на сервере; ■■ Пользователи – все методы этого типа исполняются на сервере; ■■ ПроцессИнтеграции – все методы этого типа исполняются на сервере; ■■ РегистрСведений – все методы этого типа исполняются на сервере; ■■ Справочник – все методы этого типа исполняются на сервере; ■■ ОбщийМодуль – окружение типа такое же, как у элемента проекта, которому принадлежит общий модуль; ■■ Структура – окружение типа такое же, как у элемента проекта, которому принадлежит структура; ■■ КомпонентИнтерфейса – все методы этого типа исполняются на клиенте; ■■ НавигационнаяКоманда – все методы этого типа исполняются на клиенте; ■■ ОбычнаяКоманда – все методы этого типа исполняются на клиенте; ■■ ПереключаемаяКоманда – все методы этого типа исполняются на клиенте; ■■ Перечисление – все методы этого типа исполняются и на клиенте, и на сервере; ■■ ХранимаяСтруктура – все методы этого типа исполняются на клиенте. Наряду с этим окружение для метода, структуры, исключения, перечисления, константы можно задать в явном виде с помощью аннотаций окружения: ■■ @Клиент, ■■ @Сервер, ■■ @ДоступноСКлиента. 125 «1С:Предприятие.Элемент». Возможности встроенного языка Аннотации окружения работают следующим образом: ■■ Если тип существует и на клиенте, и на сервере, то при описании языковых конструкций можно использовать следующие аннотации окружения: ○○ @Сервер. При этом метод (тип) доступен на сервере. Метод исполняется на сервере. ○○ @Клиент. При этом метод (тип) доступен на клиенте. Метод исполняется на клиенте. ○○ @Сервер @Клиент. При этом метод (тип) доступен и на клиенте, и на сервере. Если метод вызывается с клиента, то он исполняется на клиенте. Если метод вызывается с сервера, то он исполняется на сервере. ○○ @Сервер @ДоступноСКлиента. При этом метод (тип) доступен и на клиенте, и на сервере. Метод исполняется на сервере, а вызвать его можно как с сервера, так и с клиента. ■■ Если тип существует на клиенте, то при описании языковых конструкций можно использовать те же аннотации, что и для предыдущего случая. Разница только в методах, имеющих аннотацию @Сервер. Они не имеют доступа к экземпляру, то есть у них нет контекста экземпляра и недоступно обращение с помощью ключевого слова этот. ■■ Если тип существует на сервере, то при описании языковых конструкций можно использовать только одну аннотацию – @Сервер. Однако это окружение является стандартным для таких модулей, поэтому эту аннотацию можно не указывать. Статические методы элементов проекта Статический метод – это метод, общий для всего типа. Для его обозначения используется ключевое слово статический. Статические методы не могут использовать контекст элемента проекта и обращение с помощью ключевого слова этот. Статические методы необходимо использовать в том случае, когда нужно передать исполнение кода с клиента на сервер. Аннотация @ДоступноСКлиента допускается только на статических методах. 126 Глава 4. Создание прикладных решений в «Элементе» Статические методы можно использовать в тех элементах проекта, которые не имеют типов-одиночек, например: в модуле элемента перечисления, в модуле компонента интерфейса, в модуле структуры. Статический метод может быть вызван из модуля типа без квалификатора типа. Из статического метода нельзя вызывать обычные методы в данном модуле. Если тип существует в клиентском окружении, то все его серверные методы должны быть статическими. Передача исполнения с клиента на сервер В процессе работы приложения возникает необходимость получить информацию, которая недоступна на клиенте (допустим, нужно прочитать данные, содержащиеся в базе данных). Например, при работе с компонентами пользовательского интерфейса вы можете добавить в модуль компонента (который стандартно существует в окружении Клиент) статический метод с аннотациями @Сервер @ДоступноСКлиента. И затем просто вызвать этот метод из клиентского метода, например из обработчика события. При этом исполнение встроенного языка передается на сервер, выполняется вызываемый метод, а затем исполнение возвращается на клиент. Например, в модуле компонента вызывается серверный статический метод ДанныеДляСписка(): метод ПослеСоздания() ДанныеДляСписка = ДанныеДляСписка() ... ; @Сервер @ДоступноСКлиента статический метод ДанныеДляСписка(): ПолнаяИнформация ... возврат ПолнаяИнформация ; 127 «1С:Предприятие.Элемент». Возможности встроенного языка Запросы В языке «1С:Предприятия» существовал язык запросов, однако текст запроса задавался в виде строки, поэтому узнать, какие поля каких типов будут в результате, было нельзя. Из-за этого могли возникнуть ошибки во время выполнения запроса. Теперь в языке «Элемента» запрос можно задать с помощью литерала, который позволяет на этапе компиляции знать, какие колонки каких типов будут в результате, а значит, сокращает количество потенциальных ошибок. Параметры передаются в литерал запроса в виде выражения, написанного прямо в литерале. Использование литерала запроса Литерал запроса выглядит следующим образом: пер Запрос = Запрос{ВЫБРАТЬ Сотрудники.Ссылка КАК Ссылка, Сотрудники.ФИО КАК ФИО ИЗ Сотрудники КАК Сотрудники} Весь текст запроса пишется в фигурных скобках. При использовании литерала переменная Запрос имеет тип ТипизированныйЗапрос<тип-строки-результата-запроса> . Это запрос на выборку данных, порождаемый литералом. Тип-строки-результата-запроса – это синтетическое имя типа строки результата запроса, которое порождает технология «1С:Предпритяие. Элемент». Например, это может быть строка вроде: Приложение. СтрокаРезультатаЗапроса$19$18. К такому типу нельзя обращаться по имени, но можно использовать его значения в пределах модуля, содержащего литерал запроса. Если запрос с литералом не выбирает данные, то его тип будет ЗапросБезВыборки. 128 Глава 4. Создание прикладных решений в «Элементе» Обход результата запроса Чтобы выполнить запрос, используется метод Выполнить(). Он возвращает значение обобщенного типа РезультатЗапроса<типстроки-результата-запроса>. Этот тип является производным от типа Обходимое<тип-строки-результата-запроса>, поэтому результат запроса сразу же можно использовать в цикле для ... из. Например: // Задать текст запроса. пер Запрос = Запрос{ВЫБРАТЬ Сотрудники.Ссылка КАК Ссылка, Сотрудники.ФИО КАК ФИО ИЗ Сотрудники КАК Сотрудники} // Обойти результат запроса и обработать его. для СтрокаРезультата из Запрос.Выполнить() пер СотрудникСсылка = СтрокаРезультата.Ссылка пер СотрудникФИО = СтрокаРезультата.ФИО ; В этом цикле будут выдаваться строки запроса в порядке получения их из базы данных, то есть в том порядке, который указан в тексте запроса. Переменная СтрокаРезультата будет иметь тип тип-строки-результата-запроса. Явное указание типа строки Если вы хотите обрабатывать результат запроса в другом методе, то вам понадобится заранее знать тип строки результата запроса, чтобы написать вызов другого метода. Однако тип-строки-результата-запроса становится известен только после выполнения запроса. ДругойМетод(РезультатЗапроса<тип-строки-результата-запроса>) Чтобы выйти из этой ситуации, можно явно задать имя типа строки результата запроса. Для этого используется синтаксис В СТРУКТУРУ, в котором указывается нужное имя. Например: @Сервер @ДоступноСКлиента статический метод СписокСотрудников() пер Запрос = Запрос{ВЫБРАТЬ Сотрудники.Ссылка КАК Ссылка, 129 «1С:Предприятие.Элемент». Возможности встроенного языка Сотрудники.ФИО КАК ФИО В СТРУКТУРУ Сотрудник ИЗ Сотрудники КАК Сотрудники} ; // Передать результат запроса в другой метод. ДругойМетод(Запрос.Выполнить()) @Сервер статический метод ДругойМетод(РезультатЗапроса: РезультатЗапроса<Приложение.Сотрудник>) //… ; В этом примере явно задается имя типа строки результата запроса – Сотрудник. И это же имя типа используется для параметризации обобщенного типа в параметре метода ДругойМетод(). Результирующее имя типа формируется как имя типа, владеющего модулем (в котором литерал запроса), и, через точку, имя типа строки результата, указанное в запросе. Параметры запроса Параметры в литерал запроса передаются с помощью символа %. После него идет либо имя переменной, либо {выражение} (вычисляемое выражение встроенного языка). Например, нужно передать параметр Возраст. Это делается следующим образом: // Установить значения параметров запроса. пер Возраст = 40 // Задать текст запроса. пер Запрос = Запрос{ВЫБРАТЬ Сотрудники.Ссылка КАК Ссылка, Сотрудники.ФИО КАК ФИО ИЗ Сотрудники КАК Сотрудники ГДЕ Сотрудники.Возраст < %Возраст} Значения одинаковых выражений вычисляются только один раз, а не на каждое вхождение выражения в литерал. 130 Глава 4. Создание прикладных решений в «Элементе» Загрузка данных В языке «1С:Предприятия» использовалось свойство объекта и набора записей ЗагрузкаДанных, в котором существовало свойство Загрузка. Оно отключало выполнение обработчиков и проверок при записи данных, что позволяло упростить и ускорить загрузку при обмене данными. Теперь в языке «Элемента» для этих же целей реализован режим загрузки данных, в котором отключаются проверки логической целостности и отключаются обработчики событий, выполняемые при записи данных. В большинстве случаев выполнение обработчиков при загрузке данных не требуется, так как все проверки данных уже выполнены на передающей стороне. Если все нужные элементу проекта данные содержатся в пакете данных, то дополнительных проверок не требуется. Поэтому по умолчанию все обработчики в режиме загрузки данных отключаются. Но есть ряд ситуаций, при которых обработчики элементов проекта должны работать всегда. Например, когда нужно выполнить в той же транзакции регистрацию изменений по элементу. Или когда нужно положить элемент в исходящую очередь обмена данными, когда сам факт записи элемента надо зарегистрировать для дальнейшей обработки. В этих случаях обработчик, выполняющий то или иное действие, должен выполняться и в режиме загрузки данных тоже. Для этого он помечается аннотацией @ВыполнятьПриЗагрузкеДанных. Например: @ВыполнятьПриЗагрузкеДанных метод ПередЗаписью() ОперацияВыполняемаяВсегда() ; // проверяем состояние режима загрузки если не ОбменДанными.Загрузка ТолькоИнтерактивнаяОперация() ; Использование режима загрузки данных можно рассмотреть на следующем примере. Пусть в переменной МассивОписанийЗадач находятся 131 «1С:Предприятие.Элемент». Возможности встроенного языка описания задач, прочитанные из JSON-файла. По этим описаниям нужно создать элементы в справочнике Задачи: исп Загрузка = ГрупповаяОперация.Начать(РежимЗагрузкиДанных = Истина) // устанавливает режим загрузки для каждого ОписаниеЗадачи из МассивОписанийЗадач знч объектЗадача = новый Задачи.Объект() // Экземпляр объектЗадача, созданный в контексте режима загрузки, // будет иметь флаг объектЗадача.ОбменДанными.Загрузка == Истина объектЗадача.Код = ОписаниеЗадачи.id объектЗадача.Наименование = ОписаниеЗадачи.name объектЗадача.Записать() ; Загрузка.Закрыть() // завершает групповую операцию загрузки В модуле элемента справочника задачи метод ПриЗаписи() будет выполняться в режиме загрузки, а метод ПередЗаписью() – нет: @ВыполнятьПриЗагрузкеДанных метод ПриЗаписи() ВыполнитьДействияНужныеВЛюбомСлучае(); // будет выполнен всегда ; если не ОбменДанными.Загрузка ОтправитьУведомления(); // не будет выполнен в режиме загрузки ; метод ПередЗаписью() ЗдесьМногоКода() ; 132 // не будет выполнен в режиме загрузки « ООО «1С-Паблишинг», OMOO, OMOP « Оформление. ООО «1С-Паблишинг», OMOO, OMOP Все права защищены. Материалы предназначены для личного индивидуального использования приобретателем. Запрещено тиражирование, распространение материалов, предоставление доступа по сети к материалам без письменного разрешения правообладателей. Разрешено копирование фрагментов программного кода для использования в разрабатываемых прикладных решениях. Фирма «1С» 1OPM56, Москва, а/я 64, Селезневская ул., O1. Тел.: (495) TPT-9O-5T, факс: (495) 681-44-MT. [email protected], http://www.1c.ru/ Издательство ООО «1С-Паблишинг» 1OT4P4, Москва, Дмитровское ш., д. 9. Тел.: (495) 681-MO-O1, факс: (495) 681-44-MT. [email protected], http://books.1c.ru Об опечатках просьба сообщать по адресу [email protected].