Как заполнить реквизиты управляемой формы из регистра сведений в 1С 8.3 и почему данные не отображаются?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Причина 1: Неявное несовпадение типов в условиях запроса

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


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

Выясним причину, почему такой запрос может возвращать пустой результат, даже если в базе данных есть предприятие с похожим ИНН. Обратите внимание на условие в секции ГДЕ. Здесь ИНН передан как числовой литерал: 55678979.

В типовых конфигурациях 1С поле ИННорганизации (или аналогичное ему) практически всегда имеет тип Строка. Это обусловлено тем, что ИНН может начинаться с одного или нескольких нулей (например, ИНН ведомств или некоторых регионов), а также имеет строго фиксированную длину (10 или 12 знаков). При сравнении строкового поля СУБД с числом платформа производит неявное приведение типов, либо СУБД возвращает пустой результат из-за несовпадения типов.

Поскольку запрос возвращает пустую выборку, цикл Пока Выборка.Следующий() не выполняется ни разу. Следовательно, присвоение значений реквизитам Объект.НаименованиеПоставщика и Объект.ИНН просто пропускается.

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


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

// Передаем параметр в виде строки, а не числа
Запрос.УстановитьПараметр("ИННорганизации", "55678979"); 

РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Если Выборка.Следующий() Тогда
    Объект.НаименованиеПоставщика = Выборка.КраткоеНаименование;
    Объект.ИНН = Выборка.ИННорганизации;
КонецЕсли;

Причина 2: Появление нуля вместо пустой строки в поле ввода

Разберем еще один неочевидный нюанс. В исходном коде перед выполнением запроса программист очищает поля формы следующим образом:

Объект.ИНН = "";

Однако на форме в поле ИНН вместо пустой строки внезапно появляется цифра 0. Почему так происходит? Это классическое поведение платформы 1С при работе с типизированными реквизитами. Если реквизит ИНН объекта (документа или справочника) в метаданных имеет тип Число, то при попытке присвоить ему пустую строку "" платформа автоматически преобразует это несовместимое значение в значение по умолчанию для числового типа данных — то есть в ноль.

Убедитесь, что тип реквизита в метаданных конфигурации совпадает с типом данных, которые вы пытаетесь туда записать. Если ИНН должен быть строкой, измените тип реквизита в конфигураторе на Строка.

Причина 3: Некорректная настройка свойства «ПутьКДанным» на форме

Представим ситуацию: мы исправили типы данных в запросе, отладчик показывает, что переменная Объект.ИНН на сервере успешно получает значение "55678979", но после завершения серверной процедуры поле на экране пользователя по-прежнему остается пустым. В чем кроется проблема?

Нам необходимо проанализировать настройки элементов формы в конфигураторе:

  1. Откройте управляемую форму, на которой расположены ваши поля ввода.
  2. Выделите элемент формы (поле ввода), предназначенный для отображения ИНН.
  3. Перейдите в палитру свойств (клавиша F4) и найдите свойство ПутьКДанным (DataPath).
  4. Убедитесь, что там указан правильный путь к реквизиту основного объекта формы. Он должен выглядеть так: Объект.ИНН.

Если в свойстве ПутьКДанным по ошибке привязан другой реквизит формы (например, локальная переменная формы ИНН вместо Объект.ИНН), то изменения, вносимые в структуру Объект на сервере, никак не отобразятся в этом поле ввода.

Причина 4: Использование устаревшего метода Сообщить() на сервере

Часто в процессе отладки разработчики используют конструкцию Сообщить("Тест"), чтобы проверить, заходит ли выполнение программы в процедуру. Если процедура выполняется на сервере управляемой формы, метод Сообщить() может отработать некорректно или вообще не вывести сообщение пользователю на клиенте (особенно если вызов происходит в контексте фонового задания или при определенных настройках клиент-серверного взаимодействия).

Для вывода сообщений в управляемых формах по стандартам разработки фирмы «1С» следует использовать специализированный объект СообщениеПользователю. Рассмотрим пример его правильного применения:


Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Данные успешно заполнены из регистра сведений!";
Сообщение.Поле = "Объект.ИНН"; // Визуально привязывает сообщение к конкретному полю на форме
Сообщение.УстановитьДанные(ЭтотОбъект);
Сообщение.Сообщить();

Такой подход гарантирует, что сообщение будет передано на сторону клиента и красиво отобразится в интерфейсе с привязкой к рамке конкретного поля ввода.

Причина 5: Нюансы контекста выполнения и конвертации объектов

В управляемом приложении важно помнить, как передаются данные между клиентом и сервером. Если вы используете контекстную процедуру с директивой компиляции &НаСервере, платформа автоматически берет все данные формы, сериализует их, отправляет на сервер, выполняет ваш код и возвращает измененные данные обратно на клиент.

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


&НаСервере
Процедура ЗаполнитьНаСервере()
    // Конвертируем данные формы в прикладной объект для вызова его методов
    ДокументОбъект = РеквизитФормыВЗначение("Объект");
    
    // Пытаемся заполнить реквизиты объекта напрямую
    ДокументОбъект.ИНН = "1234567890";
    
    // ВНИМАНИЕ: Если здесь забыть сделать обратное преобразование, 
    // изменения останутся в памяти сервера и никогда не попадут на форму!
КонецПроцедуры

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

ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");

Итоговый правильный шаблон процедуры заполнения реквизитов

Соберем все рекомендации воедино и напишем надежную, чистую и производительную процедуру заполнения реквизитов управляемой формы из регистра сведений:


&НаСервере
Процедура ЗаполнитьРеквизитыИзРегистраНаСервере(Знач ПоискИНН)
    
    // Предварительно очищаем реквизиты (если типы строковые)
    Объект.ИНН = "";
    Объект.НаименованиеПоставщика = "";
    Объект.ЮрАдрес = "";
    
    // Инициализируем запрос
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |	НовоеПредприятие.КраткоеНаименование КАК КраткоеНаименование,
        |	НовоеПредприятие.ИННорганизации КАК ИННорганизации,
        |	НовоеПредприятие.ЮридическийАдрес КАК ЮридическийАдрес
        |ИЗ
        |	РегистрСведений.НовоеПредприятие КАК НовоеПредприятие
        |ГДЕ
        |	НовоеПредприятие.ИННорганизации = &ПараметрИНН";
        
    // Приводим передаваемый параметр к типу Строка
    Запрос.УстановитьПараметр("ПараметрИНН", СокрЛП(Строка(ПоискИНН)));
    
    РезультатЗапроса = Запрос.Выполнить();
    Если Не РезультатЗапроса.Пустой() Тогда
        
        Выборка = РезультатЗапроса.Выбрать();
        Выборка.Следующий();
        
        // Заполняем реквизиты формы полученными значениями
        Объект.НаименованиеПоставщика = Выборка.КраткоеНаименование;
        Объект.ИНН = Выборка.ИННорганизации;
        Объект.ЮрАдрес = Выборка.ЮридическийАдрес;
        
        // Выводим уведомление пользователю
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Данные контрагента успешно загружены.";
        Сообщение.Сообщить();
        
    Иначе
        
        // Сообщаем, если данные не найдены
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Предприятие с указанным ИНН не найдено в регистре сведений!";
        Сообщение.Поле = "Объект.ИНН";
        Сообщение.УстановитьДанные(ЭтотОбъект);
        Сообщение.Сообщить();
        
    КонецЕсли;
    
КонецПроцедуры

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

← На главную