При выгрузке данных из 1С во внешние файлы (особенно в формате CSV, предназначенном для сторонних систем) программисты часто сталкиваются с тем, что числа выводятся с разделителями групп разрядов. Вместо ожидаемого 1000 в файл попадает строка 1 000. Это происходит из-за того, что платформа 1С по умолчанию применяет региональные настройки операционной системы при преобразовании числа в строку. Рассмотрим подробнее, почему это происходит и какими способами можно привести числа к "техническому" виду без лишних пробелов.
Важно понимать, что в 1С пробел между разрядами — это не обычный символ пробела (код 32), а так называемый неразрывный пробел (код 160). В языке 1С он представлен системной константой Символы.НПП. Именно поэтому стандартная функция СтрЗаменить(СтрокаЧисла, " ", "") часто не приносит результата — она просто не находит обычные пробелы там, где стоят неразрывные.
Проанализируем ситуацию: когда мы используем оператор + для сложения строки и числа, 1С неявно вызывает функцию Строка(), которая форматирует число согласно правилам текущего языка и региона. Чтобы этого избежать, нам нужно явно управлять процессом преобразования.
Это самый правильный и гибкий метод с точки зрения платформы 1С. Функция Формат() позволяет точно указать, как должно выглядеть число в строковом представлении. Для решения нашей задачи используется параметр ЧГ=0 (Группировка разрядов = 0).
Рассмотрим пример использования:
// Вариант с явным указанием отсутствия группировки
Результат = Формат(Запись.ЦенаУслуги, "ЧГ=0");
// Можно также использовать пустую строку группировки
Результат = Формат(Запись.ЦенаУслуги, "ЧГ=");
Разберем, что именно мы сделали. Параметр ЧГ (Число: Группировка) определяет количество цифр в группе. Установив значение 0, мы даем платформе команду не разделять число на группы (тысячи, миллионы и т.д.).
Для выгрузки в CSV часто требуется также заменить десятичную запятую на точку и обеспечить вывод нуля в пустых значениях. В этом случае форматная строка будет выглядеть так:
ЦенаСтрокой = Формат(Запись.ЦенаУслуги, "ЧГ=0; ЧРД=.; ЧН=0");
// ЧГ=0 — убираем пробелы
// ЧРД=. — устанавливаем точку как разделитель дробной части
// ЧН=0 — если число равно 0, выводить "0", а не пустую строку
Если по каким-то причинам вы предпочитаете работать с уже полученной строкой, можно воспользоваться функцией замены. Но, как мы выяснили ранее, заменять нужно именно неразрывный пробел.
Рассмотрим, как реализовать это правильно через вспомогательную функцию:
Функция ЧислоВСтрокуБезПробелов(ЗначениеЧисло)
// Преобразуем число в стандартную строку
СтрокаСПробелами = Строка(ЗначениеЧисло);
// Удаляем неразрывные пробелы
Возврат СтрЗаменить(СтрокаСПробелами, Символы.НПП, "");
КонецФункции
Этот метод часто используется в старых конфигурациях или когда нужно быстро "почистить" результат, не вникая в синтаксис форматных строк. Однако он менее производителен, чем Формат(), так как сначала создается строка с пробелами, а потом выполняется поиск и замена в памяти.
Существует еще один "хитрый" и очень быстрый способ, о котором часто забывают. Функция XMLСтрока(Число) предназначена для преобразования данных в формат, пригодный для XML. По стандарту XML числа не должны иметь разделителей групп и всегда используют точку в качестве десятичного разделителя.
Проанализируем пример:
// Получим "1000.50" вместо "1 000,50"
СтрокаДляCSV = XMLСтрока(Запись.ВнутреннийКодУслуги);
Этот способ идеален для технических нужд, так как он гарантирует отсутствие пробелов и стабильность формата независимо от того, на каком сервере или под каким пользователем (с какими региональными настройками) запущен код.
Теперь посмотрим, как применить эти знания к коду из вопроса автора. Нам нужно модифицировать функцию СоздатьДанныеCSV. Вместо прямого сложения полей, мы применим форматирование к числовым колонкам.
Функция СоздатьДанныеCSV(ТаблицаЗначений, разделитель)
Текст = "";
Для Каждого Запись Из ТаблицаЗначений Цикл
Если Текст = "" Тогда
Текст = СоздатьЗаголовкиCSV(ТаблицаЗначений, разделитель) + Символы.ПС;
КонецЕсли;
// Применяем форматирование к каждому числовому полю
КодГруппы = Формат(Запись.ВнутреннийКодГруппыУслуг, "ЧГ=0");
КодПодгруппы = Формат(Запись.ВнутреннийКодПодгруппыУслуг, "ЧГ=0");
КодУслуги = Формат(Запись.ВнутреннийКодУслуги, "ЧГ=0");
КассовыйКод = Формат(Запись.КассовыйКодУслуги, "ЧГ=0");
Цена = Формат(Запись.ЦенаУслуги, "ЧГ=0; ЧРД=.");
Текст = Текст + КодГруппы + разделитель
+ Запись.НазваниеГруппыУслуг + разделитель
+ КодПодгруппы + разделитель
+ Запись.НазваниеПодгруппыУслуг + разделитель
+ КодУслуги + разделитель
+ Запись.НазваниеУслуги + разделитель
+ КассовыйКод + разделитель
+ Цена + Символы.ПС;
КонецЦикла;
Возврат Текст;
КонецФункции
Иногда после того, как программист 1С успешно убрал все пробелы и выгрузил файл, пользователь открывает его в Microsoft Excel и снова видит пробелы в тысячах. В этот момент может возникнуть ложное ощущение, что код 1С не сработал.
Выясним причину: Excel при открытии CSV-файла автоматически распознает числа. Если он видит строку "1000", он преобразует её в числовой тип данных и применяет к ней свой собственный формат ячейки, который в русской локализации Windows обычно включает разделитель групп разрядов.
Чтобы проверить реальное содержимое файла:
1000, значит ваша задача в 1С решена корректно.="1000" внутри CSV, но это специфический метод, подходящий не для всех систем.Подведем итог: для надежной выгрузки данных без пробелов лучше всего использовать Формат(Значение, "ЧГ=0") или XMLСтрока(Значение). Это гарантирует, что сторонние системы корректно интерпретируют ваши числовые данные и коды.