Довольно часто при интеграции и выгрузке отчетов из 1С разработчики сталкиваются с неприятной ситуацией: целые значения записываются в Excel нормально, а дробные (например, 12,5) отказываются восприниматься как числа. Если выделить такую ячейку, Excel может показывать формат «Числовой», но математические действия (суммирование, умножение) с этими данными не совершаются. Рассмотрим подробнее, в чем кроется корень этой проблемы и разберем по шагам все возможные способы ее решения.
Проанализируем типичный пример кода, который вызывает подобную ошибку:
Лист.Cells(СчетчикСтрок, 2).NumberFormat = "0,00";
Лист.Cells(СчетчикСтрок, 2).Value = Формат(Цена);
На первый взгляд всё логично: мы задаем формат ячейки, а затем передаем в нее значение. Но давайте выясним причину сбоя. Главная ошибка кроется в использовании функции Формат() при передаче значения в свойство Value. В системе 1С функция Формат() всегда возвращает строку, а не число.
Когда COM-объект Excel получает от 1С строковое значение, он пытается интерпретировать его самостоятельно. В зависимости от региональных настроек компьютера (где разделителем может быть запятая или точка), Excel может сохранить переданное значение именно как текст. Из-за этого формулы перестают работать. Более того, существует опасность, что строку вида "15.02" Excel автоматически превратит в дату — «15 февраля». Чтобы этого избежать, разберем несколько надежных подходов.
Наиболее правильный и надежный подход — передавать в Excel «чистую» числовую переменную без предварительного преобразования ее в строку. Посмотрим на правильный пример:
// Передаем само число, без функции Формат()
Лист.Cells(СчетчикСтрок, 2).Value = Цена;
Интерфейс OLE/COM автоматически и без ошибок конвертирует внутренний числовой тип 1С в числовой формат Excel. В этом случае вам не нужно беспокоиться о том, какой разделитель установлен в системе пользователя — запятая или точка. Excel сам поймет, что это число, и применит к нему нужные локальные настройки.
Если по логике алгоритма вам необходимо передавать именно отформатированную строку (например, данные уже приходят в строковом виде), то нужно учесть конфликт региональных настроек. В числовых значениях 1С разделителем служит точка, а в Excel для России по умолчанию используется запятая.
Чтобы заставить Excel корректно принять строку и распознать в ней число, явно укажите точку в качестве разделителя дробной части при форматировании. Проанализируем пример:
// Задаем точку как разделитель дробей (ЧРД=.) и убираем группировку тысяч (ЧГ=0)
Лист.Cells(СчетчикСтрок, 2).Value = Формат(Цена, "ЧРД=.; ЧГ=0");
Этот способ заставляет Excel правильно конвертировать строку в число на лету, однако он менее универсален, чем первый вариант.
При попытке задать красивый формат числа прямо в Excel из 1С, вы можете столкнуться с ошибкой: «Нельзя установить свойство NumberFormat класса Range». Посмотрим на код, который вызывает эту ошибку:
Лист.Cells(СчетчикСтрок, 2).NumberFormat = "#,##0.00";
Дело в том, что свойство NumberFormat строго привязано к англоязычной (США) локали. Оно требует использования точки в качестве десятичного разделителя и запятой для разделения тысяч, независимо от языка вашей ОС.
Если вы хотите задать формат ячейки, используя привычные региональные стандарты системы (например, запятую для дробей и неразрывный пробел для тысяч), необходимо использовать свойство NumberFormatLocal. Разберем правильный пример:
// Используем NumberFormatLocal для локальных форматов
Лист.Cells(СчетчикСтрок, 2).NumberFormatLocal = "# ##0,00";
Лист.Cells(СчетчикСтрок, 2).Value = Цена;
Если при выгрузке сложных отчетов необходимо управлять разделителями самого приложения Excel напрямую из 1С, вы можете временно переопределить системные настройки через COM-объект. Рассмотрим по шагам этот продвинутый метод:
Посмотрим на пример кода:
ExcelApp = Новый COMОбъект("Excel.Application");
// 1. Отключаем системные разделители
ExcelApp.UseSystemSeparators = Ложь;
// 2. Устанавливаем свои символы
ExcelApp.DecimalSeparator = "."; // Точка для дробей
ExcelApp.ThousandsSeparator = " "; // Пробел для тысяч
// ... (здесь ваш код выгрузки данных) ...
// 3. Возвращаем настройки обратно
ExcelApp.UseSystemSeparators = Истина;
Подводя итог, можно сказать, что самым стабильным методом выгрузки чисел является передача чистых числовых типов в свойство Value. Используйте строковое форматирование или переопределение системных настроек только тогда, когда это действительно продиктовано спецификой вашей задачи.