Каждый разработчик 1С рано или поздно сталкивается с ситуациями, когда код, идеально работающий в интерактивном сеансе под его учетной записью, внезапно ломается или ведет себя непредсказуемо при выполнении в фоновом или регламентном задании. Одним из ярких примеров такого "мистического" поведения является работа системной функции СтрокаСоединенияИнформационнойБазы().
В этой статье мы подробно разберем, почему имя базы или сервера может неожиданно менять регистр букв, подменяться на другие значения при фоновом выполнении, проанализируем причины такого поведения платформы «1С:Предприятие» и выработаем универсальные, отказоустойчивые шаблоны кода для безопасного сравнения параметров подключения.
Разберем детально, почему при вызове одной и той же функции СтрокаСоединенияИнформационнойБазы() на клиенте мы получаем, например, Ref="ut", а в фоновом задании на сервере — Ref="UT". Причина кроется в разных источниках данных, к которым обращается платформа для формирования этой строки в зависимости от контекста исполнения.
Проанализируем эти контексты:
ibases.v8i (стартер 1С). Как именно администратор или пользователь написал имя базы при добавлении в список (например, строчными буквами: Ref="ut"), именно в таком виде функция и вернет строку соединения.rphost) под служебной учетной записью (например, USR1CV8). У сервера нет доступа к файлу ibases.v8i конкретного пользователя. Поэтому менеджер кластера считывает параметры подключения непосредственно из своего собственного реестра — файла настроек кластера 1CV8Reg.lst, расположенного в каталоге srvinfo на сервере. Соответственно, фоновое задание возвращает строку подключения ровно в том виде и регистре, в котором база была зарегистрирована в консоли администрирования серверов 1С (например, Ref="UT").Различие регистра в имени базы (параметр Ref) — это лишь вершина айсберга. При жестком сравнении строк "в лоб" разработчик рискует наступить на следующие скрытые грабли:
Srvr): На сервере имя может быть записано как Srvr="SERVER", а у пользователя в стартере — Srvr="server" или Srvr="server.domain.local".Srvr="localhost", тогда как у пользователя в настройках будет прописано реальное сетевое имя компьютера.Srvr="serv1,serv2", а сервер в фоне может выдать только имя текущего активного узла.File): Для файловых баз часто различаются регистры букв дисков (например, C:\Base и c:\base), сетевые пути (UNC-пути вида \\server\share против подключенных сетевых дисков Z:\share), а также наличие или отсутствие финального слэша \ в конце пути.Попытки прямого сравнения всей строки соединения через оператор равенства = являются грубой методологической ошибкой. Рассмотрим надежные способы парсинга и сравнения параметров подключения.
Строка соединения 1С по своей структуре аналогична формату национальной строки (параметры разделены точкой с запятой, а значения сопоставляются через знак равенства). Это позволяет нам элегантно и быстро выдернуть нужный параметр без написания сложных алгоритмов поиска подстрок и регулярных выражений. Для этого мы применим встроенную функцию НСтр().
Рассмотрим пример кода для разбора строки:
СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
// Извлекаем имя базы (для клиент-серверного варианта)
ИмяБазы = НСтр(СтрокаСоединения, "Ref");
// Извлекаем имя сервера
ИмяСервера = НСтр(СтрокаСоединения, "Srvr");
// Извлекаем путь к базе (для файлового варианта)
ПутьКФайловойБазе = НСтр(СтрокаСоединения, "File");
Метод НСтр() самостоятельно очистит результат от обрамляющих кавычек и вернет чистое значение параметра.
После того как мы получили изолированное имя базы или сервера, нам необходимо выполнить сравнение. Делать это нужно строго без учета регистра букв.
Проанализируем первый вариант — приведение к единому регистру (например, к верхнему с помощью функции ВРег()):
СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
ИмяБазы = НСтр(СтрокаСоединения, "Ref");
Если ВРег(ИмяБазы) = "UT" Тогда
// Выполняем логику для базы Управление Торговлей
КонецЕсли;
Второй, более современный вариант для платформы 1С:Предприятие 8.3 — использование специализированной функции СтрСравнить(), которая по умолчанию выполняет регистронезависимое сравнение строк:
СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
ИмяБазы = НСтр(СтрокаСоединения, "Ref");
// Функция возвращает 0, если строки равны без учета регистра
Если СтрСравнить(ИмяБазы, "ut") = 0 Тогда
// Выполняем логику
КонецЕсли;
Если ваша конфигурация разработана с использованием Библиотеки стандартных подсистем (БСП), то изобретать велосипед не нужно. В составе БСП есть готовые функции общего назначения, которые уже учитывают все особенности платформ различных версий и гарантируют безопасную работу.
Например, чтобы определить, является ли база файловой или клиент-серверной, используем метод:
ЭтоФайловаяБаза = ОбщегоНазначения.ИнформационнаяБазаФайловая();
Для получения параметров соединения в БСП часто предусмотрены специализированные функции в модуле ОбщегоНазначения, которые возвращают структуру с уже распарсенными и нормализованными параметрами строки соединения.
Никогда не закладывайтесь на то, что строка соединения будет абсолютно идентична во всех контекстах выполнения. Применяйте комбинацию функций НСтр() для безопасного парсинга параметров и СтрСравнить() или ВРег() для их последующего анализа. Это убережет ваши фоновые задания от неожиданных падений и сэкономит массу времени при отладке программных решений на продуктивных серверах.