Как в 1С 7.7 объединить данные строк табличной части в одну длинную строку для выгрузки в файл

Программист 1С v7.7 Бухгалтерский учет Финансы и профессиональные услуги
← На главную

При интеграции систем учета с банковскими сервисами типа «Клиент-Банк» (в частности, при выгрузке реестров на зачисление зарплаты) разработчики часто сталкиваются с нестандартными форматами обмена. Один из таких форматов требует, чтобы вся табличная часть со списком сотрудников и суммами передавалась строго в пределах одной строки с разделителями, например, внутри блока ^_Table=...^.

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

Причина проблемы: почему метод ДобавитьСтроку разбивает текст

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


Т.ДобавитьСтроку("^_Table=");
Пока ПолучитьСтроку() = 1 Цикл
    Т.ДобавитьСтроку("Npp1="+СокрЛП(НомерСтроки)+"~Name1="+СокрЛП(Сотрудник)+"~Nch1="+"~Nch2="+СокрЛП(Сотрудник.ЛицевойСчет)+"~Sum1="+СокрЛП(Число(Сумма))+"~"+"^");
КонецЦикла;

Каждый вызов метода ДобавитьСтроку() встроенного объекта Текст добавляет в результирующий текстовый документ символ перевода строки (CRLF). Поэтому префикс ^_Table= и записи каждого отдельного сотрудника оказываются на новых строках. Для решения задачи необходимо предварительно накопить всю цепочку данных в строковую переменную внутри цикла и лишь затем единовременно отправить ее в файл.

Решение: накопление строки через строковую переменную

Рассмотрим основной способ решения, предложенный на форуме. Разберем его по шагам:

  1. Объявляем переменную перед началом обхода табличной части и инициализируем ее начальным тегом ^_Table=.
  2. Внутри цикла Пока ПолучитьСтроку() = 1 Цикл выполняем конкатенацию сведений о сотруднике, разделяя поля тильдой ~.
  3. После завершения цикла добавляем закрывающий знак ^ и вызываем Т.ДобавитьСтроку() ровно один раз для всей собранной конструкции.

Посмотрим на исправленный код процедуры выгрузки:


СтрочкаВывода = "^_Table=";

Пока ПолучитьСтроку() = 1 Цикл
    СтрочкаВывода = СтрочкаВывода + "Npp1=" + СокрЛП(НомерСтроки) 
        + "~Name1=" + СокрЛП(Сотрудник) 
        + "~Nch1=" 
        + "~Nch2=" + СокрЛП(Сотрудник.ЛицевойСчет) 
        + "~Sum1=" + СокрЛП(Число(Сумма)) + "~";
КонецЦикла;

// Закрываем блок символом циркумфлекса и добавляем в объект Текст одной строкой
Т.ДобавитьСтроку(СтрочкаВывода + "^");

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


^_Table=Npp1=1~Name1=Иванов Иван Иванович~Nch1=~Nch2=720000159~Sum1=150000~Npp1=2~Name1=Петров Петр Петрович~Nch1=~Nch2=720000147~Sum1=540000~^

Важные ограничения 1С 7.7 при работе с длинными строками

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

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

Альтернативное решение: потоковая запись без накопления в памяти

Если в реестре зарплаты содержится большое количество сотрудников, чтобы избежать переполнения памяти и ограничений платформы, применим потоковую запись через системный COM-объект Windows Scripting.FileSystemObject. Метод Write() записывает данные в файл напрямую без перевода строки:


ФСО = СоздатьОбъект("Scripting.FileSystemObject");
Файл = ФСО.CreateTextFile("E:\query.txt", 1); // 1 - перезапись файла

// Записываем открывающий блок
Файл.Write("^_Table=");

ВыбратьСтроки();
Пока ПолучитьСтроку() = 1 Цикл
    СтрСотрудника = "Npp1=" + СокрЛП(НомерСтроки) 
        + "~Name1=" + СокрЛП(Сотрудник) 
        + "~Nch1=" 
        + "~Nch2=" + СокрЛП(Сотрудник.ЛицевойСчет) 
        + "~Sum1=" + СокрЛП(Формат(Сумма, "Ч15.2.")) + "~";
    
    // Записываем порцию данных без перевода строки
    Файл.Write(СтрСотрудника);
КонецЦикла;

// Закрываем секцию и переводим строку
Файл.WriteLine("^");

// Далее можно записывать остальные параметры через WriteLine()
Файл.WriteLine("^AccountCUR=" + СокрЛП(Формат(Итог("Сумма"), "Ч016.2. ")) + "^");

Файл.Close();
Сообщить("Выгрузка успешно завершена потоковым методом!");

Подводные камни формата данных реестра

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

  1. Форматирование чисел: Конструкция СокрЛП(Число(Сумма)) для целых чисел отсекает нулевые копейки (получится 150 вместо 150.00). Для финансовых реестров критически важно сохранять разрядность копеек. Используйте функцию Формат(Сумма, "Ч15.2.") или специализированные шаблоны форматирования сумм, принятые банком.
  2. Служебные спецсимволы в ФИО: Если в наименовании сотрудника или реквизитах случайно окажется тильда ~ или циркумфлекс ^, структура файла нарушится. Перед добавлением значений рекомендуется экранировать или вырезать их через СтрЗаменить(СокрЛП(Сотрудник), "~", "").
← На главную