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