При переходе на работу через веб-клиент или после обновления платформы «1С:Предприятие 8.3» разработчики нередко сталкиваются с неожиданным сбоем. Стандартный и привычный метод вывода печатной формы ТабличныйДокумент.Показать() на стороне клиента падает с критической ошибкой: «Процедура или функция с указанным именем не определена (StrSplit)» (или аналогичной ошибкой для метода StrFind). При этом в тонком клиенте этот же самый код отрабатывает абсолютно корректно.
Разберем детально механизм возникновения данной проблемы, выясним внутренние причины конфликта платформы и конфигурации, а также рассмотрим несколько способов надежного решения задачи.
Рассмотрим типовой сценарий, в котором воспроизводится ошибка. На клиенте инициируется команда печати, на сервере формируется табличный документ, после чего объект возвращается на сторону клиента и вызывается метод отображения:
&НаКлиенте
Процедура ОткрытьФормуПечатиСкладскихБирокЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если ТипЗнч(Результат) = Тип("Структура") Тогда
П = Результат;
// Проверяем, что табличный документ не пустой
Если П.ТабДок.Области.Количество() > 0 Тогда
П.ТабДок.Показать(); // На этой строке в веб-клиенте происходит ошибка StrSplit
КонецЕсли;
КонецЕсли;
КонецПроцедуры
В тексте нашей собственной конфигурации явный вызов функции StrSplit или СтрРазделить может отсутствовать вовсе. Ошибка возникает глубоко в недрах движка веб-клиента платформы 1С.
Проанализируем цепочку взаимосвязей в архитектуре платформы:
СтрРазделить (в англоязычном синтаксисе StrSplit) и СтрНайти (StrFind).Версия 8.3.5 или ниже), платформа принудительно отключает эти встроенные методы из глобального контекста для обеспечения обратной совместимости прикладного кода.ТабличныйДокумент.Показать() пытается напрямую обращаться к глобальным методам разбора строк StrSplit. Если режим совместимости не позволяет платформе предоставить эти функции, веб-клиент аварийно завершает работу с исключением об отсутствии объявленной функции.Ниже подробно рассмотрим все варианты устранения ошибки: от системного решения до временных программных заглушек.
Самое правильное и системное решение проблемы — разрешить конфигурации использовать современные возможности платформы 1С.
После включения режима совместимости 8.3.6+ функции StrSplit и StrFind автоматически появятся в глобальном контексте веб-клиента, и встроенный механизм отображения табличных документов заработает в штатном режиме.
Бывают ситуации, когда конфигурация снята с поддержки, сильно доработана или зависит от сторонних библиотек, из-за чего моментально повысить режим совместимости невозможно. В таком случае применим обходной программный путь: объявим недостающие платформенные функции вручную в глобальной клиентской области видимости.
Откроем Модуль управляемого приложения (а при необходимости работы в обычном приложении — и Модуль обычного приложения) и добавим в конец модуля следующий код:
#Область ПрограммныеЗаглушкиДляВебКлиента
// Функция эмулирует системную функцию СтрРазделить / StrSplit для старых режимов совместимости
Функция StrSplit(ИсходнаяСтрока, Разделитель = ",", ВключатьПустые = Истина) Экспорт
// Если в конфигурации подключена Библиотека Стандартных Подсистем (БСП):
Возврат СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ИсходнаяСтрока, Разделитель, ВключатьПустые);
КонецФункции
// Функция эмулирует системную функцию СтрНайти / StrFind для старых режимов совместимости
Функция StrFind(ИсходнаяСтрока, ПодстрокаПоиска, НаправлениеПоиска = Неопределено, НачальнаяПозиция = 1, НомерВхождения = 1) Экспорт
// Используем базовую встроенную функцию платформы Найти()
Возврат Найти(ИсходнаяСтрока, ПодстрокаПоиска);
КонецФункции
#КонецОбласти
Если в вашей конфигурации не используется БСП, функцию StrSplit можно реализовать на чистом встроенном языке 1С без использования внешних библиотек:
Функция StrSplit(Знач ИсходнаяСтрока, Знач Разделитель = ",", Знач ВключатьПустые = Истина) Экспорт
Результат = Новый Массив;
Если ПустаяСтрока(Разделитель) Тогда
Результат.Добавить(ИсходнаяСтрока);
Возврат Результат;
КонецЕсли;
Позиция = Найти(ИсходнаяСтрока, Разделитель);
Пока Позиция > 0 Цикл
Подстрока = Лев(ИсходнаяСтрока, Позиция - 1);
Если ВключатьПустые Или Не ПустаяСтрока(Подстрока) Тогда
Результат.Добавить(Подстрока);
КонецЕсли;
ИсходнаяСтрока = Сред(ИсходнаяСтрока, Позиция + СтрДлина(Разделитель));
Позиция = Найти(ИсходнаяСтрока, Разделитель);
КонецЦикла;
Если ВключатьПустые Или Не ПустаяСтрока(ИсходнаяСтрока) Тогда
Результат.Добавить(ИсходнаяСтрока);
КонецЕсли;
Возврат Результат;
КонецФункции
Экспортные функции в Модуле управляемого приложения попадают в глобальное пространство имен веб-клиента, благодаря чему внутренний скрипт отображения табличного документа успешно находит нужный метод и завершает отрисовку без падения.
Рассмотрим архитектурный нюанс: вызов метода ТабличныйДокумент.Показать() в веб-клиенте генерирует отдельное браузерное всплывающее окно (pop-up). Большинство современных браузеров (Google Chrome, Mozilla Firefox, Safari, Яндекс.Браузер) по умолчанию блокируют всплывающие окна. В результате пользователь видит пустой экран либо документ не открывается вовсе.
Для надежной работы в веб-клиенте рекомендуется выводить табличные документы через специализированную форму просмотра.
ФормаПросмотраПечатнойФормы.ПечатнаяФорма с типом ТабличныйДокумент и разместим его на форме как элемент Поле табличного документа.
&НаКлиенте
Процедура ОткрытьПечатнуюФорму(ТабДок)
ПараметрыОткрытия = Новый Структура;
ПараметрыОткрытия.Вставить("ТабличныйДокумент", ТабДок);
ОткрытьФорму("ОбщаяФорма.ФормаПросмотраПечатныхФорм", ПараметрыОткрытия);
КонецПроцедуры
В модуле самой формы отображения прочитаем переданный документ при создании на сервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("ТабличныйДокумент") Тогда
ПечатнаяФорма = Параметры.ТабличныйДокумент;
КонецЕсли;
КонецПроцедуры
Такой подход полностью исключает конфликты с блокировщиками всплывающих окон браузера, не зависит от ошибок внутренних скриптов метода Показать() и предоставляет пользователю стабильный интерфейс работы с печатной формой во всех браузерах.
Подведем итог и выберем оптимальный вариант в зависимости от условий:
StrSplit и StrFind в Модуль управляемого приложения.Поле табличного документа либо используем механизмы подсистемы «Печать» БСП с сохранением в PDF.