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