В процессе разработки в среде «1С:Предприятие» программисты часто сталкиваются с необходимостью передавать данные, введенные пользователем в форму, в процедуры и функции общих модулей. Попытки сделать это «напрямую» (например, через получение формы в общем модуле) часто приводят к ошибкам или неоптимальной работе системы. В этой статье мы подробно разберем, как правильно решать эту задачу, проанализируем типичные ошибки и рассмотрим лучшие архитектурные практики для обычных и управляемых форм.
Начинающие разработчики часто пытаются получить доступ к форме непосредственно из общего модуля с помощью конструкции ПолучитьФорму(). Давайте разберем, почему этот подход ошибочен:
ЭтотОбъект недоступно (если только модуль не является модулем объекта или формы). Попытка вызвать метод получения формы вызовет ошибку компиляции.ПолучитьФорму() инициализирует новый, пустой экземпляр формы. В ней не будет тех данных, которые пользователь только что ввел на своем экране. Форма — это лишь временный интерфейсный «телевизор» для отображения данных.Рассмотрим правильные и безопасные способы передачи данных из формы в общий модуль.
Для того чтобы не связывать жестко интерфейс (форму) и бизнес-логику (общий модуль), применяется принцип «слабой связанности» (Decoupling). Вместо передачи самой формы или попыток прочитать ее элементы напрямую из общего модуля, мы собираем все необходимые значения в специальный контейнер — объект типа Структура — и передаем его в качестве параметра функции.
Давайте разберем, как реализовать этот подход по шагам.
Шаг 1. Код в модуле формы
В модуле формы (например, при нажатии на кнопку подключения) мы собираем все заполненные реквизиты в структуру и вызываем функцию общего модуля:
&НаКлиенте
Процедура ПодключитьсяКSQL(Команда)
// Формируем структуру параметров подключения
ПараметрыПодключения = Новый Структура;
ПараметрыПодключения.Вставить("ИмяСервера", Объект.ИмяСервераSQL);
ПараметрыПодключения.Вставить("Пользователь", Объект.ПользовательSQL);
ПараметрыПодключения.Вставить("Пароль", Объект.ПарольSQL);
ПараметрыПодключения.Вставить("БазаДанных", Объект.БазаДанныхSQL);
// Вызываем функцию общего модуля, передавая параметры
Таблица = "Сотрудники";
ЗначениеПоиска = "Иванов";
Результат = РаботаСВнешнимиБД.fnc_search_1C_SQL(Таблица, ЗначениеПоиска, ПараметрыПодключения);
КонецПроцедуры
Шаг 2. Код в общем модуле
В общем модуле мы принимаем эту структуру и извлекаем из нее параметры без обращения к элементам интерфейса:
Функция fnc_search_1C_SQL(a_table, a_value, ПараметрыПодключения) Экспорт
ИмяСервераSQL = ПараметрыПодключения.ИмяСервера;
ПользовательSQL = ПараметрыПодключения.Пользователь;
ПарольSQL = ПараметрыПодключения.Пароль;
БазаДанныхSQL = ПараметрыПодключения.БазаДанных;
Попытка
Соединение = Новый COMОбъект("ADODB.Connection");
Соединение.ConnectionString = "driver={SQL Server};"
+ "server=" + ИмяСервераSQL + ";"
+ "uid=" + ПользовательSQL + ";"
+ "pwd=" + ПарольSQL + ";"
+ "database=" + БазаДанныхSQL + ";";
Соединение.ConnectionTimeout = 10;
Соединение.Open();
// Здесь выполняется логика работы с БД...
Соединение.Close();
Исключение
ЗаписатьЛогОшибки(ОписаниеОшибки());
ВызватьИсключение;
КонецПопытки;
Возврат Истину;
КонецФункции
Этот способ универсален, работает как на тонком, так и на толстом клиенте, и полностью соответствует стандартам разработки фирмы «1С».
Если вы работаете в устаревшем режиме «Обычного приложения» (толстый клиент) и вам по какой-то причине необходимо обратиться к открытой форме напрямую, вы можете передать саму форму в качестве параметра в общий модуль.
Код в модуле формы:
Процедура КнопкаВыполнитьНажатие(Кнопка)
// Передаем ссылку на текущую форму (ЭтаФорма) в общий модуль
РаботаСВнешнимиБД.fnc_search_1C_SQL("Товары", "Штрихкод", ЭтаФорма);
КонецПроцедуры
Код в общем модуле:
Функция fnc_search_1C_SQL(a_table, a_value, ФормаSQL) Экспорт
// Получаем значения полей ввода напрямую из элементов формы
ИмяСервераSQL = ФормаSQL.ЭлементыФормы.ПолеИмяСервераSQL.Значение;
ПользовательSQL = ФормаSQL.ЭлементыФормы.ПолеПользовательSQL.Значение;
ПарольSQL = ФормаSQL.ЭлементыФормы.ПолеПарольSQL.Значение;
// Выполнение подключения...
КонецФункции
Важное предупреждение: Для управляемого приложения этот способ не подходит. В управляемых формах элементы формы (свойство Элементы) существуют только на клиенте и не могут быть переданы на сервер, где обычно выполняются функции общих модулей. Попытка передать форму на сервер вызовет ошибку сериализации.
Посмотрим на ситуацию шире. Если форма предназначена для настройки подключения к SQL-серверу, заставлять пользователя вводить эти данные при каждом запуске крайне неудобно. Кроме того, хранить пароли в открытом виде небезопасно.
Рассмотрим, как правильно организовать хранение таких данных:
ADODB.Connection накладывает ограничение: этот механизм работает только в операционной системе Windows. Если сервер приложений 1С работает под управлением ОС Linux, использование COM-объектов вызовет ошибку. Для кроссплатформенной работы рекомендуется использовать встроенный механизм платформы — Внешние источники данных.