Как правильно прочитать числовые значения из Excel в 1С без лишних пробелов и искажений

Программист IT и автоматизация бизнеса
← На главную

При автоматизации обмена данными между 1С и Microsoft Excel через механизм COM-объектов программисты часто сталкиваются с неприятной особенностью: числа, которые в Excel выглядят как обычный текст (например, номера счетов или артикулы), при считывании в 1С обрастают «лишними» символами. Особенно часто это происходит, когда в ячейках Excel по ошибке установлен числовой формат вместо текстового. В результате число 1234567 превращается в строку "1 234 567", где в качестве разделителя выступает не обычный пробел, а специальный неразрывный символ.

В этой статье мы подробно разберем, почему это происходит, проанализируем различные способы получения «чистых» данных и выясним, какие ловушки подстерегают разработчика при использовании стандартных свойств Value и Text.

Причина проблемы: неразрывный пробел (НПП)

Когда Excel отображает большое число с разделителями групп разрядов, он использует специальный символ — неразрывный пробел (символ с кодом 160). Если мы пытаемся применить стандартную функцию СтрЗаменить(Строка, " ", ""), используя обычный пробел (код 32), 1С просто «не видит» эти разделители и оставляет их в строке. Это приводит к тому, что поиск по артикулу или номеру документа в базе данных перестает работать.

Решение 1: Использование свойства .Text (Визуальное отображение)

Самый простой способ, который часто первым приходит на ум — это использование свойства .Text вместо .Value. Рассмотрим пример кода:


// Получаем значение ячейки как оно отображается на экране
ТекстовоеЗначение = ЛистExcel.Cells(НомерСтроки, НомерКолонки).Text;

Проанализируем этот подход. Свойство .Text возвращает ровно то, что пользователь видит в ячейке Excel в данный момент. Если в Excel настроено отображение без пробелов, вы получите чистую строку. Однако у этого метода есть критически опасные недостатки, о которых нужно знать:

  1. Ловушка «решеток» (###): Если колонка в файле Excel слишком узкая для отображения числа, свойство .Text вернет строку, состоящую из символов решетки. Ваша обработка загрузит "###" вместо реальных данных.
  2. Зависимость от региональных настроек: Формат даты или разделителей в .Text зависит от настроек операционной системы. На одном сервере дата может прочитаться как "01.01.2023", а на другом — как "1/1/23", что сломает алгоритмы парсинга.
  3. Низкая скорость: Обращение к .Text заставляет Excel каждый раз просчитывать визуальное форматирование, что значительно замедляет чтение больших файлов.

Решение 2: Очистка через Символы.НПП

Если мы решили использовать свойство .Value, нам необходимо программно удалить неразрывные пробелы. Разберем, как это сделать правильно с помощью встроенных констант 1С:


// Считываем значение
ЗначениеИзExcel = ЛистExcel.Cells(НомерСтроки, НомерКолонки).Value;

// Преобразуем в строку и удаляем неразрывные пробелы
ЧистаяСтрока = СтрЗаменить(Строка(ЗначениеИзExcel), Символы.НПП, "");

// Дополнительно можно удалить и обычные пробелы для надежности
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, " ", "");

Этот способ надежнее, так как он работает с фактическим значением, хранящимся в памяти, а не с его экранным представлением.

Решение 3: Принудительное приведение типов в 1С

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


// Считываем значение
Значение = ЛистExcel.Cells(НомерСтроки, НомерКолонки).Value;

// Превращаем в число (1С сама проигнорирует разделители при COM-преобразовании)
ТекЧисло = Число(Значение);

// Форматируем в строку без разделителей групп
Результат = Формат(ТекЧисло, "ЧГ=0");

Здесь параметр "ЧГ=0" функции Формат() прямо указывает системе, что группировку разрядов использовать не нужно.

Решение 4: Профессиональный стандарт — свойство .Value2

Существует еще одно свойство, которое редко обсуждается на форумах новичков, но является стандартом у профессионалов — это .Value2. Выясним, в чем его преимущество:

В отличие от .Value, свойство .Value2 не преобразует данные в типы «Дата» или «Валюта» на стороне Excel. Оно передает данные в 1С в максимально «сыром» виде. Это самый быстрый и стабильный способ получения числовых данных.


// Использование самого быстрого свойства
Значение = ЛистExcel.Cells(НомерСтроки, НомерКолонки).Value2;
Результат = Формат(Значение, "ЧГ=0");

Важные технические ограничения

Проанализируем ситуацию, когда даже программные методы могут бессильны. Важно помнить о пределе точности Excel:

  1. Проблема 15 знаков: Excel хранит только 15 значащих цифр. Если в ячейку с числовым форматом ввели длинный номер (например, 20-значный номер счета), Excel необратимо заменит все цифры после 15-й нулями. В этом случае ни Value, ни Text не вернут исходные данные. Решение здесь только одно: изначально устанавливать в Excel текстовый формат ячеек перед вводом данных.
  2. Экспоненциальная запись: Очень большие числа Excel часто представляет в виде 1.23E+12. При чтении через Value 1С может воспринять это именно как число. Чтобы избежать путаницы, всегда применяйте функцию Формат() к полученным значениям.

Подведем итог: Для разовых задач допустимо использовать .Text (при условии широких колонок), но для надежных промышленных решений лучше всего использовать .Value2 в сочетании с функцией Формат(Значение, "ЧГ=0") или очисткой строки от Символы.НПП.

← На главную