Работа с реквизитами документов в 1С:Предприятие — одна из самых частых задач, с которыми сталкиваются разработчики, администраторы и даже опытные пользователи.hether вы пишете отчет, автоматизируете бизнес-процесс или просто пытаетесь вытащить нужную информацию для анализа, умение правильно извлекать значения реквизитов сэкономит часы времени и избавит от типичных ошибок.
В этой статье мы разберем 5 основных способов получения значений реквизитов — от элементарных действий в пользовательском интерфейсе до сложных программных конструкций. Вы узнаете, когда лучше использовать ПолучитьФорму(), а когда обойтись простым запросом, как избежать ошибок при работе с ссылками на объекты и почему иногда значения "исчезают" при выводе в отчет. Материал будет полезен как новичкам, так и опытным специалистам, которые хотят систематизировать свои знания.
Особое внимание уделим распространенной проблеме несоответствия значений в форме и в базе данных — почему документ в интерфейсе показывает одно, а запрос возвращает другое, и как с этим бороться. Все примеры приведены для актуальных версий платформы 1С:Предприятие 8.3, но большинство методов работают и в более ранних редакциях.
1. Получение значения через форму документа (без программирования)
Самый простой способ — извлечь значение непосредственно из открытой формы документа. Этот метод не требует знания языка 1С и подходит для пользователей, которые не имеют доступа к конфигуратору.
Чтобы увидеть значение реквизита:
- 📄 Откройте нужный документ в режиме просмотра или редактирования
- 🔍 Найдите реквизит в форме (он может быть на основной закладке или в дополнительных разделах)
- 📋 Скопируйте значение вручную или через буфер обмена (
Ctrl+C) - 🖱️ Для реквизитов-таблиц используйте контекстное меню ("Копировать в Excel")
Ограничения метода:
- ❌ Не подходит для массовой обработки документов
- ❌ Нельзя получить значения скрытых или программно рассчитываемых реквизитов
- ❌ Нет доступа к служебным реквизитам (например,
СсылкаилиПометкаУдаления)
⚠️ Внимание: Значения в форме могут отличаться от реальных данных в базе, если документ не проведён или используются динамические вычисления. Всегда проверяйте актуальность информации через меню Действия → История изменений.
2. Использование встроенных отчетов и обработок
Для регулярного извлечения данных удобно использовать стандартные или пользовательские отчеты. Этот метод подходит, когда нужно получить значения реквизитов для группы документов по определенным критериям.
Пошаговая инструкция:
- Перейдите в раздел
ОтчетыилиОбработки - Выберите подходящий отчет (например, "Анализ документов" или "Универсальный отчет")
- В настройках отчета укажите:
- 📌 Тип документа (например, "РеализацияТоваровУслуг")
- 📌 Период и дополнительные отборы
- 📌 Необходимые реквизиты в колонках
Пример настройки универсального отчета для документа "ПоступлениеТоваров":
| Параметр | Значение | Пример |
|---|---|---|
| Объект | Документ.ПоступлениеТоваровУслуг | — |
| Период | Текущий месяц | 01.07.2026 — 31.07.2026 |
| Группировка | Контрагент | ООО "Ромашка", ИП Иванов |
| Реквизиты | Номер, Дата, СуммаДокумента | ПТ-000123 от 15.07.2026, 47 800 ₽ |
| Отбор | Склад = "Основной" | — |
Для сложных задач создайте собственную обработку с помощью конструктора запросов. Это позволит:
- 🔄 Объединять данные из нескольких документов
- 📊 Строить сводные таблицы с группировками
- 💾 Сохранять результаты в внешние файлы
Уточнить список необходимых реквизитов|Проверить права доступа к данным|Создать тестовую выборку|Настроить формат вывода|Протестировать на реальных данных-->
3. Программное получение значений через 1С:Предприятие
Для автоматизации процессов необходимо использовать встроенный язык 1С. Рассмотрим основные методы работы с реквизитами документов в коде.
3.1. Прямое обращение к реквизиту
Самый очевидный способ — обратиться к реквизиту через точку:
ДокументОбъект = Документы.ЗаказКлиента.НайтиПоНомеру("ЗК-000456");
Сообщить(ДокументОбъект.Контрагент.Наименование);
Сообщить(ДокументОбъект.Дата);
Сообщить(ДокументОбъект.СуммаДокумента);
Особенности метода:
- ✅ Простота и наглядность кода
- ✅ Быстрое выполнение (нет накладных расходов на запросы)
- ❌ Работает только с одним документом
- ❌ Может вызвать ошибку, если документ не найден
3.2. Использование метода ПолучитьФорму()
Когда нужно получить значение из формы документа (включая динамически рассчитываемые реквизиты):
ФормаДокумента = ДокументОбъект.ПолучитьФорму();
ЗначениеРеквизита = ФормаДокумента.ЭлементыФормы.НужныйРеквизит.Значение;
Это актуально для реквизитов, которые:
- 🔄 Рассчитываются в модуле формы
- 🔒 Зависит от прав пользователя
- 📱 Отображаются только в определенных режимах (например, при проведении)
⚠️ Внимание: Метод ПолучитьФорму() создает копию формы в памяти и может замедлить работу при массовой обработке. Для больших пакетов документов используйте запросы.
3.3. Работа со ссылками на документы
Частая ошибка — попытка получить реквизит напрямую из ссылки:
// НЕПРАВИЛЬНО (вызовет ошибку):
СсылкаНаДокумент = Документы.РеализацияТоваровУслуг.Ссылка("000000005");
Сообщить(СсылкаНаДокумент.СуммаДокумента); // Ошибка!
Правильный вариант:
// ПРАВИЛЬНО:
ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();
Сообщить(ДокументОбъект.СуммаДокумента);
Функция БезопасноеПолучениеДокумента(ТипДокумента, Номер)
Попытка
Возврат Документы[ТипДокумента].НайтиПоНомеру(Номер);
Исключение
Возврат Неопределено;
КонецПопытки;
КонецФункции
-->
4. Извлечение данных через запросы
Запросы — самый мощный инструмент для работы с большими объемами данных. Они позволяют получать значения реквизитов для тысяч документов за секунды, применять сложные отборы и группировки.
Базовый синтаксис запроса для получения реквизитов:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РеализацияТоваровУслуг.Ссылка КАК Ссылка,
| РеализацияТоваровУслуг.Дата КАК Дата,
| РеализацияТоваровУслуг.Контрагент КАК Контрагент,
| РеализацияТоваровУслуг.СуммаДокумента КАК Сумма
|ИЗ
| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
|ГДЕ
| РеализацияТоваровУслуг.Дата МЕЖДУ &НачалоПериода И &КонецПериода";
Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(ТекущаяДата()));
Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(ТекущаяДата()));
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Преимущества запросов:
- ⚡ Высокая скорость обработки больших массивов данных
- 🔧 Гибкие возможности фильтрации и агрегации
- 📊 Легкая интеграция с системами отчетности
Типичные ошибки при работе с запросами:
| Ошибка | Причина | Решение |
|---|---|---|
Неизвестное имя РеквизитX | Опечатка в названии реквизита | Проверьте имя в конфигураторе |
| Нет прав на чтение | Ограничения RLS | Добавьте РАЗРЕШЕННЫЕ в запрос |
| Пустой результат | Неверный отбор по датам | Используйте НАЧАЛОПЕРИОДА() |
| Ошибка типов | Сравнение числа и строки | Приведите типы с помощью ЧИСЛО() |
Для сложных документов с табличными частями используйте конструкцию ЛЕВОЕ СОЕДИНЕНИЕ:
ВЫБРАТЬ
РеализацияТоваровУслуг.Ссылка КАК Документ,
РеализацияТоваровУслугТовары.Номенклатура КАК Товар,
РеализацияТоваровУслугТовары.Количество КАК Количество
ИЗ
Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
ПО РеализацияТоваровУслуг.Ссылка = РеализацияТоваровУслугТовары.Ссылка
Как ускорить выполнение запросов?
1. Используйте индексируемые поля в условиях OTБOPA
2. Избегайте функций в WHERE (например, ГОД(Дата) = 2026 лучше заменить на Дата МЕЖДУ...)
3. Ограничивайте количество возвращаемых колонок
4. Для больших баз используйте временные таблицы
5. Настройте сервер 1С: увеличьте память под кэш запросов
5. Работа с динамическими реквизитами и дополнительными сведениями
Особую сложность представляют динамические реквизиты и дополнительные сведения, которые могут храниться в отдельных таблицах или рассчитываться на лету.
Для получения значений дополнительных реквизитов используйте:
// Получение дополнительного реквизита "Цвет" для номенклатуры
ДопРеквизиты = ДокументОбъект.Товары[0].Номенклатура.ДополнительныеРеквизиты;
ЦветТовара = ДопРеквизиты.НайтиПоИмени("Цвет").Значение;
Для динамических реквизитов (созданных в режиме предприятия):
// Получение динамического реквизита "ПримечаниеМенеджера"
ДинРеквизиты = ДокументОбъект.ДинамическиеСписки.ПримечаниеМенеджера;
Если ДинРеквизиты.Количество() > 0 Тогда
Сообщить(ДинРеквизиты[0].Значение);
КонецЕсли;
Важные нюансы:
- 🔹 Дополнительные реквизиты могут быть привязаны к разным типам объектов
- 🔹 Динамические реквизиты хранятся в отдельной системе хранения
- 🔹 Для работы с ними часто требуются дополнительные права
⚠️ Внимание: При переносе базы между информационными базами или обновлении конфигурации дополнительные реквизиты могут "потеряться". Всегда делайте резервную копию перед такими операциями и проверяйте целостность данных с помощью обработки "Тестирование и исправление".
Для массовой обработки дополнительных реквизитов эффективнее использовать запросы с присоединением таблицы ДополнительныеРеквизитыИСведения:
ВЫБРАТЬ
Документ.Ссылка КАК Документ,
ДополнительныеРеквизиты.Значение КАК ЗначениеРеквизита
ИЗ
Документ.РеализацияТоваровУслуг КАК Документ
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеРеквизитыИСведения КАК ДополнительныеРеквизиты
ПО Документ.Ссылка = ДополнительныеРеквизиты.Объект
ГДЕ
ДополнительныеРеквизиты.Реквизит = &Реквизит
6. Типичные ошибки и их решение
Даже опытные разработчики сталкиваются с проблемами при извлечении значений реквизитов. Разберем самые распространенные случаи.
6.1. "Объект не найден" при обращении к реквизиту
Причины и решения:
- 🔸 Документ не существует → Проверьте ссылку через
Ссылка.Пустая() - 🔸 Недостаточно прав → Используйте
Попытка...Исключение - 🔸 Реквизит удален из конфигурации → Обновите конфигурацию базы данных
6.2. Разные значения в форме и в базе
Это происходит когда:
- 🔄 Документ не проведён (значения не записаны)
- 📊 Используются расчетные реквизиты в форме
- 🔒 Работают механизмы RLS (ограничение прав)
Чтобы получить "реальное" значение:
// Сначала получаем объект
ДокОбъект = ДокументСсылка.ПолучитьОбъект();
// Затем читаем напрямую из базы
Запрос = Новый Запрос("ВЫБРАТЬ СуммаДокумента ИЗ Документ.РеализацияТоваровУслуг ГДЕ Ссылка = &Ссылка");
Запрос.УстановитьПараметр("Ссылка", ДокументСсылка);
Результат = Запрос.Выполнить().Выбрать().СуммаДокумента;
6.3. Ошибки при работе с табличными частями
Типичные проблемы:
| Ошибка | Пример кода | Исправление |
|---|---|---|
| Индекс вне границ | Док.Товары[100] | Проверяйте Док.Товары.Количество() |
| Неверный тип | Если Док.Товары.Номенклатура = "Товар1" | Сравнивайте по ссылке: = Справочники.Номенклатура.НайтиПоНаименованию() |
| Пустая строка | Сумма = Док.Товары[0].Количество * Цена | Проверяйте на Неопределено и ПустаяСтрока() |
Для безопасной работы с табличными частями используйте цикл Для Каждого:
СуммаВсего = 0;
Для Каждого СтрокаТовара Из ДокументОбъект.Товары Цикл
Если Не СтрокаТовара.Номенклатура.Пустая() Тогда
СуммаВсего = СуммаВсего + СтрокаТовара.Сумма;
КонецЕсли;
КонецЦикла;
Всегда проверяйте существование объектов и реквизитов перед обращением к ним. Используйте конструкции Попытка...Исключение и Если...Тогда для предотвращения ошибок выполнения.
7. Оптимизация производительности
При работе с большими объемами данных важно минимизировать нагрузку на систему. Вот ключевые рекомендации:
Для программного кода:
- 🚀 Используйте
ПолучитьФорму()только когда действительно нужны данные формы - 🔄 Кэшируйте часто используемые объекты в переменных
- 📉 Избегайте вложенных циклов при обработке табличных частей
Для запросов:
- 📊 Ограничивайте выборку по датам и другим критериям
- 🔍 Используйте индексируемые поля в условиях
- 🗃️ Для сложных отчетов применяйте временные таблицы
Пример оптимизированного кода для массовой обработки:
// Плохо (много обращений к базе)
Для Каждого Док Из Документы.РеализацияТоваровУслуг Цикл
Если Док.Дата = ТекущаяДата() Тогда
Сообщить(Док.Контрагент.Наименование);
КонецЕсли;
КонецЦикла;
// Хорошо (один запрос)
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Контрагент.Наименование ИЗ Документ.РеализацияТоваровУслуг КАК Док ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагент ПО Док.Контрагент = Контрагент.Ссылка ГДЕ Док.Дата = &Дата";
Запрос.УстановитьПараметр("Дата", ТекущаяДата());
Результат = Запрос.Выполнить().Выгрузить();
Для критически важных операций рассмотрите:
- 📌 Использование фоновых заданий для длительных операций
- 📌 Разбиение больших пакетов на части (по 100-500 документов)
- 📌 Применение регламентных заданий для регулярных операций
FAQ: Ответы на частые вопросы
Как получить значение реквизита из документа, который еще не проведён?
Непровedenные документы содержат только те значения, которые были явно заполнены пользователем. Для получения таких данных:
- Используйте
ПолучитьОбъект()без проведения - Для расчетных полей (например, суммы) придется вручную пересчитывать значения
- Помните, что непровedenные документы не влияют на итоги и остатки
Пример кода для получения "сырых" данных:
НепровedenныйДок = Документы.ЗаказКлиента.СоздатьДокумент();
НепровedenныйДок.ЗаполнитьДанныеИзФормы(ФормаДокумента);
// Теперь можно читать реквизиты
Сообщить(НепровedenныйДок.СуммаДокумента); // Может быть неактуальна!
Почему запрос возвращает другие значения, чем те, что видно в форме документа?
Это типичная ситуация, которая возникает по нескольким причинам:
- Динамические данные в форме: некоторые реквизиты рассчитываются в модуле формы и не хранятся в базе
- Права доступа: RLS может ограничивать видимость данных в форме, но не в запросе (и наоборот)
- Несохраненные изменения: если документ редактировался, но не сохранен
- Версионность данных: форма может показывать текущую версию, а запрос — записанную
Решение: всегда сверяйте данные через ПолучитьОбъект() или прямой запрос к таблице документа.
Можно ли получить значение реквизита из архивной версии документа?
Да, для этого используйте механизм версионирования:
// Получение архивной версии
АрхивныеВерсии = ДокументОбъект.ПолучитьВерсии();
ПоследняяВерсия = АрхивныеВерсии[0]; // или нужная по дате
ЗначениеИзАрхива = ПоследняяВерсия.Данные.НужныйРеквизит;
// Альтернативно через запрос
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ВерсияДанных.Данные.Реквизит КАК Реквизит
ИЗ РегистрСведений.ВерсииОбъектов.ВерсияДанных КАК ВерсияДанных
ГДЕ ВерсияДанных.Объект = &Ссылка
И ВерсияДанных.МоментВремени = &ДатаВерсии";
Обратите внимание, что для работы с версиями требуются специальные права и включенное версиирование в настройках информационной базы.
Как экспортировать значения реквизитов в Excel с сохранением форматирования?
Для качественного экспорта используйте Библиотеку стандартных подсистем (БСП) или специализированные обработки:
// Пример экспорта через БСП
ТаблицаДанных = Новый ТаблицаЗначений;
ТаблицаДанных.Колонки.Добавить("Дата");
ТаблицаДанных.Колонки.Добавить("Контрагент");
ТаблицаДанных.Колонки.Добавить("Сумма");
// Заполняем данными из запроса
РезультатЗапроса.Выгрузить(ТаблицаДанных);
// Экспорт в Excel
ПараметрыЭкспорта = Новый Структура();
ПараметрыЭкспорта.Вставить("ФорматЯчеек", Новый Соответствие);
ПараметрыЭкспорта.ФорматЯчеек.Вставить("Сумма", "Числовой");
БСП.ЭкспортВExcel(ТаблицаДанных, "", Истина, ПараметрыЭкспорта);
Для сложного форматирования (цвета, формулы) лучше использовать COM-объект Excel или специализированные библиотеки типа EPPlus (для работы через .NET).
Какие есть альтернативные способы получения данных из документов 1С?
Помимо стандартных методов, рассмотрите следующие подходы:
- HTTP-сервисы: если нужно интегрироваться с внешними системами
- Прямой доступ к SQL: для опытных администраторов (требует осторожности)
- Регламентные задания: для регулярного сбора данных
- Внешние обработки: с использованием Managed-форм или Такси
- REST API: в новых версиях 1С (начиная с 8.3.20)
Пример работы через REST:
// Получение данных через REST (упрощенно)
Адрес = "http://server/1c/rest/Документ/РеализацияТоваровУслуг?$filter=Дата ge 2026-01-01";
HTTPСоединение = Новый HTTPСоединение(Адрес);
HTTPЗапрос = Новый HTTPЗапрос();
Ответ = HTTPСоединение.Получить(HTTPЗапрос);
Данные = JSON.Прочитать(Ответ.ПолучитьТекст());
Для работы с SQL напрямую (только для администраторов!):
// ВНИМАНИЕ: Небезопасный метод, может нарушить целостность данных!
ЗапросSQL = Новый Запрос(
"SELECT t1._Fld12345 AS СуммаДокумента
FROM _Document83 t1
WHERE t1._IDRRef = '0x1A2B3C4D5E6F'"
);
Результат = ЗапросSQL.Выполнить().Выбрать();