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