1C-Code → Основы 1С → Формы: клиент, сервер и управление элементами
Где выполняется код формы, почему это важнее синтаксиса и как менять форму программно.
Глава 12 из 36 · чтение примерно 26 минут
Форма — это то, что человек видит: поля, кнопки, таблицы. И почти всё, что делает разработчик 1С после первого месяца, так или иначе связано с формами.
Синтаксис здесь простой. Сложность в другом — в том, где выполняется код.
Это главное, что надо понять про формы, и понять до всего остального.
Часть кода формы работает на клиенте — на компьютере пользователя. Там видны элементы формы, там происходят нажатия и ввод. Но базы данных там нет.
Другая часть работает на сервере — там, где база. Оттуда доступны справочники, документы, запросы. Но экрана пользователя там нет.
| Клиент | Сервер | |
|---|---|---|
| элементы формы, их видимость | да | да, если &НаСервере в контексте формы |
| справочники, документы, запросы | нет | да |
| сообщения и вопросы пользователю | да | сообщения — да, вопросы — нет |
| где физически выполняется | компьютер пользователя | сервер приложений |
&НаКлиенте
Процедура НажатиеКнопки(Команда)
Данные = ПрочитатьДанные(); // уход на сервер и обратно
Сообщить(Данные);
КонецПроцедуры
&НаСервере
Функция ПрочитатьДанные()
// здесь есть база
Возврат Справочники.Номенклатура.НайтиПоКоду("000001").Наименование;
КонецФункции
| Часть | Что означает |
|---|---|
&НаКлиенте | директива компиляции — пишется строкой выше процедуры |
&НаСервере | здесь доступна база, но не диалоги с пользователем |
вызов | клиентский код вызывает серверный обычным вызовом… |
…но | …и это отправка запроса по сети — самое дорогое, что тут есть |
Каждый вызов сервера — поход по сети
Вызов серверной процедуры из клиентской выглядит как обычный вызов функции. Но физически это обращение по сети: данные упаковываются, летят на сервер, там выполняются, результат летит обратно.
В офисе, по локальной сети, это миллисекунды и незаметно. Через интернет, у бухгалтера из филиала, — уже десятые доли секунды на каждый вызов.
Пять элементов формы, для каждого спросили у сервера видимость — пять походов. Форма открывается с ощутимой задержкой, и на разработке этого не видно: там сервер на той же машине.
Правило: один вызов сервера за всеми данными сразу, а не по вызову на каждый элемент.
✓ Вызов на каждый элемент
Для Каждого Имя Из Имена Цикл
Виден = ЭлементВиден(Имя); // ← сервер
Элементы.Найти(Имя).Видимость = Виден;
КонецЦикла;Пять элементов — пять походов по сети. Ровно та же ошибка, что запрос в цикле.
✕ Один вызов за всем
Настройки = НастройкиВидимости(); // ← сервер, один раз
Для Каждого Имя Из Имена Цикл
Элементы.Найти(Имя).Видимость = Настройки[Имя];
КонецЦикла;Один поход, дальше цикл работает с соответствием в памяти.
Все элементы формы лежат в коллекции Элементы. Взять нужный можно двумя способами.
Элементы.ПолеСклад — через точку, когда имя известно, когда пишется код. Коротко и наглядно.
Элементы.Найти("ПолеСклад") — по имени-строке, когда имя вычисляется. Возвращает Неопределено, если элемента нет.
| Свойство | Что делает |
|---|---|
| Видимость | показать или скрыть элемент целиком |
| Доступность | оставить видимым, но запретить менять |
| Заголовок | подпись, которую видит человек |
Скрыть или заблокировать — разные вещи
Видимость = Ложь убирает элемент с экрана. Человек не узнает, что он существует.
Доступность = Ложь оставляет элемент на месте, но запрещает менять. Значение видно, изменить нельзя.
Выбор не косметический. Скрытое поле вызывает вопрос «а где сумма?», заблокированное отвечает на него само: сумма вот она, просто её считает программа.
Общее правило: прячут то, что не нужно, блокируют то, что нужно видеть, но нельзя трогать.
Упражнение 1. Скрыть поле
На форме есть элементы ПолеСклад, ПолеКомментарий и КнопкаПечать. Напишите функцию СкрытьКомментарий(), которая прячет поле комментария и возвращает его видимость.
Решается в тренажёре: код запускается и проверяется сразу.
Найти вернёт Неопределено, а не ошибку
Опечатались в имени элемента — Найти вернёт Неопределено. Спокойно, без единой жалобы.
Программа упадёт строкой ниже, на попытке присвоить Видимость несуществующему элементу. И сообщение будет про Неопределено, а не про опечатку в имени.
Когда имя элемента приходит откуда-то извне — из настройки, из списка, из другого кода — результат Найти проверяют:
Элемент = Элементы.Найти(Имя); Если Элемент <> Неопределено Тогда Элемент.Видимость = Ложь; КонецЕсли;
Упражнение 2. Осторожное скрытие
Напишите СкрытьЕслиЕсть(Имя): скрыть элемент с таким именем, если он на форме есть, и вернуть Истина. Если элемента нет — вернуть Ложь, не падая. Проверка передаёт имя, которого на форме нет.
Решается в тренажёре: код запускается и проверяется сразу.
Кроме элементов у формы есть реквизиты — её собственные данные. Элемент показывает реквизит, реквизит хранит значение.
Обращаются к ним прямо по имени: ЭтаФорма.Сумма или просто Сумма внутри модуля формы.
Разница между элементом и реквизитом важна: элемент — это как показано, реквизит — это что показано. Скрыть элемент не значит очистить реквизит: значение останется и запишется.
Упражнение 3. Заполнить реквизит формы
На форме есть реквизит Сумма. Напишите ПоставитьСумму(Значение): записать значение в реквизит формы и вернуть его.
Решается в тренажёре: код запускается и проверяется сразу.
Код формы не запускается сам — его вызывает платформа, когда что-то происходит. Эти моменты называют событиями, и у каждого своё назначение.
| Событие | Когда срабатывает | Что туда пишут |
|---|---|---|
| ПриСозданииНаСервере | форма создаётся, до показа | начальное заполнение, настройка видимости |
| ПриОткрытии | форма уже показана, на клиенте | то, что требует готового экрана |
| ПриИзменении (у поля) | человек изменил значение | пересчёт зависимых полей |
| ПередЗаписью | перед сохранением | проверки — но не единственные, см. ниже |
| ПередЗакрытием | форма закрывается | вопрос «сохранить изменения?» |
Проверка только в форме — это не проверка
Соблазн очевиден: человек вводит данные в форме, значит и проверять их логично в форме.
Но форма — не единственный путь к данным. Есть обмен с другой базой, есть загрузка из файла, есть обработка, есть код другого разработчика. Все они пишут документы мимо формы, и проверка в форме на них не сработает.
Поэтому правило такое: в форме проверяют, чтобы подсказать человеку сразу, пока он не ушёл. А настоящую защиту ставят в модуле объекта, в ПередЗаписью, — через неё не пройдёт никто.
Данные, испорченные обменом, находят через полгода, и восстанавливать их будет уже некому.
Чем меньше на клиенте, тем лучше
Итог главы в одну строку: решения принимают на сервере, показывают на клиенте.
Клиентский код должен быть тонким: собрать, что нажали, один раз сходить на сервер, разложить полученное по элементам. Вся работа с данными — там, где данные.
Это же ответ на вопрос, почему у одних формы открываются мгновенно, а у других «задумываются». Дело почти никогда не в железе.
Осталась последняя большая тема — язык запросов. Это то, чем в 1С читают данные: с отбором, группировкой и соединением, одним обращением вместо цикла.
Читать про код и писать код — разные умения. В тренажёре к этой главе идут упражнения: вы пишете решение, оно запускается на настоящем интерпретаторе 1С и проверяется сразу, без установки платформы.
← Справочники и документы: чтение и запись
→ Язык запросов: читать данные пачками