1C-Code → Основы 1С → Где живёт код: модули, клиент и сервер
Первое знакомство: почему в 1С один и тот же код нельзя написать где угодно. Подробный разбор всех модулей и директив — в части «Платформа».
Глава 4 из 36 · чтение примерно 22 минут
В предыдущей главе мы писали функции «в воздухе». В настоящей конфигурации так не бывает: у каждой функции есть место, и от места зависит, что ей разрешено.
Это главное, чем 1С отличается от языков, которые учат по книжкам. Там программа — один процесс. Здесь она разорвана на две части, работающие на разных компьютерах, и это приходится держать в голове с первого дня.
Модуль — это место, где лежат функции и процедуры. Не файл на диске в привычном смысле, а раздел внутри конфигурации, привязанный к чему-то конкретному.
Модулей много видов, но для начала достаточно четырёх.
| Модуль | К чему привязан | Что в нём пишут |
|---|---|---|
| Общий модуль | ни к чему — сам по себе | Расчёты и правила, нужные из разных мест. Главное место для вашего кода |
| Модуль объекта | к справочнику или документу | Что происходит при записи и проведении ЭТОГО вида документов |
| Модуль формы | к конкретной форме | Что происходит при нажатии кнопок и изменении полей НА ЭТОЙ форме |
| Модуль менеджера | к виду объекта целиком | Действия над видом, а не над одним экземпляром: печатные формы, выборки |
Куда класть код по умолчанию
Если сомневаетесь — в общий модуль.
Код в модуле формы намертво привязан к этой форме: понадобился тот же расчёт в другом месте — придётся копировать. Код в общем модуле вызывается откуда угодно и проверяется отдельно.
Правило, которое стоит запомнить сразу: в модуле формы — только то, что про эту форму. Расчёт суммы, проверка правил, обращение к базе — не про форму, им место в общем модуле.
Теперь слово Экспорт из прошлой главы обретает смысл. Функция без него видна только внутри своего модуля. С ним — из любого другого места.
Вызывают так: ИмяМодуля.ИмяФункции(аргументы). Например, РаботаСЦенами.СуммаСоСкидкой(1000, 10).
// Общий модуль «РаботаСЦенами»
Функция СуммаСоСкидкой(Сумма, Процент) Экспорт
Возврат Сумма - Скидка(Сумма, Процент);
КонецФункции
Функция Скидка(Сумма, Процент)
Возврат Окр(Сумма * Процент / 100, 2);
КонецФункции
| Часть | Что означает |
|---|---|
СуммаСоСкидкой | с Экспорт — её вызывают снаружи, это «вход» в модуль |
Скидка | без Экспорт — вспомогательная, видна только соседям по модулю |
зачем прятать | то, что не видно снаружи, можно свободно менять |
если экспортировать всё | через год окажется, что на любую мелочь кто-то опёрся |
Программа 1С работает не на одном компьютере. Часть её выполняется у человека — там, где окна, кнопки и мышь. Другая часть на сервере — там, где база данных.
Разделение не выдумано ради сложности. База может быть в другом городе, и гонять по сети каждое обращение к ней было бы невозможно медленно. Поэтому работа с данными идёт там же, где данные.
| На клиенте | На сервере | |
|---|---|---|
| Где выполняется | на компьютере человека | там же, где база |
| Видит формы и кнопки | да | нет |
| Читает и пишет базу | нет | да |
| Показывает вопросы и предупреждения | да | нет |
| Работает с файлами человека | да | нет |
| Знает про интернет и почту | ограниченно | да |
&НаКлиенте
Процедура ПосчитатьНажатие(Команда)
Итого = ПосчитатьНаСервере(); // уходим на сервер
Сообщить("Получилось: " + Строка(Итого));
КонецПроцедуры
&НаСервере
Функция ПосчитатьНаСервере()
// здесь можно обращаться к базе
Возврат 1000;
КонецФункции
| Часть | Что означает |
|---|---|
&НаКлиенте | директива: эта процедура выполняется у человека |
&НаСервере | а эта — на сервере, рядом с базой |
вызов между ними | клиент может вызвать сервер, и это поход по сети |
обратно нельзя | сервер не может вызвать клиентскую процедуру: он не знает про окна |
Сообщить | работает и там и там, но на сервере копится и покажется потом |
Каждый вызов сервера — поход по сети
Переход с клиента на сервер стоит времени: данные упаковываются, летят по сети, распаковываются, и обратно так же.
Один вызов — незаметно. Вызов внутри цикла по строкам документа — уже секунды. Именно поэтому в боевых задачах тренажёра считается число обращений к базе: решение, которое ходит на сервер в цикле, формально верное, а на настоящих данных не работает.
Правило: собрать всё нужное, сходить на сервер один раз, вернуть всё сразу.
✓ Один поход
&НаКлиенте
Процедура Заполнить()
Данные = ПолучитьВсёСразу();
Для Каждого С Из Данные Цикл
// работаем с готовым
КонецЦикла;
КонецПроцедурыОдно обращение к серверу, дальше всё на клиенте. Так и надо.
✕ Поход в цикле
&НаКлиенте
Процедура Заполнить()
Для Каждого С Из Строки Цикл
Цена = ПолучитьЦену(С); // сервер!
КонецЦикла;
КонецПроцедурыСто строк — сто походов по сети. На демо-базе незаметно, на рабочей — минуты.
Клиент и сервер — разные компьютеры, и переменные у них разные. Значение, чтобы попасть с одного на другой, должно быть передаваемым: числа, строки, даты, массивы и структуры — можно. Объект документа, открытая форма, соединение с файлом — нельзя.
Отсюда частая ошибка новичка: получил на сервере объект справочника, попробовал вернуть его на клиент — и получил отказ. Возвращать надо то, что клиенту действительно нужно: обычно несколько значений в структуре, а не объект целиком.
Упражнение 1. Собрать ответ в структуру
Напишите функцию ДанныеДляФормы(Цена, Количество). Она возвращает структуру с полями Сумма (цена × количество) и Строка (текст вида "Итого: 1000").
Структура создаётся так: Новый Структура("Поле1, Поле2", Значение1, Значение2).
Решается в тренажёре: код запускается и проверяется сразу.
Три вопроса по порядку.
Она обращается к базе? Значит, только на сервере. Другого варианта нет.
Она показывает что-то человеку или спрашивает его? Значит, только на клиенте: сервер не знает, что у человека открыто на экране.
Она просто считает? Может быть где угодно. Тогда решает второе соображение: если расчёт нужен и там и там, ему место в общем модуле с пометкой, что он доступен обеим сторонам.
Почему это учат так рано
Разделение на клиент и сервер выглядит как деталь, которую можно отложить. Но код, написанный без него, приходится переписывать целиком: расчёт, залезший в базу из клиентской процедуры, не «поправить в одном месте» — он просто не работает.
Поэтому вопрос «где это выполнится» задают до того, как пишут первую строку, а не после.
Упражнение 2. Расчёт, годный обеим сторонам
Напишите функцию СуммаСоСкидкой(Сумма, Процент): вычитает из суммы скидку в процентах и округляет до двух знаков. Такой расчёт не трогает базу и ничего не показывает — значит, его место в общем модуле, доступном и клиенту, и серверу.
Решается в тренажёре: код запускается и проверяется сразу.
Вы знаете, где живёт код и почему это важно. Дальше — типы значений по одному: числа, строки, даты, булево. С каждым свои приёмы и свои ловушки, и именно на них уходит большая часть времени новичка.
Читать про код и писать код — разные умения. В тренажёре к этой главе идут упражнения: вы пишете решение, оно запускается на настоящем интерпретаторе 1С и проверяется сразу, без установки платформы.
← Функции и процедуры: как код делится на части
→ Числа: арифметика, округление и деньги