В процессе разработки в среде 1С:Предприятие программисты часто сталкиваются с ситуацией, когда внесенные в макет печатной формы (MXL) изменения «не подхватываются» системой. Вы правите ячейки, меняете тип заполнения с «Текст» на «Параметр», перекрашиваете фон или меняете шрифт, но при выводе на печать пользователь по-прежнему видит старый вариант макета. Рассмотрим подробнее, почему это происходит, проанализируем причины возникновения «фантомных» макетов и разберем по шагам методы борьбы с этим явлением, включая последствия так называемого «демонического» (динамического) обновления.
Типичный сценарий проблемы выглядит так: в документе или справочнике существует макет печатной формы. Разработчик вносит изменения в конфигураторе, прописывает код для заполнения новых параметров, но при запуске получает ошибку «Поле объекта не обнаружено» или «Параметр не найден», так как система обращается к старой версии макета, где этих параметров еще нет. Если же подавить ошибку, выводится старый текст-заглушка.
Первым делом проанализируем ситуацию: не является ли этот макет «пользовательским». В современных конфигурациях на базе БСП (Библиотека стандартных подсистем) пользователи могут переопределять макеты в режиме «Предприятие» (Администрирование — Печатные формы, отчеты и обработки — Макеты печатных форм). Если там создана индивидуальная настройка макета, то изменения в конфигураторе не будут видны, пока пользовательский макет не будет удален или обновлен. Однако, если конфигурация самописная и БСП не используется, причину нужно искать глубже — в механизмах кэширования и обновления конфигурации. Для работы с пользовательскими настройками макетов подойдёт руководство по редактированию печатных форм в типовых конфигурациях.
Самое очевидное решение, которое мы всегда пробуем первым — это очистка локального кэша. 1С сохраняет структуры метаданных во временных папках пользователя для ускорения работы. Выясним, где они находятся:
%AppData%\Local\1C\1cv8\%AppData%\Roaming\1C\1cv8\Обычно удаление папок с длинными буквенно-цифровыми именами (GUID) решает проблему. Но, как показывает практика, при серьезных сбоях динамического обновления чистка только клиентского кэша не помогает. Существует также серверный кэш (на стороне сервера приложений 1С), который находится в каталоге службы (например, reg_1541). Если перезагрузка службы сервера 1С не помогает, это верный признак того, что проблема зафиксировалась в самой базе данных.
Динамическое обновление — это механизм, позволяющий вносить изменения в конфигурацию без выгона пользователей. Несмотря на удобство, это основной источник проблем с «зависанием» старых версий объектов. Проанализируем механизм сбоя: при динамическом обновлении платформа не заменяет основную конфигурацию полностью, а создает «дополнительный слой» изменений. В таблице Config базы данных SQL могут накопиться некорректные записи, из-за чего сеанс пользователя (или даже фоновое задание) продолжает считывать бинарные данные старого макета.
Симптомы сбоя динамического обновления:
Разберем последовательность действий, если стандартная чистка кэша не принесла результатов.
Посмотрим на пример правильного цикла обновления. Вместо динамического обновления («Обновить конфигурацию базы данных» при наличии активных пользователей) необходимо выполнить следующие шаги:
Если макет «заклинило», попробуем заставить платформу создать новую запись в таблице конфигурации с новым уникальным идентификатором. Для этого выполним следующее:
Этот метод часто помогает, так как для 1С это становится абсолютно новым объектом, и старые кэшированные связи разрываются.
Рассмотрим ситуацию, когда в SQL-версии базы данных «висят» две конфигурации. Это критическая ошибка целостности. В таблице Config (или DBSchema) могут оставаться записи, которые система считает актуальными ошибочно. Внимание: любые действия напрямую в SQL-базе крайне опасны и должны производиться только после создания резервной копии!
Обычно специалисты анализируют таблицу Config. Если в ней присутствуют дублирующие записи для одного и того же объекта (файла внутри конфигурации), одну из них (более старую) необходимо удалить. Однако более безопасным способом является выполнение «Загрузки конфигурации» (Конфигурация — Загрузить конфигурацию из файла .cf). Это полностью перезаписывает таблицу Config, удаляя все накопившиеся «хвосты» динамических обновлений.
Проанализируем современный подход к оперативным правкам. Чтобы не рисковать стабильностью основной конфигурации и не прибегать к динамическому обновлению, рекомендуется использовать Расширения конфигурации.
Разберем этот процесс по шагам:
Макеты в расширениях имеют приоритет над макетами основной конфигурации. Это позволяет избежать конфликтов на уровне бинарных данных основной базы. После того как в конце рабочего дня будет возможность монопольно обновить основную конфигурацию, изменения можно перенести из расширения в «основу», а само расширение удалить.
Чтобы окончательно убедиться, что система видит нужный нам макет, можно временно добавить в код проверки. Рассмотрим пример кода, который выводит количество параметров в области макета, чтобы понять, тот ли макет подгрузился:
Макет = Документы.НашДокумент.ПолучитьМакет("Печать");
Попытка
Область = Макет.ПолучитьОбласть("Заголовок");
// Проверим наличие нового параметра программно
Если Область.Параметры.Свойство("НовыйПараметрСДатой") Тогда
Сообщить("Макет обновлен, параметр найден.");
Иначе
Сообщить("ВНИМАНИЕ: Выводится старый макет без нового параметра!");
КонецЕсли;
Исключение
Сообщить("Ошибка при получении области: " + ОписаниеОшибки());
КонецПопытки;
Подводя итог, можно сказать, что «зависание» старого макета — это почти всегда следствие нарушения целостности кэша или сбоя динамического обновления. Выясним главные правила, которые помогут избежать этой проблемы в будущем:
Таким образом, мы рассмотрели все основные причины проблемы и методы их решения, от простых манипуляций с кэшем до серьезных исправлений на уровне базы данных.