Разработка и Конфигурация · 13 мин
Как найти документ по номеру в 1С программно
Как найти документ по номеру в 1С программно: НайтиПоНомеру, запросы, поиск по части номера, проверка результата, типичные ошибки и примеры кода на встроенном языке.
Поиск документа по номеру — одна из самых частых задач при обмене данными, загрузке выписок, интеграции с внешними системами и написании обработок. Во встроенном языке 1С для этого есть штатный метод НайтиПоНомеру() у менеджера документа, а также более гибкий вариант — запрос по таблице документов. Выбор зависит от того, известен ли точный номер, нужен ли поиск по части строки и важна ли скорость на больших объёмах.
Главная тонкость: номер документа в 1С — строка, а не число. Номера «000000001» и «1» для платформы — разные значения, и поиск без учёта ведущих нулей и префиксов часто возвращает пустую ссылку. Кроме того, номер уникален только в пределах периода нумерации (обычно года) и вида документа, поэтому надёжный поиск всегда учитывает дату или период.
Ниже разобраны рабочие способы поиска: штатный метод, запрос, поиск по части номера, проверка результата, а также типичные ошибки, из-за которых документ «не находится», хотя он есть в базе.
Как устроен номер документа в 1С и почему это важно
Номер документа хранится в поле Номер как строка фиксированной длины, заданной в конфигураторе (свойство «Длина номера»). Платформа автоматически дополняет номер ведущими нулями до этой длины, а при включённой нумерации по префиксам добавляет префикс организации или информационной базы. Поэтому реальный номер в базе может выглядеть как «00БП-000123», хотя пользователь видит на экране «123».
Практическое следствие: перед поиском нужно знать точный формат номера. Если внешняя система передаёт число 123, а в базе хранится «000000123», прямой поиск по строке «123» не найдёт ничего. В типовых конфигурациях для приведения номеров есть функции работы с префиксами, например ПрефиксацияОбъектовКлиентСервер.НомерНаПечать(), которая удаляет префикс и лидирующие нули, — обратная задача (дополнение нулями) решается функцией вида:
Функция ДополнитьНомерНулями(Номер, ДлинаНомера)
Результат = СокрЛП(Номер);
Пока СтрДлина(Результат) < ДлинаНомера Цикл
Результат = "0" + Результат;
КонецЦикла;
Возврат Результат;
КонецФункции
Узнать длину номера программно можно через метаданные: Метаданные.Документы.РеализацияТоваровУслуг.ДлинаНомера. Это надёжнее, чем зашивать константу в код, — конфигурация может измениться.
Базовый способ: метод НайтиПоНомеру
Штатный метод вызывается у менеджера конкретного вида документа и возвращает ссылку на документ или пустую ссылку, если ничего не найдено. Синтаксис: Документы.ИмяДокумента.НайтиПоНомеру(Номер, Дата), где второй параметр — дата, ограничивающая период поиска.
НомерДокумента = "000000123";
ДатаПоиска = Дата(2026, 3, 15);
Ссылка = Документы.РеализацияТоваровУслуг.НайтиПоНомеру(НомерДокумента, ДатаПоиска);
Если Ссылка.Пустая() Тогда
Сообщить("Документ с номером " + НомерДокумента + " не найден");
Иначе
Сообщить("Найден: " + Ссылка);
КонецЕсли;
Параметр даты работает как граница периода нумерации: метод ищет документ в том периоде (годе), которому принадлежит указанная дата. Если передать пустую дату, поиск будет идти по всей таблице, но при совпадении номеров в разных годах результат станет непредсказуемым. Поэтому дату лучше передавать всегда, когда она известна.
Метод работает быстро, потому что по полю «Номер» в таблице документов построен индекс. Для разового поиска по точному номеру это оптимальный вариант: минимум кода, предсказуемое поведение, нет лишних выборок.
- 1Определите вид документа и длину номера через метаданные
- 2Приведите входящий номер к формату базы: префикс и ведущие нули
- 3Вызовите НайтиПоНомеру с указанием даты документа
- 4Проверьте ссылку методом Пустая() перед использованием
- 5Проверьте ПометкаУдаления у найденного объекта, если это важно для сценария
Поиск запросом: когда номер известен не точно
Запрос нужен, когда формат номера неизвестен, требуется поиск по части строки или нужно заодно получить реквизиты документа без обращения к объекту. Оператор ПОДОБНО позволяет искать по шаблону, а функция ПОДСТРОКА — сравнивать часть номера.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Док.Ссылка КАК Ссылка,
| Док.Дата КАК Дата,
| Док.ПометкаУдаления КАК ПометкаУдаления
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Док
|ГДЕ
| Док.Номер ПОДОБНО &Шаблон
| И Док.Дата МЕЖДУ &НачалоГода И &КонецГода";
Запрос.УстановитьПараметр("Шаблон", "%" + "123");
Запрос.УстановитьПараметр("НачалоГода", НачалоГода(ДатаПоиска));
Запрос.УстановитьПараметр("КонецГода", КонецГода(ДатаПоиска));
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
НайденнаяСсылка = Выборка.Ссылка;
КонецЕсли;
Обратите внимание на ограничение периода датами. Поиск по ПОДОБНО без индекса заставляет СУБД просматривать таблицу целиком, и на базе с сотнями тысяч документов такой запрос без отбора по дате может выполняться заметное время. Сужение периода до года или месяца — простой способ ускорить выборку.
Запрос также удобен, когда нужно найти сразу несколько документов по списку номеров: вместо цикла с НайтиПоНомеру передаётся таблица значений с номерами, и одним запросом возвращаются все найденные ссылки. Это существенно быстрее при пакетной обработке.
Сравнение способов поиска
Подходит при точно известном номере и дате. Быстрый, короткий код. Не умеет искать по части номера.
Подходит при неизвестном формате номера или поиске по фрагменту. Медленнее, требует ограничения периода.
Подходит для пакетной загрузки: один запрос вместо цикла. Требует подготовки таблицы значений.
Поиск по номеру без учёта префикса и нулей
В интеграциях часто приходит «человеческий» номер — без префикса и ведущих нулей. Универсальный приём — сравнивать не сами номера, а их числовые хвосты. Поскольку прямого приведения строки к числу в запросе нет, на практике применяют два подхода.
Первый — перебор вариантов: сформировать несколько кандидатов (с префиксами всех организаций, с нулями разной длины) и искать точным совпадением через условие Номер В (&СписокНомеров). Способ быстрый, так как использует индекс, но требует знать возможные префиксы.
Второй — поиск по шаблону с хвостом номера: шаблон "%" + ЧисловаяЧасть находит все номера, оканчивающиеся на нужные цифры. Риск этого подхода — ложные совпадения: номер «000123» и «001123» оба оканчиваются на «123». Поэтому результат нужно дополнительно фильтровать по дате, контрагенту или сумме, если эти данные известны из источника.
При загрузке из внешних систем надёжнее хранить не номер, а дополнительный реквизит с внешним идентификатором документа. Поиск по точному строковому реквизиту с индексом устраняет всю проблематику префиксов и нулей. Если менять конфигурацию нельзя, используйте дополнительные сведения.
Проверка результата и работа с найденным документом
Пустая ссылка — не единственный неуспешный исход. Документ может быть найден, но помечен на удаление, не проведён или принадлежать другой организации. Минимальная проверка перед использованием ссылки выглядит так:
Если Ссылка.Пустая() Тогда
Возврат; // документа нет
КонецЕсли;
Реквизиты = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Ссылка,
"ПометкаУдаления, Проведен, Организация");
Если Реквизиты.ПометкаУдаления Тогда
// документ помечен на удаление — решить, обрабатывать ли его
КонецЕсли;
Чтение реквизитов через ЗначенияРеквизитовОбъекта (в типовых конфигурациях БСП) или прямым запросом не создаёт объект в памяти и работает быстрее, чем Ссылка.ПолучитьОбъект(). Объект стоит получать только когда планируется изменение документа.
Если документ нужно изменить, помните про блокировки: при конкурентной работе пользователей попытка записи может завершиться ошибкой «Конфликт блокировок». В пакетных обработках такие ситуации обрабатывают повторной попыткой или переносом документа в конец очереди.
Как проверить результат поиска
Ссылка.Пустая() = Ложь
Пустая ссылка — проверьте формат номера и дату
ПометкаУдаления = Ложь
Документ помечен на удаление
Дата документа в ожидаемом году
Найден документ другого года с тем же номером
Ровно один документ
Несколько документов — нужен дополнительный фильтр
Типичные ошибки и ограничения
Самая частая причина «документ не найден» — несовпадение формата номера. Входящие данные содержат «123», а в базе «00ТД-000123». Вторая по частоте причина — неверный период: документ января ищется с датой декабря, и метод не находит его из-за границы периода нумерации.
Отдельная группа проблем — права доступа. Если у пользователя, под которым выполняется код, настроено ограничение доступа на уровне записей (RLS) по организациям или контрагентам, поиск вернёт пустую ссылку, хотя документ физически существует. В регламентных заданиях и обменах обычно выполняют код от имени пользователя с полными правами либо используют привилегированный режим: УстановитьПривилегированныйРежим(Истина).
Ограничение метода НайтиПоНомеру — он не ищет по подстроке и не учитывает регистр в некоторых СУБД-зависимых сценариях. Также не стоит искать документ перебором всех ссылок через выборку Документы.Имя.Выбрать() с последующим сравнением номера в цикле: на больших таблицах это медленно и создаёт лишнюю нагрузку.
Выбор способа под конкретную задачу
Если обмен передаёт точный номер в том же формате, что хранится в базе, и известна хотя бы примерная дата — используйте НайтиПоНомеру. Это самый быстрый и предсказуемый вариант. Для разовых ручных обработок этого достаточно в подавляющем большинстве случаев.
Если номер приходит в произвольном виде (выгрузки из банков, сайтов, сторонних учётных систем), начинайте с нормализации: удалите пробелы, выделите числовую часть, попробуйте точный поиск по сгенерированным вариантам, и только потом переходите к ПОДОБНО с обязательным ограничением периода и дополнительной проверкой по реквизитам.
Для массовой загрузки (тысячи документов за сеанс) проектируйте пакетный поиск через запрос с таблицей номеров, а в перспективе — хранение внешнего идентификатора в отдельном реквизите или регистре сведений соответствия. Это убирает зависимость от формата номера, который может измениться при перенумерации или смене префиксов.
Как выбрать способ поиска
Частые вопросы
Можно ли найти документ по номеру, не зная его вида?
Напрямую — нет: поиск всегда выполняется внутри конкретного вида документов. Обходной путь — перебрать нужные виды через Метаданные.Документы и для каждого выполнить НайтиПоНомеру или общий запрос. Чтобы не сканировать всю конфигурацию, ограничьте список видов заранее по смыслу задачи.
Почему НайтиПоНомеру возвращает пустую ссылку, хотя документ видно в списке?
Чаще всего не совпадает формат номера (префикс, ведущие нули) или дата попадает в другой период нумерации. Реже причина в ограничении прав доступа на уровне записей. Откройте документ, скопируйте его номер через «Ещё — Вывести список» или запросом и сравните посимвольно с искомой строкой.
Как искать документы с неуникальными номерами?
Добавьте в условие дату, организацию, контрагента или сумму — любой реквизит, известный из источника данных. Запрос с несколькими условиями вернёт единственный документ там, где поиск только по номеру даёт несколько совпадений.
Что быстрее: НайтиПоНомеру или запрос?
При точном совпадении номера оба варианта используют индекс и работают сопоставимо. НайтиПоНомеру короче в коде. Запрос выигрывает, когда нужно заодно получить реквизиты, проверить пометку удаления или найти пакет документов одним обращением к базе.
Как найти документ по номеру в запросе к нескольким видам документов?
Используйте ОБЪЕДИНИТЬ ВСЕ по таблицам нужных видов документов с одинаковым набором полей (Ссылка, Номер, Дата) и отбором по номеру в каждой секции. Учтите, что длина номера у разных видов может отличаться — нормализуйте искомое значение под каждый вид.
Безопасно ли искать и изменять документы в привилегированном режиме?
Привилегированный режим отключает проверку прав, включая RLS, поэтому код должен сам контролировать, какие документы обрабатывает. Используйте его только в серверных процедурах обменов и регламентных заданий, никогда — в обработчиках, доступных обычному пользователю без дополнительных проверок.
Что важно запомнить
Номер документа в 1С — строка с префиксом и ведущими нулями, уникальная только в пределах периода. Для точного поиска используйте НайтиПоНомеру с датой, для нечёткого — запрос с ПОДОБНО и ограничением периода. Всегда проверяйте пустоту ссылки, пометку удаления и учитывайте права доступа.