Как правильно обновить контактную информацию в справочнике через выборку запроса

Программист 1С:Управление нашей фирмой Управленческий учет
← На главную

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

Анализ исходной задачи

Рассмотрим ситуацию: нам необходимо программно обновить поле Представление для определенного вида контактной информации (например, фактического адреса) у структурных единиц. Для этого мы сначала получаем данные с помощью запроса, а затем в цикле пытаемся их изменить. Ошибка, с которой часто сталкиваются разработчики — «Поле объекта не обнаружено (Представление)» — возникает из-за попытки обратиться к реквизиту напрямую через объект справочника, в то время как Представление является колонкой табличной части КонтактнаяИнформация.

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

Для начала нам необходимо выбрать ссылки на объекты и данные их контактной информации. Воспользуемся конструктором запроса. Важно выбрать не только саму ссылку на справочник, но и Вид контактной информации, чтобы мы могли точно идентифицировать строку, которую хотим изменить.


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

Запрос.УстановитьПараметр("Ссылка", ДанныеОбъекта.СтруктурнаяЕдиница);
// Указываем конкретный вид контактной информации, который ищем
Запрос.УстановитьПараметр("ВидКИ", Справочники.ВидыКонтактнойИнформации.ФактАдресСтруктурнойЕдиницы);

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

Шаг 2: Правильный алгоритм изменения данных в цикле

Теперь проанализируем ситуацию с записью. Самая распространенная ошибка — пытаться присвоить значение переменной Представление сразу объекту. Вместо этого нам нужно получить объект (ПолучитьОбъект()), найти в его табличной части нужную строку и изменить данные именно в ней.

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


Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    // 1. Получаем объект справочника для редактирования
    ОбъектСпр = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();
    
    // Флаг того, что мы нашли и изменили данные
    ДанныеИзменены = Ложь;
    
    // 2. Итерируемся по табличной части "КонтактнаяИнформация"
    Для Каждого СтрокаКИ Из ОбъектСпр.КонтактнаяИнформация Цикл
        // Сравниваем вид КИ из строки с видом КИ из нашей выборки
        Если СтрокаКИ.Вид = ВыборкаДетальныеЗаписи.Вид Тогда
            СтрокаКИ.Представление = "Новый адрес или текст";
            ДанныеИзменены = Истина;
        КонецЕсли;
    КонецЦикла;
    
    // 3. Записываем объект только если были изменения
    Если ДанныеИзменены Тогда
        ОбъектСпр.Записать();
    КонецЕсли;
КонецЦикла;

Шаг 3: Оптимизация поиска через метод НайтиСтроки()

Если табличная часть справочника содержит много записей, перебор всей таблицы Для Каждого может быть неэффективным. Разберем более быстрый способ с использованием метода НайтиСтроки(). Этот метод позволяет мгновенно получить массив строк, соответствующих определенному условию.


Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    ОбъектСпр = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();
    
    // Создаем структуру отбора
    ПараметрыОтбора = Новый Структура;
    ПараметрыОтбора.Вставить("Вид", ВыборкаДетальныеЗаписи.Вид);
    
    // Ищем подходящие строки
    НайденныеСтроки = ОбъектСпр.КонтактнаяИнформация.НайтиСтроки(ПараметрыОтбора);
    
    Если НайденныеСтроки.Количество() > 0 Тогда
        // Если нашли — редактируем первую попавшуюся (обычно вид КИ уникален для объекта)
        СтрокаКИ = НайденныеСтроки[0];
        СтрокаКИ.Представление = "Обновленное значение";
    Иначе
        // Если не нашли — можем добавить новую запись
        НоваяСтрока = ОбъектСпр.КонтактнаяИнформация.Добавить();
        НоваяСтрока.Вид = ВыборкаДетальныеЗаписи.Вид;
        НоваяСтрока.Представление = "Новое значение";
    КонецЕсли;
    
    ОбъектСпр.Записать();
КонецЦикла;

Почему данные могут не отображаться в печатной форме?

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

  1. Поле «ЗначенияПолей»: Кроме текстового реквизита Представление, в табличной части часто присутствует скрытое строковое поле ЗначенияПолей (в формате XML или JSON). В нем хранятся разобранные составляющие адреса (город, улица, дом). Многие печатные формы берут данные именно оттуда. Если вы изменили только «Представление», система может игнорировать его при печати.
  2. Кэширование данных: Если печать вызывается сразу после записи в той же транзакции или процедуре, убедитесь, что запрос для печатной формы обращается к базе данных заново, а не использует старую выборку, сформированную до модификации объекта.
  3. Несоответствие Видов КИ: Проверьте, какой именно вид адреса выводится в печатной форме. Если вы программно меняете «Фактический адрес», а макет формы настроен на «Юридический адрес» (или просто «Адрес»), вы не увидите изменений.

Использование механизмов БСП (Рекомендуемый способ)

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


// Пример записи контактной информации методами БСП
ЗначениеКИ = "г. Москва, ул. Ленина, дом 1";
ТипКИ = Перечисления.ТипыКонтактнойИнформации.Адрес;
ВидКИ = Справочники.ВидыКонтактнойИнформации.ФактАдресСтруктурнойЕдиницы;

УправлениеКонтактнойИнформацией.ЗаписатьКонтактнуюИнформацию(ВыборкаДетальныеЗаписи.Ссылка, ЗначениеКИ, ВидКИ, ТипКИ);

Этот метод самостоятельно найдет нужную строку в табличной части объекта, обновит Представление и сформирует правильную XML-структуру в поле ЗначенияПолей. Это самый надежный способ избежать проблем с пустыми полями в отчетах и формах.

Важные рекомендации по производительности

При массовом обновлении данных (например, тысячи контрагентов) выполнение Объект.Записать() внутри цикла может существенно замедлить работу системы. Проанализируем, как ускорить этот процесс:

Таким образом, мы выяснили, что для успешной записи данных в выборку необходимо работать непосредственно со строками табличной части полученного объекта, учитывая специфику хранения контактной информации в конкретной конфигурации 1С.

← На главную