Как устроены функции во встроенном языке 1С:Предприятия 8.3 и как писать свои
Содержание
Функция в 1С — это именованный блок кода на встроенном языке, который принимает параметры, выполняет действия и возвращает значение через оператор Возврат. Её объявляют между словами Функция и КонецФункции, а вызывают внутри выражения: Сумма = СуммаНДСИзСуммы(1220, 22);. Процедура устроена так же, но значения не возвращает.
Функции бывают встроенными (их даёт платформа: СтрДлина(), Формат(), НачалоМесяца()) и пользовательскими — их пишет разработчик в модулях конфигурации. Всё ниже относится к платформе 8.3 и одинаково работает в любой конфигурации: БП 3.0, ЗУП 3.1, УТ 11 или самописной.
Функция в 1С и процедура: в чём разница
Разница одна, но принципиальная: функция отдаёт результат, процедура — нет.
| Функция | Процедура | |
|---|---|---|
| Объявление | Функция … КонецФункции | Процедура … КонецПроцедуры |
| Возвращает значение | Да, через Возврат Значение; | Нет, допустим только Возврат; |
| Вызов в выражении | А = Ф(1); | Нельзя — ошибка при проверке модуля |
| Вызов отдельной строкой | Можно, результат просто теряется | Обычный способ вызова |
Несколько деталей, которые всплывают на практике:
- 🔹 Если функция дошла до
КонецФункциии не встретилаВозврат, она вернётНеопределено. Ошибки не будет, но код, который ждёт число, сломается дальше. - 🔹
Возврат;без значения внутри функции — синтаксическая ошибка. - 🔹 Функция может иметь несколько
Возврат: обычно ранний выход ставят в начале, когда входные данные пустые.
Правило выбора простое. Нужен результат — функция. Нужно только что-то сделать (записать, вывести, заполнить) — процедура. Функция, которая и меняет данные, и возвращает результат, хуже читается: такие побочные эффекты потом ищут отладчиком.
Какие бывают функции в 1С: встроенные, запросные и свои
Под словом «функции» в 1С понимают несколько разных вещей. Полезно их различать, иначе непонятно, где искать справку.
| Вид | Где живёт | Примеры |
|---|---|---|
| Встроенные функции языка | Глобальный контекст платформы | СтрДлина(), СокрЛП(), Окр(), Цел(), Формат(), ТипЗнч(), ЗначениеЗаполнено() |
| Функции языка запросов | Только внутри текста запроса | ЕСТЬNULL(), НАЧАЛОПЕРИОДА(), РАЗНОСТЬДАТ(), ПОДСТРОКА() |
| Методы объектов | Вызываются через точку | Массив.Количество(), Структура.Свойство(), Запрос.Выполнить() |
| Функции общих модулей | Модули конфигурации, библиотека БСП | ОбщегоНазначения.ЗначениеРеквизитаОбъекта() |
| Пользовательские | Любой модуль, который вы правите | Всё, что вы написали сами |
Встроенные функции, которые нужны чаще всего
- 📝 Строки:
СтрДлина,СокрЛП,Лев,Прав,Сред,ВРег,НРег,СтрЗаменить,СтрНайти,СтрРазделить,СтрСоединить,СтрШаблон. - 🔢 Числа:
Окр,Цел,Мин,Макс,Число. - 📅 Даты:
ТекущаяДатаСеанса,НачалоМесяца,КонецМесяца,ДобавитьМесяц,Год,Месяц,День. - 🧩 Типы и значения:
ТипЗнч,Тип,ЗначениеЗаполнено,Строка,Формат.
СтрНайти, СтрРазделить и СтрСоединить появились в платформе 8.3.6. В старом коде вместо них встречаются Найти() и самописные функции разбора строки.
Полный список встроенных функций с описанием параметров есть в синтакс-помощнике Конфигуратора: раздел «Глобальный контекст». Поставьте курсор на имя функции в модуле и нажмите Ctrl+F1 — откроется её описание.
Функции языка запросов — отдельный мир
Внутри текста запроса работают только функции языка запросов. Вызвать там СтрДлина() или свою функцию из модуля нельзя: запрос выполняет СУБД, а не встроенный язык. Если нужна обработка, которую язык запросов не умеет, её делают после выполнения запроса, в цикле по выборке.
Как написать свою функцию в 1С: синтаксис и параметры
Общий вид объявления:
// Выделяет НДС из суммы, в которую налог уже включён.
// Параметры:
// СуммаСНДС - Число - сумма с налогом.
// СтавкаПроцент - Число - ставка в процентах, например 22.
// Возвращаемое значение:
// Число - сумма НДС, округлённая до копеек.
Функция СуммаНДСИзСуммы(Знач СуммаСНДС, Знач СтавкаПроцент) Экспорт
Если СтавкаПроцент = 0 Тогда
Возврат 0;
КонецЕсли;
Возврат Окр(СуммаСНДС * СтавкаПроцент / (100 + СтавкаПроцент), 2);
КонецФункции
Проверим: СуммаНДСИзСуммы(1220, 22) даёт 1220 × 22 / 122 = 220. Для ставки 0 функция сразу вернёт 0.
Разберём части объявления.
- Комментарий-описание. Блок «Параметры / Возвращаемое значение» над функцией — стандарт оформления в типовых конфигурациях. Конфигуратор и EDT показывают его во всплывающей подсказке при вызове.
- Имя. Пишут слитно, каждое слово с большой буквы. Имя функции отвечает на вопрос «что вернётся»:
СуммаНДСИзСуммы,ФамилияИнициалы,ЭтоВыходнойДень. Процедуры называют глаголом:ЗаполнитьТабличнуюЧасть. - Параметры. Перечисляются через запятую. Тип не указывается — язык динамический.
Знач. Параметр передаётся по значению: функция получает копию и не испортит переменную вызывающего кода.Экспорт. Делает функцию видимой из других модулей. Без него её можно вызвать только внутри того же модуля.
Передача параметров: по ссылке и через Знач
По умолчанию параметры в 1С передаются по ссылке. Это главный источник неожиданных ошибок у новичков:
Функция Удвоить(Число)
Число = Число * 2;
Возврат Число;
КонецФункции
А = 5;
Б = Удвоить(А); // Б = 10, но и А теперь тоже 10
Добавьте Знач перед параметром — и А останется равным 5.
Знач защищает саму переменную, но не содержимое коллекции. Если передать массив с Знач, функция не сможет подменить его на другой массив, но Массив.Добавить() внутри функции изменит исходный массив. Нужна независимая копия — создайте новый массив и скопируйте элементы.
Значения по умолчанию
Параметру можно задать значение по умолчанию, тогда при вызове его разрешено не указывать:
Функция ДатаПрописью(Дата, ФорматнаяСтрока = "ДЛФ=DD") Экспорт
Возврат Формат(Дата, ФорматнаяСтрока);
КонецФункции
Вызов ДатаПрописью(ТекущаяДатаСеанса()) вернёт дату длинным форматом, например «7 октября 2026 г.».
Где разместить функцию: модули и директивы компиляции
От места размещения зависит, кто сможет вызвать функцию и где она выполнится: на клиенте или на сервере.
| Где размещена | Кто вызывает | Когда выбирать |
|---|---|---|
| Модуль формы | Только эта форма | Логика одной формы |
| Модуль объекта | Через объект: ДокументОбъект.МояФункция() | Расчёты по данным самого объекта |
| Модуль менеджера | Через менеджер: Документы.РеализацияТоваровУслуг.МояФункция() | Функции, не требующие экземпляра объекта |
| Общий модуль | Из любого места: МойМодуль.МояФункция() | Повторно используемый код |
Директивы компиляции в модуле формы
В модуле управляемой формы перед каждой функцией ставят директиву:
- 🖥
&НаКлиенте— выполняется на клиенте, видит элементы формы, не может обращаться к базе напрямую. - 🗄
&НаСервере— выполняется на сервере, получает данные формы. Каждый вызов с клиента — обращение к серверу с передачей данных формы. - ⚡
&НаСервереБезКонтекста— на сервере, но без данных формы. Вызов дешевле: передаются только параметры. - 🔁
&НаКлиентеНаСервереБезКонтекста— компилируется и там и там; подходит для чистых расчётов.
&НаКлиенте
Процедура НоменклатураПриИзменении(Элемент)
Объект.Ставка = СтавкаНоменклатуры(Объект.Номенклатура);
КонецПроцедуры
&НаСервереБезКонтекста
Функция СтавкаНоменклатуры(Номенклатура)
Возврат ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Номенклатура, "СтавкаНДС");
КонецФункции
ОбщегоНазначения.ЗначениеРеквизитаОбъекта — функция библиотеки стандартных подсистем (БСП). Она читает один реквизит запросом и не загружает объект целиком.
Флаги общего модуля
У общего модуля в палитре свойств есть флаги Клиент (управляемое приложение), Сервер, Вызов сервера, Внешнее соединение, Привилегированный, Глобальный. Чтобы клиентский код мог вызвать серверную функцию общего модуля, у модуля должны стоять Сервер и Вызов сервера, а функция — быть с Экспорт.
Флаг Глобальный позволяет звать функции без имени модуля. Удобно, но такие модули компилируются при старте сеанса и замедляют запуск. В типовых конфигурациях глобальных модулей держат минимум.
Примеры функций в 1С для типовых задач
Фамилия и инициалы из полного ФИО
Функция ФамилияИнициалы(Знач ПолноеФИО) Экспорт
Части = СтрРазделить(СокрЛП(ПолноеФИО), " ", Ложь);
Если Части.Количество() = 0 Тогда
Возврат "";
КонецЕсли;
Результат = Части[0];
Для Индекс = 1 По Мин(Части.Количество() - 1, 2) Цикл
Результат = Результат + " " + Лев(Части[Индекс], 1) + ".";
КонецЦикла;
Возврат Результат;
КонецФункции
ФамилияИнициалы("Иванов Пётр Сергеевич") вернёт «Иванов П. С.». Третий параметр Ложь у СтрРазделить выбрасывает пустые части, поэтому двойные пробелы не ломают результат. Строка из одной фамилии вернётся как есть: цикл от 1 до 0 не выполнится ни разу.
Проверка, что дата — выходной по календарю недели
Функция ЭтоСубботаИлиВоскресенье(Дата) Экспорт
Возврат ДеньНедели(Дата) >= 6;
КонецФункции
ДеньНедели() возвращает 1 для понедельника и 7 для воскресенья. Праздники эта функция не учитывает — для них в типовых конфигурациях есть производственный календарь
.
Сумма с представлением валюты и количеством знаков
Функция ПредставлениеСуммы(Сумма, Опции = Неопределено) Экспорт
Настройки = Новый Структура("Валюта, Знаков", "руб.", 2);
Если Опции <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(Настройки, Опции);
КонецЕсли;
ФорматнаяСтрока = "ЧДЦ=" + Строка(Настройки.Знаков) + "; ЧН=0";
Возврат Формат(Сумма, ФорматнаяСтрока) + " " + Настройки.Валюта;
КонецФункции
Вызов ПредставлениеСуммы(1500) даст «1 500,00 руб.», а ПредставлениеСуммы(1500, Новый Структура("Валюта", "USD")) — «1 500,00 USD». Параметр ЧН=0 нужен, чтобы нулевая сумма не превратилась в пустую строку: без него Формат(0, …) возвращает «».
Функции с неопределённым числом параметров в 1С
Объявить функцию с произвольным числом аргументов, как в некоторых других языках, во встроенном языке 1С нельзя. Число параметров фиксируется при объявлении. Встроенная СтрШаблон() выглядит исключением, но и у неё предел — до 10 подставляемых значений.
Задачу решают тремя способами.
| Способ | Как выглядит | Когда подходит |
|---|---|---|
| Параметры по умолчанию | Функция Ф(А, Б = 0, В = "") | 2–4 необязательных значения |
| Массив | Функция СуммаЧисел(Числа) | Однотипные значения, их количество заранее неизвестно |
| Структура опций | Функция Ф(А, Опции = Неопределено) | Много разнородных настроек, часть не задаётся |
Пропустить параметр в середине можно запятыми: Ф(1, , "текст"). Но только если у пропущенного параметра есть значение по умолчанию.
Пример с массивом:
Функция СуммаЧисел(Числа) Экспорт
Итог = 0;
Для Каждого Элемент Из Числа Цикл
Итог = Итог + Элемент;
КонецЦикла;
Возврат Итог;
КонецФункции
Значения = Новый Массив;
Значения.Добавить(100);
Значения.Добавить(250);
Значения.Добавить(50);
Итого = СуммаЧисел(Значения); // 400
Структура опций показана выше в ПредставлениеСуммы: значения по умолчанию задаются внутри функции, а ЗаполнитьЗначенияСвойств перекрывает только те, что передал вызывающий. Новую опцию можно добавить позже, не меняя ни одного существующего вызова.
Как ускорить функции в 1С
Медленная функция почти всегда медленная по одной из четырёх причин: лишние вызовы сервера, запросы в цикле, загрузка объектов целиком и повторное вычисление одного и того же.
- Сокращайте вызовы сервера. Три вызова
&НаСервереподряд в одном обработчике — три обращения к серверу. Соберите их в одну серверную функцию, которая вернёт структуру с результатами. - Выбирайте
&НаСервереБезКонтекста, если данные формы не нужны. На форме с большой табличной частью разница заметна на глаз. - Не делайте запрос в цикле. Вместо 500 запросов по одной строке — один запрос с параметром-массивом и условием
В (&Список). - Не вызывайте
ПолучитьОбъект()ради одного реквизита. Объект читается со всеми табличными частями. Для чтения естьОбщегоНазначения.ЗначениеРеквизитаОбъектаили обращение через ссылку. - Кешируйте неизменные данные. У общего модуля есть свойство «Повторное использование возвращаемых значений»:
На время вызоваилиНа время сеанса. Функция такого модуля при тех же параметрах вернёт сохранённый результат без повторного вычисления.
Функция в модуле повторного использования должна возвращать неизменяемые значения: ФиксированнаяСтруктура, ФиксированныйМассив, примитивные типы. Обычную структуру вызывающий код может изменить — и испорченное значение получат все последующие вызовы. Сбросить кеш принудительно можно методом ОбновитьПовторноИспользуемыеЗначения().
Где именно теряется время, показывает замер производительности. Запустите отладку из Конфигуратора, включите замер через меню Отладка → Замер производительности, выполните действие в программе и остановите замер. Строки с наибольшим временем и числом вызовов — первые кандидаты на переделку.
Ошибки при работе с функциями и как их избежать
- ❌ «Процедура или функция с указанным именем не определена». Опечатка в имени, функция объявлена в другом модуле или стоит под другой директивой: клиентский код не видит функцию с
&НаСервереБезКонтекста, если та объявлена в другой форме. - ❌ «Метод объекта не обнаружен» при вызове
МойМодуль.Функция(). Чаще всего у функции нет словаЭкспортили у общего модуля не подходят флаги: например, клиент обращается к модулю без флагаВызов сервера. - ❌ «Недостаточно фактических параметров» / «Слишком много фактических параметров». Количество аргументов при вызове не совпадает с объявлением. Часто так бывает после того, как в функцию добавили параметр без значения по умолчанию.
- ❌ Переменная «сама» поменялась после вызова. Параметр передан по ссылке и изменён внутри функции. Лечится словом
Знач. - ❌ Функция иногда возвращает
Неопределено. Есть веткаЕсли, в которой нетВозврат. ПоставьтеВозвратв конце функции — тогда пустой результат станет явным. - ❌ Ошибка передачи значения на клиент. Серверная функция вернула объект (
ДокументОбъект,Запрос,РезультатЗапроса), который нельзя передать на клиент. Возвращайте ссылки, примитивные значения, структуры и массивы из них.
Частые вопросы о функциях в 1С
Где пользователю найти «Все функции» в 1С 8.3?
Сервис → Параметры и включите флажок «Отображать команду “Все функции”». После этого в главном меню появится пункт «Все функции» со списком всех справочников, документов и регистров.Чем «Все функции» отличается от функций встроенного языка?
Может ли функция вызывать сама себя?
Можно ли вернуть из функции несколько значений?
Возврат Новый Структура("Сумма, НДС", 1220, 220);.