При изучении методической литературы по платформе 1С:Предприятие можно встретить утверждение, что имена всех экспортируемых процедур и функций в конфигурации должны быть строго уникальными, иначе система выдаст синтаксическую ошибку из-за дублирования в глобальном контексте. Однако на практике разработчики часто создают методы с одинаковыми именами (например, Печать() или ЗаполнитьДанные()) в разных общих модулях, и конфигурация сохраняется без каких-либо предупреждений. Разберем по шагам, почему возникает такое противоречие, как именно платформа управляет пространствами имен и в каких случаях конфликт имен действительно приводит к ошибке.
Выясним причину расхождения между старыми учебниками и реальным поведением системы. В версии платформы 1С:Предприятие 8.0 все общие модули были исключительно глобальными. Это означало, что все объявленные с ключевым словом Экспорт процедуры и функции автоматически помещались в единый глобальный контекст конфигурации. В такой архитектуре две процедуры с одинаковым именем неизбежно приводили к коллизии.
Начиная с версии 8.1, а затем и в 8.2, 8.3 концепция изменилась: разработчикам предоставили возможность создавать неглобальные общие модули, у которых флаг Глобальный снят. Однако в некоторых переводных и переизданных методических пособиях устаревшее описание из версии 8.0 переходило из редакции в редакцию без уточнения о глобальности модуля.
Рассмотрим подробнее механизм вызова и регистрации процедур для каждого типа модулей:
ОбщийМодуль). Экспортные методы не попадают в глобальную область напрямую, а вызываются исключительно через точку от имени модуля. Пространство имен каждого неглобального модуля полностью изолировано, поэтому одинаковые имена процедур в разных модулях не конфликтуют:
// Вызов методов с одинаковым именем из разных неглобальных модулей
МодульА.Первая();
МодульБ.Первая();
ИмяМодуля.ИмяПроцедуры() невозможно (возникнет ошибка компиляции «Переменная не определена»). В глобальный контекст экспортируются только сами процедуры и функции. Вызов происходит напрямую по имени:
// Прямой вызов глобального метода без указания имени модуля
Первая();
Проанализируем ситуацию, при которой платформа выдаст синтаксическую ошибку. Для воспроизведения коллизии должны одновременно выполниться три условия:
// В модуле МодульА
Процедура Первая() Экспорт
// Код процедуры
КонецПроцедуры
// В модуле МодульБ
Процедура Первая() Экспорт
// Код процедуры
КонецПроцедуры
Экспорт отсутствует, процедура является локальной для своего модуля, не попадает в глобальный контекст и ошибки не вызывает.Обратим внимание на важную деталь: глобальный контекст на стороне клиента и глобальный контекст на стороне сервера изолированы друг от друга. Проверка на уникальность имен экспортных процедур выполняется только в рамках одного контекста компиляции.
Посмотрим на пример: если модуль МодульА является глобальным со свойством Сервер, а модуль МодульБ — глобальным со свойством Клиент (управляемое приложение), то одноименная экспортная процедура Первая() не вызовет синтаксической ошибки. На сервере будет доступна серверная версия метода, а на клиенте — клиентская.
Разберем, что происходит при совпадении имени глобальной процедуры с локальными методами или системными функциями:
Первая() внутри этого объекта обратится именно к локальной процедуре.Сообщить или Формат), платформа зафиксирует ошибку еще на этапе проверки конфигурации.Проанализируем влияние глобальных модулей на работу конфигурации в целом:
ПодключитьОбработчикОжидания()), либо глобальные функции для выражений в Системе компоновки данных (СКД).Таким образом, для большинства прикладных задач следует использовать неглобальные модули: они защищают код от случайных коллизий имен, ускоряют запуск конфигурации и делают структуру решения прозрачной и модульной.