Битые ссылки в запросах 1С: как их найти, проверить и исправить
Содержание
Чтобы найти битые ссылки в запросе 1С, соедините таблицу с проверяемым полем с таблицей объекта через ЛЕВОЕ СОЕДИНЕНИЕ и отберите строки, где Ссылка ЕСТЬ NULL, а само поле не пустое. Для всей базы сразу есть штатный путь: Конфигуратор → Администрирование → Тестирование и исправление с флажком проверки ссылочной целостности.
Это два разных инструмента. Запрос точечный и безопасный: он только читает данные и показывает, в каких документах ссылка ведёт в никуда. Тестирование проходит по всей базе и умеет чинить, но требует монопольного доступа и резервной копии. Отдельная история — ссылки на внешние ресурсы (адреса сайтов, FTP, сетевые папки), которые хранятся в реквизитах. Их проверяют уже не запросом, а кодом.
Что считается битой ссылкой в 1С
Под «битой ссылкой» в 1С понимают три разные ситуации. От типа зависит способ поиска.
- 🔗 Ссылка на несуществующий объект. В реквизите лежит уникальный идентификатор, а объекта с таким идентификатором в таблице нет. В форме это выглядит как
<Объект не найден> (45:b1c2...). - 📌 Битое значение в тексте запроса. Запрос обращается к предопределённому элементу или перечислению, которого уже нет в конфигурации, например
ЗНАЧЕНИЕ(Справочник.Склады.Основной)после удаления элемента. Запрос падает при выполнении. - 🌐 Нерабочая внешняя ссылка. В реквизите хранится URL, адрес FTP или путь к файлу, а ресурс недоступен: сайт отдаёт 404, файл перенесли, у сервера нет прав на сетевую папку.
Откуда берутся ссылки первого типа:
- Объект удалили непосредственно, минуя пометку на удаление и контроль ссылок.
- Данные пришли по обмену раньше, чем пришёл сам справочник, или не пришли вовсе.
- Базу восстанавливали частично: загрузили документы без справочников.
- Сбой файловой базы повредил таблицу.
Пустая ссылка и битая ссылка — разные вещи. Пустая означает «значение не выбрано» и нормальна для необязательного реквизита. Битая означает «значение выбрано, но объекта нет». В запросе их нужно разделять, иначе отчёт утонет в пустых значениях.
Поиск битых ссылок запросом и анализ кода
Шаг 1. Запрос по одному реквизиту
Откройте консоль запросов (в типовых конфигурациях она есть среди обработок, в остальных её подключают как внешнюю обработку ) и выполните запрос. Пример для реквизита «Контрагент» документа реализации:
ВЫБРАТЬ
Д.Ссылка КАК Документ,
Д.Дата КАК Дата,
Д.Контрагент КАК БитаяСсылка
ИЗ
Документ.РеализацияТоваровУслуг КАК Д
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК К
ПО Д.Контрагент = К.Ссылка
ГДЕ
К.Ссылка ЕСТЬ NULL
И Д.Контрагент <> ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
Логика простая. Если объект существует, соединение найдёт его строку. Если нет, все поля правой таблицы будут NULL.
Шаг 2. Табличные части и регистры
Табличная часть проверяется так же, только источником становится сама табличная часть:
ВЫБРАТЬ
Т.Ссылка КАК Документ,
Т.НомерСтроки КАК Строка,
Т.Номенклатура КАК БитаяСсылка
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Т
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Н
ПО Т.Номенклатура = Н.Ссылка
ГДЕ
Н.Ссылка ЕСТЬ NULL
И Т.Номенклатура <> ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
Для регистров накопления и сведений меняется только источник: вместо документа ставите основную таблицу регистра и проверяете измерения.
Шаг 3. Поля составного типа
Если реквизит может хранить ссылки разных типов (например, «Документ-основание»), одно соединение не подойдёт. Отфильтруйте нужный тип через ТИПЗНАЧЕНИЯ и соедините с каждой таблицей отдельно, объединив результаты через ОБЪЕДИНИТЬ ВСЕ.
Шаг 4. Массовая проверка по метаданным
Писать запрос руками на каждый реквизит долго. Удобнее собрать текст программно: обойти Метаданные.Документы, для каждого реквизита ссылочного типа сформировать блок с ЛЕВОЕ СОЕДИНЕНИЕ и склеить блоки через ОБЪЕДИНИТЬ ВСЕ. На большой базе запускайте такую проверку частями, по 5–10 объектов метаданных за раз, иначе запрос будет выполняться десятки минут.
Статический анализ: битые значения в текстах запросов
Ссылки второго типа ищут в конфигурации, а не в данных:
- 🔍
Конфигурация → Проверка конфигурациив Конфигураторе с флажком расширенной проверки найдёт обращения к несуществующим объектам метаданных в коде модулей. - 🔎 Глобальный поиск по конфигурации (
Ctrl+Shift+F) по строкеЗНАЧЕНИЕ(или имени удалённого элемента покажет все запросы, где он упоминается. - 🧩 Тексты запросов, собранные из строк в коде, проверка конфигурации не разберёт. Их проверяет только выполнение. Откройте такой запрос в конструкторе: при синтаксической ошибке он сразу скажет, на какой строке.
Захардкоженные адреса сайтов и пути к папкам в модулях тоже ищите глобальным поиском по http, ftp и \\. Именно они чаще всего ломаются после переезда сервера.
Тестирование и исправление: проверка ссылочной целостности всей базы
Когда битых ссылок много и неизвестно где, запросами всё не охватить. Тогда используют штатную проверку.
- Сделайте полную резервную копию: выгрузку
.dtили копию файлов базы. Без копии проверку с исправлением не запускайте. - Попросите всех выйти из базы. Тестирование требует монопольного доступа, активные сеансы будут мешать запуску.
- Откройте Конфигуратор →
Администрирование → Тестирование и исправление. - Отметьте проверку логической и ссылочной целостности.
- Выберите режим «Только проверка», если сначала хотите увидеть масштаб.
- Для найденных ссылок на несуществующие объекты есть три варианта действий. Их сравнение — в таблице ниже.
| Действие | Когда выбирать | Риски |
|---|---|---|
| Не изменять | Первая разведка, нужен только список | Нет |
| Создавать объекты | Объект потерян при обмене и его можно восстановить | Появятся пустые элементы-заглушки, их надо заполнить |
| Очищать ссылки | Объект точно не нужен | Документы с очищенными реквизитами могут стать некорректными, проведение «поплывёт» |
Режим «Создавать объекты» удобен тем, что сохраняет связи. Заглушки получают наименование вида «Объект не найден», их легко найти поиском по списку, заполнить и перепровести документы.
Тот же механизм запускается из командной строки ключом /IBCheckAndRepair в режиме Конфигуратора. Набор дополнительных параметров уточняйте во встроенной справке платформы к параметрам командной строки для вашей версии.
Журнал регистрации: где видны ошибки от битых ссылок
Битые ссылки часто не видны, пока не сломается что-то конкретное: отчёт, проведение, обмен. Следы этого остаются в журнале регистрации.
- 📖 В пользовательском режиме:
Администрирование → Обслуживание → Журнал регистрации. - 🛠 В Конфигураторе:
Администрирование → Журнал регистрации.
Как искать:
- Установите отбор по уровню «Ошибка» и по интервалу, когда жаловались пользователи.
- Добавьте отбор по событию: «Данные. Проведение», «Обмен данными» или ваши собственные события.
- Ищите в комментарии фразы
Объект не найден,Неверное значение предопределенногои коды HTTP-ответов, если вы их логируете. - По колонке «Данные» откройте документ, на котором упало, и проверьте его реквизиты запросом из предыдущего раздела.
Платформа сама пишет в журнал только сбои. Успешные проверки внешних ссылок и коды ответов сайтов туда не попадут, если не записать их явно через ЗаписьЖурналаРегистрации().
Динамическая проверка URL, FTP и путей к файлам
Ссылки на внешние ресурсы запрос не проверит: для СУБД это просто строка. Проверку пишут на встроенном языке и выполняют на сервере.
HTTP и HTTPS
Для адреса сайта достаточно запросить заголовки и посмотреть код ответа. Пример использует функцию ОбщегоНазначенияКлиентСервер.СтруктураURI() из БСП, которая есть в типовых конфигурациях:
Функция КодОтветаURL(Адрес, Таймаут = 10) Экспорт
Части = ОбщегоНазначенияКлиентСервер.СтруктураURI(Адрес);
Защищенное = ?(НРег(Части.Схема) = "https", Новый ЗащищенноеСоединениеOpenSSL, Неопределено);
Соединение = Новый HTTPСоединение(Части.Хост, Части.Порт, , , , Таймаут, Защищенное);
Ответ = Соединение.ПолучитьЗаголовки(Новый HTTPЗапрос("/" + Части.ПутьНаСервере));
Возврат Ответ.КодСостояния;
КонецФункции
Как читать результат:
| Код | Что значит | Битая ли ссылка |
|---|---|---|
| 200 | Ресурс доступен | Нет |
| 301, 302 | Адрес переехал | Ссылку стоит обновить |
| 401, 403 | Нужна авторизация или нет прав | Проверьте учётные данные |
| 404, 410 | Ресурса нет | Да |
| 500–503 | Сбой на стороне сайта | Проверить повторно позже |
Некоторые сайты не отвечают на запрос заголовков. Если пришёл 405, повторите проверку методом Получить().
Файлы и сетевые папки
Путь к файлу проверяется одной строкой: Новый Файл(Путь).Существует(). Помните, что проверка идёт от имени того пользователя, под которым работает сервер 1С. Папка, открытая у бухгалтера в проводнике, для службы сервера может быть недоступна.
FTP
Для FTP создайте FTPСоединение и вызовите НайтиФайлы() по нужному каталогу. Пустой результат или исключение при подключении — повод пометить ссылку как нерабочую.
Повторные попытки и обработка исключений в запросе и коде
Одна неудачная проверка ещё не значит, что ссылка битая. Сеть моргнула, сайт перегружен. Поэтому любой внешний вызов оборачивают в Попытка ... Исключение и повторяют.
Функция ПроверитьСсылку(Адрес, Попыток = 3) Экспорт
Для Номер = 1 По Попыток Цикл
Попытка
Код = КодОтветаURL(Адрес, 10 * Номер);
Если Код < 500 Тогда
Возврат Код;
КонецЕсли;
Исключение
ЗаписьЖурналаРегистрации("ПроверкаСсылок", УровеньЖурналаРегистрации.Предупреждение, , Адрес,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецЦикла;
Возврат 0;
КонецФункции
Что здесь сделано:
- ⏱ Таймаут растёт с каждой попыткой: 10, 20, 30 секунд.
- 🔁 Коды 5xx считаются временными и проверяются ещё раз, а 404 возвращается сразу.
- 📝 Каждое исключение пишется в журнал с подробностями, чтобы потом понять причину.
- 0️⃣ Ноль означает «ресурс так и не ответил». Его удобно отличать от реальных кодов.
Встроенной паузы между попытками в серверном коде нет. Если ресурсу нужно время, не крутите цикл, а оставьте повторную проверку на следующий запуск регламентного задания.
Защита запросов от битых ссылок
В отчётах битая ссылка не должна ронять вывод. При разыменовании несуществующего объекта его реквизиты возвращаются как NULL. Обработайте это явно:
ВЫБРАТЬ
Д.Ссылка,
ЕСТЬNULL(Д.Контрагент.Наименование, "<битая ссылка>") КАК Контрагент
ИЗ
Документ.РеализацияТоваровУслуг КАК Д
Так пользователь сразу видит проблемную строку, а не пустую ячейку.
Внешние утилиты и скрипты для проверки ссылок
Иногда проще вынести проверку за пределы 1С.
| Инструмент | Для чего | Ограничения |
|---|---|---|
| Консоль запросов | Разовые проверки ссылочных реквизитов | Ручной запуск |
/IBCheckAndRepair в пакетном режиме | Ночная проверка всей базы | Монопольный доступ |
Утилита chdbfl.exe | Физическая целостность файловой базы | Логические ссылки не проверяет |
| curl или PowerShell | Пакетная проверка списка URL | Нужна выгрузка адресов из 1С |
Схема для внешних адресов: выгрузите из 1С таблицу «объект — адрес» в CSV, прогоните её скриптом и загрузите результат обратно. Пример для PowerShell:
Import-Csv links.csv | ForEach-Object {
try { $code = (Invoke-WebRequest -Uri $_.url -Method Head -UseBasicParsing -TimeoutSec 15).StatusCode }
catch { $code = $_.Exception.Response.StatusCode.value__ }
[pscustomobject]@{ id = $_.id; url = $_.url; code = $code }
} | Export-Csv result.csv -NoTypeInformation
chdbfl.exe запускают только на закрытой базе. Если в ней работают пользователи, сначала попросите всех выйти, иначе утилита не получит доступ к файлу или повредит данные при исправлении.
Профилактика: как не допускать битых ссылок и автоматизировать мониторинг
Чинить дороже, чем не допустить. Основные меры:
- Запретите непосредственное удаление. Уберите у ролей право «Интерактивное удаление», оставьте только пометку. Окончательно удаляйте через «Удаление помеченных объектов»: эта обработка проверяет, есть ли ссылки на объект.
- Контролируйте обмены. После загрузки пакета прогоняйте запрос на битые ссылки по ключевым справочникам: контрагенты, номенклатура, договоры.
- Регламентное задание. Раз в сутки ночью запускайте проверку внешних адресов и запросы по главным реквизитам. Результат пишите в отдельный регистр сведений : объект, адрес, код ответа, дата проверки.
- Оповещение. Если число битых ссылок выросло относительно прошлой проверки, отправляйте письмо ответственному.
- Не храните абсолютные пути. Вместо
\\srv01\docs\...держите в константе корневой каталог, а в реквизитах только относительную часть. Переезд сервера тогда правится в одном месте.
Частые вопросы
Почему запрос не находит битую ссылку, хотя в форме «Объект не найден»?
ТИПЗНАЧЕНИЯ и добавьте соединение с нужной таблицей.