В процессе разработки на платформе 1С:Предприятие 8.3 программисты иногда сталкиваются с ситуациями, которые буквально заставляют усомниться в адекватности системы. Одной из таких проблем является отсутствие реакции синтаксического контроля на наличие в одном модуле двух абсолютно идентичных функций. Давайте подробно проанализируем, почему это происходит, как механизмы кэширования могут вводить разработчика в заблуждение и какими методами можно победить этот «призрачный» баг.
Рассмотрим классическую ситуацию, описанную участниками сообщества. В модуле управляемой формы создаются две функции с одинаковыми именами, помеченные директивой компиляции &НаСервереБезКонтекста. Логично ожидать, что при сохранении или проверке модуля (Ctrl+F7) система выдаст ошибку о дублировании имен. Однако в некоторых релизах платформы (особенно часто это упоминается для ветки 8.3.16) этого не происходит.
Посмотрим на пример кода, который может вызвать подобное поведение:
&НаСервереБезКонтекста
Функция ПолучитьПараметрыВыгрузки(ОбъектВыгрузки = "", МассивРеквизитовВыгрузки = Неопределено)
// Логика первой функции
КонецФункции
&НаСервереБезКонтекста
Функция ПолучитьПараметрыВыгрузки(Параметры = Неопределено)
// Логика второй функции
КонецФункции
Проблема заключается в том, что разработчик может работать с кодом, вносить изменения в одну функцию, а при выполнении программы 1С будет вызывать совершенно другую — ту, что была определена первой или сохранена в кэше ранее. Это создает крайне опасную ситуацию для стабильности системы, так как ошибку можно обнаружить только при отладке.
Проанализируем, почему платформа ведет себя подобным образом. Основная причина кроется в архитектуре компиляции модулей 1С. Директива &НаСервереБезКонтекста указывает системе, что данная функция должна быть скомпилирована отдельно от контекста формы, что делает ее технически похожей на метод общего модуля. В платформе реализована так называемая инкрементальная компиляция и «ленивая» проверка имен.
Когда мы нажимаем кнопку сохранения модуля, система старается сэкономить ресурсы и проверяет только те части дерева вызовов, которые претерпели значительные изменения. Если функции с директивой бесконтекстного вызова обрабатываются в разных проходах компилятора, проверка на уникальность имен внутри модуля может попросту «пропустить» дубликат, если на него нет явных вызовов в текущем коде.
Интересно, что при добавлении третьей функции с тем же именем платформа часто «просыпается» и начинает ругаться на все три. Это происходит потому, что критическая масса изменений заставляет систему полностью перестроить таблицу идентификаторов модуля, сбрасывая старые результаты проверки.
Самый быстрый и эффективный способ борьбы с любыми странностями поведения платформы — очистка локального кэша. Платформа 1С хранит скомпилированные образы модулей в пользовательских папках AppData. Если данные в кэше рассинхронизировались с реальным текстом модуля в базе данных, возникают подобные «глюки».
Для решения этой проблемы рекомендуется использовать параметр запуска /ClearCache. Рассмотрим, как это сделать:
/ClearCache.Этот параметр заставляет платформу игнорировать локальные временные файлы при запуске сеанса и заново получать актуальные данные из конфигурации базы данных.
Стандартная проверка модуля по нажатию Ctrl+F7 является поверхностной. Для того чтобы заставить платформу выполнить глубокий анализ всех взаимосвязей и уникальности имен, необходимо использовать встроенный инструмент проверки конфигурации.
Разберем шаги для выполнения полной проверки:
Такой подход игнорирует результаты предыдущих инкрементальных проверок и выполняет полный синтаксический разбор всего кода конфигурации, что гарантированно выявит дублирующиеся функции.
В особо тяжелых случаях, когда даже очистка локального кэша не помогает (например, при работе в файловом режиме или при использовании распределенных баз), можно прибегнуть к хитрости с изменением версии конфигурации. Каждая конфигурация имеет внутренний номер версии. При его изменении платформа считает, что база глобально обновилась, и принудительно обновляет кэш на всех клиентах.
Проанализируем алгоритм действий:
Это действие инициирует обновление таблицы ConfigSave и заставляет механизмы платформы пересмотреть все закэшированные объекты. Это часто помогает в случаях, когда после «Загрузки конфигурации из файла» в базе остаются «фантомные» куски старого кода.
Чтобы не стать жертвой «сырости» некоторых релизов платформы, стоит придерживаться нескольких правил при разработке:
Подводя итог, можно сказать, что проблема дублирования функций &НаСервереБезКонтекста — это классический пример того, как оптимизация производительности (кэширование) может идти в ущерб корректности разработки. Понимание механизмов работы платформы позволяет быстро диагностировать такие ситуации и устранять их стандартными средствами администрирования 1С.