Как выгрузить данные о продажах из 1С в текстовый файл с форматированием даты и UUID?

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

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

Разберем подробно, как правильно составить запрос, обойти ограничения платформы 1С:Предприятие и корректно сформировать итоговый файл выгрузки.

Назначение специализированных полей выгрузки

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

  1. OutletID — уникальный идентификатор торговой точки. В конфигурациях 1С в качестве этого значения обычно выступает код или уникальный идентификатор (GUID) элемента справочника Контрагенты, Партнеры или ДоговорыКонтрагентов (если адреса доставки привязаны к соглашениям).
  2. TAID (Trade Agent ID) — идентификатор торгового агента. Это поле связывается с кодом пользователя из справочника Пользователи либо кодом сотрудника из справочника ФизическиеЛица / Сотрудники.
  3. OperationID — идентификатор типа операции. Для разделения реализации и возврата в файле выгрузки задают числовую или строковую константу (например, 1 — продажа, 2 — возврат от покупателя).

Ограничения языка запросов 1С

Проанализируем две частые проблемы, с которыми сталкиваются программисты при попытке выгрузить данные «чистым» запросом:

  1. Форматирование даты в запросе: В языке запросов 1С отсутствуют функции Формат() или прямые аналоги преобразования даты в строку вида YYYYMMDD. Функция ДАТАВРЕМЯ() служит только для задания констант, а функции ГОД(), МЕСЯЦ() и ДЕНЬ() возвращают числовые значения без ведущих нулей (например, месяц 2 вместо 02).
  2. Получение UUID документа: Получить строковый представление УникальныйИдентификатор непосредственно в запросе нельзя. Платформа передает в выборку ссылку на объект (DocumentRef), а не его текстовый GUID.

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

Реализация выгрузки данных с постобработкой

Рассмотрим пошаговый пример построчного формирования текстового файла. В цикле обхода выборки применяется метод Формат() для даты и свойство УникальныйИдентификатор() для ссылочного поля документа.


// Создание текстового файла для выгрузки
ТекстПродажи = Новый ЗаписьТекста(ИмяФайлаПродажи, КодировкаТекста.UTF8);

// Записываем строку заголовка файла
ТекстПродажи.ЗаписатьСтроку(ЗагФайлаПродажи);

// Формируем запрос к регистру накопления
ЗапросПродаж = Новый Запрос;
ЗапросПродаж.Текст = 
    "ВЫБРАТЬ
    |	РеализацияТМЗОбороты.Номенклатура.Код КАК КодНоменклатуры,
    |	РеализацияТМЗОбороты.СтруктурноеПодразделение.Код КАК КодПодразделения,
    |	РеализацияТМЗОбороты.Партия.Автор.ФизЛицо.Код КАК КодАвтора,
    |	РеализацияТМЗОбороты.Регистратор КАК РегистраторСсылка,
    |	РеализацияТМЗОбороты.Период КАК ДатаДокумента,
    |	РеализацияТМЗОбороты.КоличествоОборот КАК Количество,
    |	РеализацияТМЗОбороты.СуммаОборот КАК Сумма
    |ИЗ
    |	РегистрНакопления.РеализацияТМЗ.Обороты(&НачалоПериода, &КонецПериода, Регистратор, Организация = &Организация) КАК РеализацияТМЗОбороты";

ЗапросПродаж.УстановитьПараметр("НачалоПериода", НачалоПериода);
ЗапросПродаж.УстановитьПараметр("КонецПериода", КонецПериода);
ЗапросПродаж.УстановитьПараметр("Организация", Организация);

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

// Построчно обрабатываем результат и записываем в файл
Пока ВыборкаПродажи.Следующий() Цикл

    // Форматируем дату в вид YYYYMMDD (например, 20230115)
    СтрокаДата = Формат(ВыборкаПродажи.ДатаДокумента, "ДФ=ггггММдд");

    // Получаем строковый GUID из ссылки на документ
    ИдентификаторДокумента = Строка(ВыборкаПродажи.РегистраторСсылка.УникальныйИдентификатор());

    // Собираем строку с разделителями
    СтрокаПродажи = ВыборкаПродажи.КодНоменклатуры + Разделитель
        + ВыборкаПродажи.КодПодразделения + Разделитель
        + ВыборкаПродажи.КодАвтора + Разделитель
        + СтрокаДата + Разделитель
        + ИдентификаторДокумента + Разделитель
        + ВыборкаПродажи.Количество + Разделитель
        + ВыборкаПродажи.Сумма;

    ТекстПродажи.ЗаписатьСтроку(СтрокаПродажи);

КонецЦикла;

ТекстПродажи.Закрыть();

Альтернативный вариант форматирования через Таблицу Значений

Если данные необходимо сначала подготовить в памяти, а затем передавать далее по коду, можно выгрузить результат запроса в объект ТаблицаЗначений и добавить вычисляемую колонку:


ТаблицаРезультата = ЗапросПродаж.Выполнить().Выгрузить();
ТаблицаРезультата.Колонки.Добавить("ПредставлениеДаты", Новый ОписаниеТипов("Строка"));

Для Каждого СтрокаРезультата Из ТаблицаРезультата Цикл
    СтрокаРезультата.ПредставлениеДаты = Формат(СтрокаРезультата.ДатаДокумента, "ДФ=ггггММдд");
КонецЦикла;

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

Обратим внимание на важный аспект производительности при составлении запросов в 1С:

  1. Избегайте обращения через несколько точек: Конструкция вида РеализацияТМЗОбороты.Партия.Автор.ФизЛицо.Код создает цепочку неявных левых соединений (LEFT JOIN) к базами данных СУБД. Если одно из полей окажется составного типа, это приведет к резкому падению скорости выполнения запроса.
  2. Используйте явные соединения: Для получения реквизитов авторов или контрагентов рекомендуется делать явное ЛЕВОЕ СОЕДИНЕНИЕ с нужным справочником по ссылке.
  3. Контролируйте периодичность оборотов: Чтобы получить поле Регистратор в виртуальной таблице оборотов, обязательно указывайте периодичность Регистратор в параметрах виртуальной таблицы: РегистрНакопления.РеализацияТМЗ.Обороты(&НачалоПериода, &КонецПериода, Регистратор, ...).
← На главную