Переход с файлового варианта базы данных на клиент-серверный (SQL) — это важный этап масштабирования системы 1С:Предприятие. Однако этот процесс часто сопровождается выявлением скрытых ошибок в коде, которые «удачно» работали в файловом режиме, но приводят к полной неработоспособности механизмов в клиент-серверной архитектуре. Одной из таких проблем является внезапный «отказ» обработки открываться без видимых причин и сообщений об ошибках.
В данной статье мы подробно разберем ситуацию, когда внешняя обработка успешно функционирует в файловой базе, но после загрузки в SQL-вариант перестает запускаться. Рассмотрим причины этого поведения, проанализируем работу препроцессора и выясним, как правильно организовать проверки контекста выполнения.
Рассмотрим типичную ситуацию. Разработчик использует процедуру ПриСозданииНаСервере в модуле формы обработки для проверки условий запуска. В коде присутствует ограничение, разрешающее работу только в определенном типе клиента. Пример кода, который вызывает проблему:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
#Если НЕ ТолстыйКлиентУправляемоеПриложение Тогда
Отказ = Истина;
#КонецЕсли
КонецПроцедуры
В файловом варианте этот код может работать корректно, если пользователь запускает базу через Толстый клиент. Однако в клиент-серверном варианте при попытке открыть форму ничего не происходит: форма просто не появляется на экране, не выдавая никаких предупреждений. Выясним причину такого поведения.
Главная причина кроется в том, как платформа 1С интерпретирует инструкции препроцессора (команды, начинающиеся с символа #) в разных режимах работы.
1. Файловый вариант: В этой архитектуре клиентское приложение и серверная часть (база данных) работают, по сути, в рамках одного процесса на компьютере пользователя. Граница между «клиентом» и «сервером» здесь размыта. Инструкции препроцессора типа #Если ТолстыйКлиентУправляемоеПриложение могут возвращать значение Истина даже в серверных процедурах, так как контекст клиента доступен приложению напрямую.
2. Клиент-серверный вариант (SQL): Здесь происходит строгое разделение. Код с директивой &НаСервере физически выполняется на сервере приложений 1С (rphost). Сервер 1С — это не «Толстый клиент» и не «Тонкий клиент». Это отдельный программный слой. Поэтому, когда препроцессор на стороне сервера встречает проверку #Если ТолстыйКлиентУправляемоеПриложение, он всегда оценивает ее как Ложь.
Следовательно, условие в нашем примере всегда срабатывает, переменной Отказ присваивается значение Истина, и платформа штатно прекращает открытие формы. Так как разработчик не предусмотрел вывод сообщения для пользователя, система просто «молча» отменяет действие.
Проанализируем ситуацию, когда программист пытается отладить код, но отладчик игнорирует точки останова в процедуре ПриСозданииНаСервере. В SQL-базах это происходит по двум причинам:
-debug.Для решения проблемы разберем несколько шагов. Рассмотрим первый и самый очевидный вариант — удаление избыточных проверок.
Если ваша управляемая форма написана по стандартам разработки 1С 8.3, она должна быть универсальной. Проверка на «Толстый клиент» в серверном контексте чаще всего является анахронизмом. Если код внутри формы использует только стандартные серверные методы, смело удаляйте блок #Если...#КонецЕсли. После этого форма начнет открываться в любом режиме.
Если проверка действительно необходима (например, вы используете специфические COM-объекты, доступные только в Толстом клиенте), никогда не делайте «тихий» отказ. Рассмотрим, как правильно модифицировать код:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Проверка должна быть логической, а не через препроцессор,
// если мы хотим анализировать свойства сеанса.
// Но препроцессор на сервере не знает о типе клиента.
// Если нужно проверить тип клиента на сервере, используем методы системы:
Если НЕ (ТипЗнч(ТерминальнаяСессия) = Тип("Неопределено")) Тогда // Пример логики
// Логика проверки
КонецЕсли;
// Если всё же используем препроцессор для разделения кода:
#Если ТонкийКлиент ИЛИ ВебКлиент Тогда
// Этот код вообще не скомпилируется на сервере в SQL-варианте внутри &НаСервере
#КонецЕсли
КонецПроцедуры
Важный совет: Чтобы пользователь не гадал, почему форма не открылась, используйте метод Сообщить() или ОбщегоНазначенияКлиентСервер.СообщитьПользователю() перед установкой отказа.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
#Если НЕ ТолстыйКлиентУправляемоеПриложение И НЕ Сервер Тогда
// Данная логика в &НаСервере всегда будет вести к Отказу в SQL
Сообщить("Данная обработка предназначена только для запуска в толстом клиенте!");
Отказ = Истина;
#КонецЕсли
КонецПроцедуры
Выясним еще одну причину, по которой загрузка данных может не работать после перехода на SQL. Если ваша обработка работает с внешними файлами (Excel, CSV), помните:
&НаСервере выполняется от имени пользователя, под которым запущена служба сервера 1С (обычно это системная учетная запись USR1CV8).Рассмотрим ситуацию: вы пытаетесь прочитать файл по сетевому пути \\Server\Share\file.xls. Даже если у вас есть доступ к этой папке, у службы сервера 1С его может не быть. В этом случае процедура может завершиться ошибкой или «пустым» результатом, что также создаст иллюзию неработоспособности обработки.
Подведем итог. Чтобы ваша обработка успешно работала в SQL-базе:
Отказ = Истина должен сопровождаться поясняющим сообщением.