При разработке сложных управляемых форм в платформе 1С:Предприятие 8.3 программисты нередко сталкиваются с ситуацией, когда стандартный элемент интерфейса Планировщик неожиданно начинает вызывать системные ошибки вида «Ошибка сценария» (Script Error). Проблема часто проявляется при попытке переключить вкладку формы, при динамическом добавлении новых точек/элементов или при изменении масштаба шкалы времени, причем явный стек вызовов встроенного языка 1С может отсутствовать.
Разберем детально внутреннее устройство элемента Планировщик, выясним первопричины сбоев рендеринга и рассмотрим пошаговые методы исправления данной ошибки в управляемом приложении.
Для понимания источника ошибки проанализируем, как платформа 1С визуализирует элемент Планировщик на клиенте под управлением операционной системы Windows:
Планировщик (аналогично элементам ПолеHTMLДокумента и ФорматированныйДокумент) в тонком клиенте традиционно отрисовывается с помощью системных компонентов браузера Internet Explorer (движок MSHTML/Trident).Рассмотрим две ключевые причины, из-за которых планировщик завершает работу аварийно, и разберем практические способы их решения.
Самая распространенная ошибка в прикладном коде — передача в коллекцию Элементы планировщика некорректных временных интервалов. Если дата окончания меньше даты начала, одна из дат пустая (значение '00010101000000') или не задана корректно граница в свойстве ТекущиеПериодыОтображения, движок JavaScript не может вычислить ширину блока в пикселях и падает с ошибкой.
Разберем по шагам, как правильно валидировать данные перед заполнением планировщика:
ТекущиеПериодыОтображения планировщика корректным диапазоном.Посмотрим на пример безопасного заполнения планировщика на клиенте или сервере:
// Очищаем существующие элементы планировщика
Элементы.Планировщик.Элементы.Очистить();
// Задаем явный период отображения планировщика
Элементы.Планировщик.ТекущиеПериодыОтображения.Очистить();
ИнтервалОтображения = Новый ИнтервалВремени(НачалоДня(ТекущаяДата()), КонецДня(ТекущаяДата()));
Элементы.Планировщик.ТекущиеПериодыОтображения.Добавить(ИнтервалОтображения);
// Заполнение элементов с предварительной валидацией интервалов
Для Каждого СтрДанных Из ТаблицаЗадач Цикл
// Проверяем заполненность дат
Если Не ЗначениеЗаполнено(СтрДанных.ДатаНачала) Или Не ЗначениеЗаполнено(СтрДанных.ДатаОкончания) Тогда
Продолжить;
КонецЕсли;
// Исключаем инвертированные интервалы
Если СтрДанных.ДатаНачала > СтрДанных.ДатаОкончания Тогда
// Корректируем даты либо пропускаем некорректную строку
ДатаНачала = СтрДанных.ДатаОкончания;
ДатаОкончания = СтрДанных.ДатаНачала;
Иначе
ДатаНачала = СтрДанных.ДатаНачала;
ДатаОкончания = СтрДанных.ДатаОкончания;
КонецЕсли;
// Безопасное добавление элемента в планировщик
НовыйЭлемент = Элементы.Планировщик.Элементы.Добавить(ДатаНачала, ДатаОкончания);
НовыйЭлемент.Текст = СтрДанных.ПредставлениеЗадачи;
НовыйЭлемент.Значение = СтрДанных.Ссылка;
КонецЦикла;
Второй частый сценарий возникновения ошибки — размещение элемента Планировщик внутри подчиненной страницы группы страниц (вкладки), которая в момент открытия формы или обновления данных является неактивной.
Проанализируем механизм проявления проблемы: пока вкладка скрыта, визуальный контейнер элемента в DOM-структуре имеет нулевые размеры (Ширина = 0, Высота = 0). Если в этот момент программно инициируется перерисовка или расчет временной шкалы, скрипт рендеринга выдает исключение при расчете координатной сетки. При последующем переключении пользователя на эту страницу окно браузера отображает накопленную ошибку скрипта.
Для предотвращения этой проблемы используем подход с отложенной инициализацией планировщика:
ПриСозданииНаСервере или ПриОткрытии, если вкладка с планировщиком не является активной по умолчанию.ПриСменеСтраницы для родительской панели страниц.Рассмотрим программную реализацию отложенной отрисовки:
&НаКлиенте
Процедура ГруппаСтраницыПриСменеСтраницы(Элемент, ТекущаяСтраница)
// Проверяем, что пользователь переключился именно на страницу с планировщиком
Если ТекущаяСтраница = Элементы.СтраницаПланировщик Тогда
// Если планировщик еще не был заполнен, выполняем первичное заполнение
Если Не ПланировщикИнициализирован Тогда
ОбновитьДанныеПланировщикаНаСервере();
ПланировщикИнициализирован = Истина;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ОбновитьДанныеПланировщикаНаСервере()
// Выполняем выборку и безопасное заполнение шкалы и элементов
СформироватьСеткуПланировщика();
КонецПроцедуры
Разберем сопутствующие настройки окружения, которые снижают вероятность подобных сбоев при интенсивной работе с графическими элементами:
ШкалаВремени убедитесь, что минимальный шаг шкалы времени (например, минуты, часы, дни) кратен общему отображаемому диапазону, чтобы исключить дробные пиксельные нестыковки в JavaScript.Таким образом, для устранения ошибки сценария в планировщике необходимо убедиться в строгой валидности всех передаваемых интервалов дат и исключить попытки перерисовки элемента, находящегося на неактивной странице управляемой формы.