К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как обратиться к документу в 1С

Как обратиться к документу в 1С: получение ссылки, объекта, выборка по реквизитам, работа через запрос. Примеры кода, типичные ошибки и проверка результата.

Обращение к документу — одна из базовых операций во встроенном языке 1С. Под ней обычно понимают три разные задачи: получить ссылку на существующий документ, получить объект для чтения и изменения данных, либо найти документ по условию — номеру, дате, реквизиту. Каждая задача решается своим способом, и смешение этих подходов — самая частая причина ошибок у начинающих разработчиков.

Ключевое понятие — менеджер документа Документы.ИмяДокумента. Именно через него выполняются все операции: поиск ссылки, создание нового документа, построение выборки, получение пустой ссылки. Например, для документа «Реализация товаров и услуг» менеджер доступен как Документы.РеализацияТоваровУслуг.

Важно понимать разницу между ссылкой и объектом. Ссылка — это лёгкий идентификатор документа в базе, её чтение не загружает данные документа в память. Объект — это полноценная структура данных со всеми реквизитами и табличными частями, которую можно менять и записывать. Получать объект без необходимости — плохая практика: это замедляет код и повышает риск блокировок.

Ссылка и объект: в чём разница и что выбрать

Ссылка (ДокументСсылка) содержит только уникальный идентификатор и тип документа. Через ссылку можно читать реквизиты «точечно» — обращение вида Ссылка.Номер приведёт к неявному запросу к базе. Это удобно для одиночных обращений, но в цикле порождает множество мелких запросов и резко снижает производительность.

Объект (ДокументОбъект) получают вызовом Ссылка.ПолучитьОбъект(). Объект загружает в память все реквизиты и табличные части, позволяет их менять и записывать методом Записать(). Режим записи задаётся параметром: РежимЗаписиДокумента.Проведение — с проведением, РежимЗаписиДокумента.Запись — без проведения, РежимЗаписиДокумента.ОтменаПроведения — для распроведения.

Сравнение вариантов

Ссылка (ДокументСсылка)

Подходит для передачи в параметры, сравнения, хранения в реквизитах. Ограничение: каждое чтение реквизита — обращение к базе.

Объект (ДокументОбъект)

Нужен для изменения и записи документа. Ограничение: тяжёлая загрузка данных, риск блокировок при длительной работе.

Запрос

Оптимален для чтения данных по многим документам и поиска по условиям. Ограничение: результат только для чтения, изменить данные через запрос нельзя.

Как получить ссылку на документ

Самый частый способ — поиск по номеру и дате методом НайтиПоНомеру(). Метод возвращает ссылку на документ, а если документ не найден — пустую ссылку, которую проверяют методом Пустая() или функцией ЗначениеЗаполнено().

bsl
НайденныйДокумент = Документы.РеализацияТоваровУслуг.НайтиПоНомеру("00000-001234", ТекущаяДатаСеанса());

Если НайденныйДокумент.Пустая() Тогда
	Сообщить("Документ не найден");
Иначе
	Сообщить("Найден: " + НайденныйДокумент);
КонецЕсли;

Обратите внимание на второй параметр — дату. Нумерация документов в 1С периодична (обычно в пределах года), поэтому поиск по номеру без указания даты может вернуть документ не того периода или не найти его вовсе. Передавайте дату, попадающую в период нумерации нужного документа.

Если документ нужно найти по произвольному реквизиту — например, по контрагенту или комментарию — методы НайтиПоРеквизиту() и НайтиПоНомеру() не покрывают все случаи. Тогда используется запрос, о котором ниже.

Как получить объект и изменить документ

Изменение документа всегда идёт по схеме: ссылка → объект → правка реквизитов → запись. Пропуск записи — типичная ошибка: изменения в объекте существуют только в памяти и теряются при завершении кода.

bsl
ДокументОбъект = НайденныйДокумент.ПолучитьОбъект();
ДокументОбъект.Комментарий = "Скорректировано обработкой";
ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);

При работе с табличной частью обращение идёт по имени табличной части: ДокументОбъект.Товары. Строки можно перебирать в цикле, добавлять методом Добавить(), очищать методом Очистить().

Если документ проведён, вызов Записать(РежимЗаписиДокумента.Проведение) выполнит перепроведение с перезаписью движений. Если требуется только поменять реквизит, не влияющий на проведение, достаточно режима Запись — это быстрее и безопаснее.

Поиск документов запросом и выборкой

Когда нужно найти документы по условию или прочитать данные сразу по многим документам, применяют запрос. Это самый производительный способ чтения: один запрос к базе вместо сотен обращений через ссылки.

bsl
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|	Реализация.Ссылка КАК Ссылка,
|	Реализация.Номер КАК Номер,
|	Реализация.СуммаДокумента КАК Сумма
|ИЗ
|	Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ
|	Реализация.Дата МЕЖДУ &НачалоПериода И &КонецПериода
|	И Реализация.Проведен";
Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(ТекущаяДатаСеанса()));
Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(ТекущаяДатаСеанса()));
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
	Сообщить(Выборка.Номер + " — " + Выборка.Сумма);
КонецЦикла;

Альтернатива запросу — метод Выбрать() менеджера документа. Он возвращает выборку ссылок с возможностью отбора по дате. Выборка подходит для простого перебора за период, но не поддерживает произвольные условия по реквизитам, поэтому в реальных задачах чаще используется запрос.

Создание нового документа программно

Новый документ создаётся методом СоздатьДокумент() менеджера. До записи такой документ не имеет ссылки — она появляется только после Записать(). Если ссылка нужна до записи (например, чтобы подставить её в другой объект), используют ПолучитьСсылку() и УстановитьСсылкуНового(), но в типовых сценариях это не требуется.

Порядок создания документа
  1. 1
    Вызовите Документы.ИмяДокумента.СоздатьДокумент()
  2. 2
    Заполните обязательные реквизиты: дату, организацию, контрагента и другие по логике конфигурации
  3. 3
    Заполните табличные части через Добавить() в цикле
  4. 4
    Вызовите Записать() с нужным режимом — Запись или Проведение
  5. 5
    Проверьте, что документ появился в журнале и дал ожидаемые движения по регистрам

Незаполненные обязательные реквизиты — главная причина того, что созданный программно документ не проводится. Перед записью с проведением убедитесь, что заполнены все поля, которые конфигурация проверяет в обработчике проведения: обычно это организация, склад, контрагент, договор, валюта.

Обращение к документу в пользовательском режиме

Не только разработчики сталкиваются с задачей «обратиться к документу». Пользователю открыть нужный документ можно несколькими способами: через журнал документов соответствующего раздела, через универсальный отбор (команда «Ещё» → «Найти» или стандартный поиск по номеру и дате), либо через полнотекстовый поиск по данным информационной базы, если он включён администратором.

Если документ не находится, проверьте три вещи: установленный период журнала (отбор по дате отсекает документы вне интервала), права доступа (при ограничении на уровне записей часть документов скрыта) и пометку удаления — помеченные документы часто скрываются отбором.

Контрольные точки

Как проверить результат

Документ найден программно
Норма

Ссылка не пустая, реквизиты читаются

Тревожный признак

Пустая ссылка — проверьте номер, дату и вид документа

Изменения сохранены
Норма

После Записать() реквизиты видны при повторном открытии

Тревожный признак

Изменения пропали — забыт вызов Записать() или возникла ошибка, перехваченная молча

Документ проведён
Норма

Признак Проведен = Истина, движения есть в регистрах

Тревожный признак

Проведен = Ложь — смотрите сообщения об ошибках проведения

Типичные ошибки при обращении к документам

Типичные ошибки
01
Чтение реквизитов через ссылку в цикле — сотни обращений к базе вместо одного запроса
02
Получение объекта только для чтения данных — лишняя загрузка табличных частей и риск блокировки
03
Изменение объекта без вызова Записать() — правки теряются без сообщения об ошибке
04
Поиск по номеру без даты — находится документ другого периода или ничего не находится
05
Игнорирование проверки Пустая() после поиска — обращение к реквизитам пустой ссылки даёт неожиданные значения
06
Перепроведение чужих документов без учёта даты запрета изменения и прав пользователя

Отдельная группа проблем — исключения при ПолучитьОбъект(). Если документ удалён непосредственно (не пометкой) или ссылка «битая», вызов вернёт Неопределено или вызовет ошибку. Перед получением объекта полезно проверять существование ссылки, особенно в обменах и при работе с данными из внешних источников.

Итог

Что важно запомнить

Все обращения идут через менеджер Документы.ИмяДокумента. Ссылка — для идентификации и лёгкого чтения, объект — для изменения, запрос — для поиска и массового чтения. После правки объекта обязателен Записать(), а перед массовыми изменениями — резервная копия и проверка на тестовой базе.

Частые вопросы

Чем отличается НайтиПоНомеру от поиска запросом?

НайтиПоНомеру ищет по индексированной комбинации «номер + дата» и работает быстро, но ничего не знает о других реквизитах. Запрос позволяет задать любые условия — по контрагенту, сумме, комментарию, — и сразу вернуть нужные поля, поэтому универсальнее, но требует аккуратного написания текста.

Как проверить, что документ существует, не получая объект?

Достаточно проверить ссылку: если она не пустая и запрос к таблице документа по этой ссылке возвращает строку, документ существует. Получать объект для такой проверки не нужно — это избыточная операция.

Почему изменения в документе не сохраняются?

Чаще всего забыт вызов Записать() после правки объекта. Реже — запись обернута в попытку с пустым обработчиком исключения, и ошибка (например, дата запрета изменения или нарушение прав) глушится молча. Всегда выводите или журналируйте текст ошибки в блоке Исключение.

Можно ли изменить проведённый документ без перепроведения?

Да: Записать(РежимЗаписиДокумента.Запись) сохранит реквизиты, не трогая движения. Но если изменённый реквизит участвует в проведении, движения станут неактуальными — в этом случае корректнее перепровести документ.

Как обратиться к документу, вид которого заранее неизвестен?

Используйте метаданные: перебирайте коллекцию Метаданные.Документы, а менеджер получайте через Документы[МетаданныеДокумента.Имя]. Тип ссылки проверяется функцией ТипЗнч() сравнением с Тип("ДокументСсылка.ИмяДокумента").

Что делать, если ПолучитьОбъект() выдаёт ошибку?

Проверьте, не является ли ссылка битой (документ удалён физически), есть ли у пользователя права на чтение и изменение этого вида документов и не заблокирован ли документ другим сеансом. Управляемые блокировки в транзакции помогают избежать конфликтов при конкурентной записи.