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

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

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

Анализируем структуру хранения данных

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

Давайте проанализируем ситуацию, описанную в теме. На форме справочника аоЛицевыеСчета есть поле «Текущий статус», но в структуре самого справочника этого поля нет. Рассмотрим алгоритм поиска источника данных:

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

Использование регистров сведений для получения текущего значения

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


// Пример получения статуса через менеджер регистра
СтатусЗаписи = РегистрыСведений.аоСтатусыЛицевыхСчетов.СрезПоследних(ТекущаяДата(), Новый Структура("ЛицевойСчет", СсылкаНаЛС));
Если СтатусЗаписи.Количество() > 0 Тогда
    ТекущийСтатус = СтатусЗаписи[0].Статус;
КонецЕсли;

Оптимизация выгрузки: переход от выборки к запросу

В исходном коде автора используется метод Выбрать(). Это допустимо для простых задач, но когда нам нужно связать справочник со статусом и отфильтровать закрытые счета, использование объекта Запрос становится обязательным. Это значительно ускоряет работу системы и снижает нагрузку на сервер.

Рассмотрим, как составить запрос, который сразу выберет лицевые счета, их контактную информацию и актуальный статус, отсекая при этом записи со статусом «Закрыт»:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ЛицевыеСчета.Код КАК Код,
    |	ЛицевыеСчета.Абонент КАК Абонент,
    |	ЛицевыеСчета.Регион КАК Регион,
    |	ЛицевыеСчета.Город КАК Город,
    |	ЛицевыеСчета.Улица КАК Улица,
    |	ЛицевыеСчета.НомерДома КАК НомерДома,
    |	ЛицевыеСчета.НомерКвартиры КАК НомерКвартиры,
    |	СтатусыСрезПоследних.Статус КАК Статус
    |ИЗ
    |	Справочник.аоЛицевыеСчета КАК ЛицевыеСчета
    |		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.аоСтатусыЛицевыхСчетов.СрезПоследних(&Период, ) КАК СтатусыСрезПоследних
    |		ПО ЛицевыеСчета.Ссылка = СтатусыСрезПоследних.ЛицевойСчет
    |ГДЕ
    |	СтатусыСрезПоследних.Статус <> ЗНАЧЕНИЕ(Перечисление.аоСтатусыЛицевыхСчетов.Закрыт)";

Запрос.УстановитьПараметр("Период", ТекущаяДата());
Выборка = Запрос.Выполнить().Выбрать();

Формирование XML-структуры с данными из перечисления

Теперь разберем процесс записи полученных данных в XML. Для этого мы будем использовать объект ЗаписьXML. Важно помнить, что при выгрузке перечислений мы можем передавать либо их синоним (текст для пользователя), либо имя метаданных (код для разработчика сайта).

Выясним, как правильно записать строковое представление статуса в XML-узел:


Запись.ЗаписатьНачалоЭлемента("Status");
// Получаем строковое значение перечисления (синоним)
ТекстСтатуса = Строка(Выборка.Статус); 
Запись.ЗаписатьТекст(ТекстСтатуса);
Запись.ЗаписатьКонецЭлемента();

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

Полный пример функции выгрузки данных

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


Функция ВыгрузитьАбонентовВXML(СпособВыгрузки)
    Запись = Новый ЗаписьXML;
    Если СпособВыгрузки = "Файл" Тогда
        Запись.ОткрытьФайл("C:\Exports\Abonents.xml");
    Иначе
        Запись.УстановитьСтроку();
    КонецЕсли;

    Запись.ЗаписатьОбъявлениеXML();
    Запись.ЗаписатьНачалоЭлемента("Abonents");

    // Используем запрос для получения данных из справочника и регистра
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ * ИЗ Справочник.аоЛицевыеСчета КАК ЛС"; // Упрощенно
    Выборка = Запрос.Выполнить().Выбрать();

    Пока Выборка.Следующий() Цикл
        Запись.ЗаписатьНачалоЭлемента("Abonent");
        
        Запись.ЗаписатьНачалоЭлемента("Code");
        Запись.ЗаписатьТекст(Строка(Выборка.Код));
        Запись.ЗаписатьКонецЭлемента();

        Запись.ЗаписатьНачалоЭлемента("Name");
        Запись.ЗаписатьТекст(Строка(Выборка.Абонент));
        Запись.ЗаписатьКонецЭлемента();

        // Работа со статусом из перечисления
        Запись.ЗаписатьНачалоЭлемента("Status");
        Если ЗначениеЗаполнено(Выборка.Статус) Тогда
            Запись.ЗаписатьТекст(Строка(Выборка.Статус));
        Иначе
            Запись.ЗаписатьТекст("Не определен");
        КонецЕсли;
        Запись.ЗаписатьКонецЭлемента();

        // Выгрузка контактной информации из табличной части
        ТабличнаяЧасть = Выборка.Ссылка.КонтактнаяИнформация;
        Для Каждого СтрокаТЧ Из ТабличнаяЧасть Цикл
            Если СтрокаТЧ.Тип = Перечисления.ТипыКонтактнойИнформации.Телефон Тогда
                Запись.ЗаписатьНачалоЭлемента("Phone");
                Запись.ЗаписатьТекст(Строка(СтрокаТЧ.НомерТелефона));
                Запись.ЗаписатьКонецЭлемента();
            КонецЕсли;
        КонецЦикла;

        Запись.ЗаписатьКонецЭлемента(); // Abonent
    КонецЦикла;

    Запись.ЗаписатьКонецЭлемента(); // Abonents
    
    Результат = ?(СпособВыгрузки = "Файл", "Выгружено в файл", Запись.Закрыть());
    Возврат Результат;
КонецФункции

Подведем итоги

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

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

← На главную