При разработке конфигураций на платформе 1С:Предприятие в управляемом приложении разработчики нередко сталкиваются с ситуацией, когда внутри общего модуля объявляются клиентская и серверная процедуры, и при попытке вызвать серверную процедуру из клиентской платформа выдает ошибку: «Процедура или функция не определена», либо при явном указании имени модуля — «Переменная не определена <ИмяМодуля>».
Проанализируем причины такого поведения платформы 1С, выясним внутреннюю механику компиляции общих модулей и разберем по шагам, как правильно структурировать код в соответствии со стандартами разработки.
Рассмотрим, что происходит, когда в свойствах общего модуля одновременно включены флаги «Клиент (управляемое приложение)» и «Сервер»:
&НаСервере или внутри блока препроцессора #Если Сервер Тогда), она физически отсутствует в клиентском экземпляре модуля. Клиентский контекст о ней ничего не знает, поэтому прямой вызов по локальному имени приводит к ошибке «Процедура или функция не определена».Разберем основной и правильный способ решения задачи согласно стандартам 1С. Если процедура должна выполнять серверные действия (обращаться к базе данных, выполнять запросы, работать с серверными объектами), ее необходимо разместить в отдельном специализированном модуле.
ВызовСервера (например, ОбщегоНазначенияВызовСервера).«Сервер» — включен.
«Вызов сервера» — включен.
«Клиент (управляемое приложение)» — выключен.
Процедура ВыполнитьСервернуюОперациюНаСервере(Параметр1) Экспорт
// Серверная логика, работа с базой данных
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";
Результат = Запрос.Выполнить();
КонецПроцедуры
Процедура КлиентскаяПроцедура() Экспорт
ПараметрДанных = "ТестовоеЗначение";
// Вызов серверного модуля
ОбщегоНазначенияВызовСервера.ВыполнитьСервернуюОперациюНаСервере(ПараметрДанных);
КонецПроцедуры
Проанализируем ситуацию, когда алгоритм не обращается к базе данных и не требует переключения контекста между клиентом и сервером. Это могут быть математические расчеты, обработка строк, преобразование дат или работа со структурами данных.
В таком случае правильным решением является создание единого универсального модуля:
&НаКлиенте, &НаСервере) и конструкции препроцессора. Код процедур пишется на чистом клиент-серверном подмножестве языка 1С.
Функция СформироватьСтроку(Значение1, Значение2) Экспорт
Возврат СокрЛП(Значение1) + " / " + СокрЛП(Значение2);
КонецФункции
Процедура ОбработатьДанные(СтруктураДанных) Экспорт
РезультатСтрока = СформироватьСтроку(СтруктураДанных.Поле1, СтруктураДанных.Поле2);
СтруктураДанных.Вставить("ПолноеНаименование", РезультатСтрока);
КонецПроцедуры
В таком варианте процедура ОбработатьДанные доступна и на клиенте, и на сервере без дополнительных сетевых вызовов, локально в том контексте, где она была вызвана.
Посмотрим на общую классификацию общих модулей, принятую в типовых конфигурациях 1С:
КлиентСервер: флаги Клиент (управляемое приложение) и Сервер. Служат для вспомогательных вычислений, валидации структур и строк без обращения к базе данных. Флаг Вызов сервера отключен.ВызовСервера: флаги Сервер и Вызов сервера. Представляют собой тонкий API-фасад для вызова серверного функционала из клиентских модулей и форм.Сервер (или без суффикса): флаг Сервер. Содержат основную бизнес-логику, недоступную напрямую с клиента.Клиент: флаг Клиент (управляемое приложение). Содержат логику открытия окон, интерфейсных вопросов и взаимодействия с пользователем.Рассмотрим ключевые технические ограничения, о которых необходимо помнить при вызове процедур через модули с признаком «Вызов сервера»:
СправочникОбъект, ДокументОбъект, ТаблицаЗначений, ДеревоЗначений. В параметры серверных процедур можно передавать только ссылки (СправочникСсылка, ДокументСсылка), примитивные типы (число, строка, дата, булево), а также универсальные коллекции (Структура, Массив, Соответствие).*ВызовСервера внутри циклов клиентского кода. Если требуется обработать набор данных, формируйте массив или структуру на клиенте и передавайте их на сервер одним вызовом.