1C-CodeОсновы 1С → Где живёт код: модули, клиент и сервер

Где живёт код: модули, клиент и сервер

Первое знакомство: почему в 1С один и тот же код нельзя написать где угодно. Подробный разбор всех модулей и директив — в части «Платформа».

Глава 4 из 36 · чтение примерно 22 минут

В предыдущей главе мы писали функции «в воздухе». В настоящей конфигурации так не бывает: у каждой функции есть место, и от места зависит, что ей разрешено.

Это главное, чем 1С отличается от языков, которые учат по книжкам. Там программа — один процесс. Здесь она разорвана на две части, работающие на разных компьютерах, и это приходится держать в голове с первого дня.

Модуль — файл с кодом

Модуль — это место, где лежат функции и процедуры. Не файл на диске в привычном смысле, а раздел внутри конфигурации, привязанный к чему-то конкретному.

Модулей много видов, но для начала достаточно четырёх.

Модули, с которыми работают чаще всего

МодульК чему привязанЧто в нём пишут
Общий модульни к чему — сам по себеРасчёты и правила, нужные из разных мест. Главное место для вашего кода
Модуль объектак справочнику или документуЧто происходит при записи и проведении ЭТОГО вида документов
Модуль формык конкретной формеЧто происходит при нажатии кнопок и изменении полей НА ЭТОЙ форме
Модуль менеджерак виду объекта целикомДействия над видом, а не над одним экземпляром: печатные формы, выборки

Куда класть код по умолчанию

Если сомневаетесь — в общий модуль.

Код в модуле формы намертво привязан к этой форме: понадобился тот же расчёт в другом месте — придётся копировать. Код в общем модуле вызывается откуда угодно и проверяется отдельно.

Правило, которое стоит запомнить сразу: в модуле формы — только то, что про эту форму. Расчёт суммы, проверка правил, обращение к базе — не про форму, им место в общем модуле.

Экспорт: видно снаружи или нет

Теперь слово Экспорт из прошлой главы обретает смысл. Функция без него видна только внутри своего модуля. С ним — из любого другого места.

Вызывают так: ИмяМодуля.ИмяФункции(аргументы). Например, РаботаСЦенами.СуммаСоСкидкой(1000, 10).

Что видно, а что нет

// Общий модуль «РаботаСЦенами»

Функция СуммаСоСкидкой(Сумма, Процент) Экспорт
	Возврат Сумма - Скидка(Сумма, Процент);
КонецФункции

Функция Скидка(Сумма, Процент)
	Возврат Окр(Сумма * Процент / 100, 2);
КонецФункции
ЧастьЧто означает
СуммаСоСкидкойс Экспорт — её вызывают снаружи, это «вход» в модуль
Скидкабез Экспорт — вспомогательная, видна только соседям по модулю
зачем прятатьто, что не видно снаружи, можно свободно менять
если экспортировать всёчерез год окажется, что на любую мелочь кто-то опёрся

Клиент и сервер: главная особенность 1С

Программа 1С работает не на одном компьютере. Часть её выполняется у человека — там, где окна, кнопки и мышь. Другая часть на сервере — там, где база данных.

Разделение не выдумано ради сложности. База может быть в другом городе, и гонять по сети каждое обращение к ней было бы невозможно медленно. Поэтому работа с данными идёт там же, где данные.

Что где можно

На клиентеНа сервере
Где выполняетсяна компьютере человекатам же, где база
Видит формы и кнопкиданет
Читает и пишет базунетда
Показывает вопросы и предупрежденияданет
Работает с файлами человекаданет
Знает про интернет и почтуограниченнода

Директивы компиляции

&НаКлиенте
Процедура ПосчитатьНажатие(Команда)
	Итого = ПосчитатьНаСервере();   // уходим на сервер
	Сообщить("Получилось: " + Строка(Итого));
КонецПроцедуры

&НаСервере
Функция ПосчитатьНаСервере()
	// здесь можно обращаться к базе
	Возврат 1000;
КонецФункции
ЧастьЧто означает
&НаКлиентедиректива: эта процедура выполняется у человека
&НаСервереа эта — на сервере, рядом с базой
вызов между нимиклиент может вызвать сервер, и это поход по сети
обратно нельзясервер не может вызвать клиентскую процедуру: он не знает про окна
Сообщитьработает и там и там, но на сервере копится и покажется потом

Каждый вызов сервера — поход по сети

Переход с клиента на сервер стоит времени: данные упаковываются, летят по сети, распаковываются, и обратно так же.

Один вызов — незаметно. Вызов внутри цикла по строкам документа — уже секунды. Именно поэтому в боевых задачах тренажёра считается число обращений к базе: решение, которое ходит на сервер в цикле, формально верное, а на настоящих данных не работает.

Правило: собрать всё нужное, сходить на сервер один раз, вернуть всё сразу.

✓ Один поход

&НаКлиенте
Процедура Заполнить()
	Данные = ПолучитьВсёСразу();
	Для Каждого С Из Данные Цикл
		// работаем с готовым
	КонецЦикла;
КонецПроцедуры

Одно обращение к серверу, дальше всё на клиенте. Так и надо.

✕ Поход в цикле

&НаКлиенте
Процедура Заполнить()
	Для Каждого С Из Строки Цикл
		Цена = ПолучитьЦену(С);  // сервер!
	КонецЦикла;
КонецПроцедуры

Сто строк — сто походов по сети. На демо-базе незаметно, на рабочей — минуты.

Данные тоже делятся

Клиент и сервер — разные компьютеры, и переменные у них разные. Значение, чтобы попасть с одного на другой, должно быть передаваемым: числа, строки, даты, массивы и структуры — можно. Объект документа, открытая форма, соединение с файлом — нельзя.

Отсюда частая ошибка новичка: получил на сервере объект справочника, попробовал вернуть его на клиент — и получил отказ. Возвращать надо то, что клиенту действительно нужно: обычно несколько значений в структуре, а не объект целиком.

Упражнение 1. Собрать ответ в структуру

Напишите функцию ДанныеДляФормы(Цена, Количество). Она возвращает структуру с полями Сумма (цена × количество) и Строка (текст вида "Итого: 1000").
Структура создаётся так: Новый Структура("Поле1, Поле2", Значение1, Значение2).

Решается в тренажёре: код запускается и проверяется сразу.

Как понять, где должна быть функция

Три вопроса по порядку.

Она обращается к базе? Значит, только на сервере. Другого варианта нет.

Она показывает что-то человеку или спрашивает его? Значит, только на клиенте: сервер не знает, что у человека открыто на экране.

Она просто считает? Может быть где угодно. Тогда решает второе соображение: если расчёт нужен и там и там, ему место в общем модуле с пометкой, что он доступен обеим сторонам.

Почему это учат так рано

Разделение на клиент и сервер выглядит как деталь, которую можно отложить. Но код, написанный без него, приходится переписывать целиком: расчёт, залезший в базу из клиентской процедуры, не «поправить в одном месте» — он просто не работает.

Поэтому вопрос «где это выполнится» задают до того, как пишут первую строку, а не после.

Упражнение 2. Расчёт, годный обеим сторонам

Напишите функцию СуммаСоСкидкой(Сумма, Процент): вычитает из суммы скидку в процентах и округляет до двух знаков. Такой расчёт не трогает базу и ничего не показывает — значит, его место в общем модуле, доступном и клиенту, и серверу.

Решается в тренажёре: код запускается и проверяется сразу.

Что дальше

Вы знаете, где живёт код и почему это важно. Дальше — типы значений по одному: числа, строки, даты, булево. С каждым свои приёмы и свои ловушки, и именно на них уходит большая часть времени новичка.

Как закрепить

Читать про код и писать код — разные умения. В тренажёре к этой главе идут упражнения: вы пишете решение, оно запускается на настоящем интерпретаторе 1С и проверяется сразу, без установки платформы.

Открыть эту главу в тренажёре

Функции и процедуры: как код делится на части
Числа: арифметика, округление и деньги