Как получить значение реквизита документа и правильно проверить его на заполненность в 1С

Программист 1С v8.3 (Обычные формы) Управленческий учет Торговля и дистрибуция
← На главную

При работе в среде 1С:Предприятие начинающие разработчики часто сталкиваются с ситуацией, когда код ведет себя непредсказуемо при попытке проверить, заполнено ли то или иное поле в документе. Типичный пример: мы пишем запрос, чтобы узнать адрес доставки из заказа, но программа всегда сообщает, что «адрес есть», даже если поле визуально пустое. В этой статье мы подробно разберем, почему так происходит, и изучим несколько надежных способов решения этой задачи.

Анализ ошибки: почему запрос не определяет пустое поле

Рассмотрим ситуацию, описанную автором темы. Проблема заключается в неправильном использовании метода Пустой() объекта РезультатЗапроса. Давайте проанализируем логику работы платформы. Когда мы выполняем запрос к таблице документов с условием по конкретному номеру, СУБД возвращает нам набор строк. Если документ с таким номером существует, запрос вернет одну строку.

Метод РезультатЗапроса.Пустой() проверяет лишь одно: есть ли в результате запроса хотя бы одна строка. Если документ в базе найден, этот метод всегда будет возвращать Ложь, независимо от того, что написано в его реквизитах. Даже если поле АдресДоставки совершенно пустое, строка-то в результате запроса есть! Именно поэтому условие Если РезультатЗапроса.Пустой() Тогда срабатывает только в том случае, если документа с таким номером вообще нет в базе данных.

Решение №1: Правильная обработка результата запроса

Чтобы проверить значение конкретного реквизита через запрос, нам необходимо не просто выполнить его, но и обратиться к данным внутри полученной строки. Разберем по шагам, как это сделать правильно.

Во-первых, в тексте запроса лучше использовать параметры, а не вставлять номер документа прямой строкой. Это повышает безопасность и производительность системы. Во-вторых, после выполнения запроса нам нужно вызвать метод Выбрать() и перейти к первой (и в данном случае единственной) строке с помощью метода Следующий().

Рассмотрим исправленный пример кода:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ЗаказПокупателя.АдресДоставки КАК АдресДоставки
    |ИЗ
    |	Документ.ЗаказПокупателя КАК ЗаказПокупателя
    |ГДЕ
    |	ЗаказПокупателя.Номер = &НомерДокумента";

Запрос.УстановитьПараметр("НомерДокумента", "00000001440");

РезультатЗапроса = Запрос.Выполнить();

Если РезультатЗапроса.Пустой() Тогда
    Сообщить("Документ с таким номером не найден в базе!");
Иначе
    Выборка = РезультатЗапроса.Выбрать();
    Выборка.Следующий(); // Переходим к единственной строке результата
    
    // Теперь проверяем именно ЗНАЧЕНИЕ реквизита в строке
    Если ПустаяСтрока(Выборка.АдресДоставки) Тогда
        Сообщить("Документ найден, но адрес доставки не заполнен.");
    Иначе
        Сообщить("Адрес доставки: " + Выборка.АдресДоставки);
    КонецЕсли;
КонецЕсли;

В данном примере функция ПустаяСтрока() корректно определяет, содержит ли реквизит АдресДоставки (который имеет тип «Строка») хоть какие-то значимые символы.

Решение №2: Использование объектной техники (НайтиПоНомеру)

Если нам нужно проверить реквизит всего одного конкретного документа и мы знаем его номер, использование тяжелого механизма запросов не всегда оправдано. Мы можем воспользоваться методами менеджера документа. Рассмотрим, как это реализовать более лаконично.

Важный нюанс: при поиске по номеру в 1С 8.3 крайне желательно указывать дату, так как нумерация документов часто бывает периодической (ежегодной). Без даты метод может вернуть документ за старый год или не найти вовсе.


// Ищем ссылку на документ
ДокСсылка = Документы.ЗаказПокупателя.НайтиПоНомеру("00000001440", ТекущаяДата());

// Проверяем, что ссылка не пустая (документ найден)
Если ДокСсылка.Пустая() Тогда
    Сообщить("Документ не найден!");
Иначе
    // Обращаемся к реквизиту напрямую через точку
    Если ПустаяСтрока(ДокСсылка.АдресДоставки) Тогда
        Сообщить("Адрес не заполнен.");
    Иначе
        Сообщить("Адрес есть: " + ДокСсылка.АдресДоставки);
    КонецЕсли;
КонецЕсли;

Обратите внимание на проверку ДокСсылка.Пустая(). В 1С метод НайтиПоНомеру всегда возвращает объект типа «Ссылка», но если поиск не удался, эта ссылка будет указывать «в никуда» (станет пустой). Сравнение с Неопределено здесь не сработает.

Решение №3: Оптимальный способ для конфигураций на БСП

Если вы работаете в современной конфигурации (например, УТ 11, ERP 2.0 или БСП), проанализируем самый эффективный способ получения данных — функцию ОбщегоНазначения.ЗначениеРеквизитаОбъекта. Она позволяет получить значение конкретного поля, не считывая весь объект целиком из базы данных, что значительно экономит ресурсы сервера.

Рассмотрим пример использования:


// Предположим, у нас уже есть ссылка на документ ЗаказСсылка
Адрес = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ЗаказСсылка, "АдресДоставки");

Если ПустаяСтрока(Адрес) Тогда
    Сообщить("Внимание: адрес пуст!");
КонецЕсли;

Этот метод объединяет в себе преимущества запроса (скорость) и удобство обращения к реквизиту по имени.

Важные технические нюансы при проверке значений

Разберем еще несколько моментов, которые могут привести к ошибкам в логике программы:

  1. Различие между NULL и пустой строкой: Если вы используете в запросе ЛЕВОЕ СОЕДИНЕНИЕ, то вместо пустой строки может вернуться значение NULL. В этом случае функция ПустаяСтрока() может вызвать ошибку. В запросах рекомендуется использовать функцию ЕСТЬNULL(АдресДоставки, ""), чтобы всегда гарантированно получать строку.
  2. Пробелы в строке: Иногда пользователи случайно ставят пробел в поле. С точки зрения 1С " " — это не совсем пустая строка. Чтобы быть уверенными, можно использовать функцию СокрЛП() перед проверкой: Если ПустаяСтрока(СокрЛП(Выборка.АдресДоставки)) Тогда....
  3. Тип реквизита: Убедитесь, что реквизит АдресДоставки действительно является строкой. В некоторых сложных системах это может быть ссылка на справочник «Адреса» или запись в регистре сведений «Контактная информация». В таком случае проверка должна быть на ЗначениеЗаполнено().

Подводя итог, проанализируем основные выводы нашей совместной работы: никогда не полагайтесь на метод РезультатЗапроса.Пустой() для проверки конкретных данных внутри документа. Всегда делайте шаг внутрь выборки (Следующий()) и анализируйте конечное значение с помощью специализированных функций ПустаяСтрока() или ЗначениеЗаполнено().

← На главную