Как правильно записывать данные в XML в 1С и почему нельзя использовать функцию ЗначениеВСтрокуВнутр

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

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

Разбор причины ошибки Параметр 1

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

Использование функции ЗначениеВСтрокуВнутр() кажется простым выходом, так как она принудительно возвращает текст. Однако это решение в корне неверно. Выясним причину: данная функция формирует специфическую системную строку (похожую на JSON, но во внутреннем формате 1С), которая содержит служебную информацию о типе. Например, вместо числа 3050 вы получите {"N",3050}. Такой формат сделает ваш XML-файл нечитаемым для других программ и невалидным согласно схеме XSD.

Правильное преобразование через XMLСтрока

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

  1. Числа: Стандартная функция Строка() может добавлять неразрывные пробелы для разделения разрядов (например, "1 250,50"), что недопустимо в XML. Функция XMLСтрока() запишет число в каноническом виде: "1250.50" (без пробелов, с точкой в качестве разделителя).
  2. Даты: Она автоматически приводит дату к стандарту ISO 8601 (ГГГГ-ММ-ДДTHH:MM:SS), что является обязательным требованием для большинства XML-схем.
  3. Булево: Преобразует значения в "true"/"false" (или "1"/"0"), понятные внешним системам.

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


// Вместо: ЗаписьXML.ЗаписатьТекст(ЗначениеВСтрокуВнутр(Строка.Количество));
// Используем:
ЗаписьXML.ЗаписатьТекст(XMLСтрока(Строка.Количество));

Обращение к полям запроса по именам

Проанализируем ваш метод получения данных через Строка.Получить(Индекс). Это считается плохим тоном в разработке на 1С по нескольким причинам:

Рассмотрим, как сделать код надежнее. Всегда обращайтесь к полям по их именам, заданным в тексте запроса через ключевое слово КАК.


Для Каждого ТекСтрока Из РезультатЗапроса Цикл
    ЗаписьXML.ЗаписатьНачалоЭлемента("T3RXXXXG2S");
    // Обращаемся по имени поля
    ЗаписьXML.ЗаписатьТекст(ТекСтрока.КонтрагентНаименование);
    ЗаписьXML.ЗаписатьКонецЭлемента();
КонецЦикла;

Оптимизация структуры циклов

В исходном коде часто встречается ошибка: создание нескольких отдельных циклов по одной и той же таблице значений для заполнения разных узлов XML. Это существенно замедляет работу системы. Разберем по шагам, как оптимизировать процесс:

  1. Минимизируйте количество обходов: Старайтесь записать все необходимые данные за один проход цикла Для Каждого.
  2. Используйте компактные методы записи атрибутов: Вместо связки ЗаписатьНачалоАтрибута + ЗаписатьТекст + ЗаписатьКонецАтрибута, используйте одну команду ЗаписатьАтрибут("Имя", "Значение").

Пример оптимизированного заполнения строки отчета:


Счетчик = 0;
Для Каждого СтрокаДанных Из РезультатЗапроса Цикл
    Счетчик = Счетчик + 1;
    СтрНомер = XMLСтрока(Счетчик);
    
    // Записываем наименование
    ЗаписьXML.ЗаписатьНачалоЭлемента("T3RXXXXG2S");
    ЗаписьXML.ЗаписатьАтрибут("ROWNUM", СтрНомер);
    ЗаписьXML.ЗаписатьТекст(СтрокаДанных.КонтрагентНаименование);
    ЗаписьXML.ЗаписатьКонецЭлемента();
    
    // Записываем код ЕДРПОУ
    ЗаписьXML.ЗаписатьНачалоЭлемента("T3RXXXXG3S");
    ЗаписьXML.ЗаписатьАтрибут("ROWNUM", СтрНомер);
    ЗаписьXML.ЗаписатьТекст(СтрокаДанных.КонтрагентКодПоЕДРПОУ);
    ЗаписьXML.ЗаписатьКонецЭлемента();
    
    // Записываем количество
    ЗаписьXML.ЗаписатьНачалоЭлемента("T3RXXXXG5");
    ЗаписьXML.ЗаписатьАтрибут("ROWNUM", СтрНомер);
    ЗаписьXML.ЗаписатьТекст(XMLСтрока(СтрокаДанных.Количество));
    ЗаписьXML.ЗаписатьКонецЭлемента();
КонецЦикла;

Работа с NULL и ссылками в запросах

При выгрузке данных в XML критически важно, чтобы запрос возвращал "чистые" данные. Выясним, какие подводные камни могут встретиться:

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

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

Решение: Получайте все необходимые строковые данные (Наименование, Код, ИНН) сразу в основном запросе. Идеально, если результат запроса — это плоская таблица с типами Строка, Число, Дата.

Использование XDTO — современный подход

Если вам необходимо формировать сложные файлы (например, налоговую отчетность по строгим государственным схемам), ручная запись через ЗаписьXML становится слишком трудоемкой и рискованной. Рассмотрим альтернативу — механизм XDTO.

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

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

Заключение

Подведем итоги нашего анализа. Для корректной работы с XML в 1С следует придерживаться следующих правил:

  1. Никогда не использовать ЗначениеВСтрокуВнутр для экспорта данных.
  2. Всегда использовать XMLСтрока() для преобразования чисел, дат и булевых значений.
  3. Обращаться к полям результата запроса по их псевдонимам.
  4. Минимизировать количество циклов обхода данных.
  5. Предварительно обрабатывать NULL и получать все данные «через точку» еще на этапе выполнения запроса.

Соблюдение этих простых правил не только избавит вас от ошибки «Параметр 1», но и сделает ваши механизмы обмена данными быстрыми и надежными.

← На главную