При автоматизации обмена данными между 1С и Microsoft Excel через механизм COM-объектов программисты часто сталкиваются с неприятной особенностью: числа, которые в Excel выглядят как обычный текст (например, номера счетов или артикулы), при считывании в 1С обрастают «лишними» символами. Особенно часто это происходит, когда в ячейках Excel по ошибке установлен числовой формат вместо текстового. В результате число 1234567 превращается в строку "1 234 567", где в качестве разделителя выступает не обычный пробел, а специальный неразрывный символ.
В этой статье мы подробно разберем, почему это происходит, проанализируем различные способы получения «чистых» данных и выясним, какие ловушки подстерегают разработчика при использовании стандартных свойств Value и Text.
Когда Excel отображает большое число с разделителями групп разрядов, он использует специальный символ — неразрывный пробел (символ с кодом 160). Если мы пытаемся применить стандартную функцию СтрЗаменить(Строка, " ", ""), используя обычный пробел (код 32), 1С просто «не видит» эти разделители и оставляет их в строке. Это приводит к тому, что поиск по артикулу или номеру документа в базе данных перестает работать.
Самый простой способ, который часто первым приходит на ум — это использование свойства .Text вместо .Value. Рассмотрим пример кода:
// Получаем значение ячейки как оно отображается на экране
ТекстовоеЗначение = ЛистExcel.Cells(НомерСтроки, НомерКолонки).Text;
Проанализируем этот подход. Свойство .Text возвращает ровно то, что пользователь видит в ячейке Excel в данный момент. Если в Excel настроено отображение без пробелов, вы получите чистую строку. Однако у этого метода есть критически опасные недостатки, о которых нужно знать:
.Text вернет строку, состоящую из символов решетки. Ваша обработка загрузит "###" вместо реальных данных..Text зависит от настроек операционной системы. На одном сервере дата может прочитаться как "01.01.2023", а на другом — как "1/1/23", что сломает алгоритмы парсинга..Text заставляет Excel каждый раз просчитывать визуальное форматирование, что значительно замедляет чтение больших файлов.Если мы решили использовать свойство .Value, нам необходимо программно удалить неразрывные пробелы. Разберем, как это сделать правильно с помощью встроенных констант 1С:
// Считываем значение
ЗначениеИзExcel = ЛистExcel.Cells(НомерСтроки, НомерКолонки).Value;
// Преобразуем в строку и удаляем неразрывные пробелы
ЧистаяСтрока = СтрЗаменить(Строка(ЗначениеИзExcel), Символы.НПП, "");
// Дополнительно можно удалить и обычные пробелы для надежности
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, " ", "");
Этот способ надежнее, так как он работает с фактическим значением, хранящимся в памяти, а не с его экранным представлением.
Если вы точно знаете, что в ячейке находится число, которое нужно превратить в строку без форматирования, можно воспользоваться функцией Число() и последующим форматированием в 1С. Посмотрим на пример:
// Считываем значение
Значение = ЛистExcel.Cells(НомерСтроки, НомерКолонки).Value;
// Превращаем в число (1С сама проигнорирует разделители при COM-преобразовании)
ТекЧисло = Число(Значение);
// Форматируем в строку без разделителей групп
Результат = Формат(ТекЧисло, "ЧГ=0");
Здесь параметр "ЧГ=0" функции Формат() прямо указывает системе, что группировку разрядов использовать не нужно.
Существует еще одно свойство, которое редко обсуждается на форумах новичков, но является стандартом у профессионалов — это .Value2. Выясним, в чем его преимущество:
В отличие от .Value, свойство .Value2 не преобразует данные в типы «Дата» или «Валюта» на стороне Excel. Оно передает данные в 1С в максимально «сыром» виде. Это самый быстрый и стабильный способ получения числовых данных.
// Использование самого быстрого свойства
Значение = ЛистExcel.Cells(НомерСтроки, НомерКолонки).Value2;
Результат = Формат(Значение, "ЧГ=0");
Проанализируем ситуацию, когда даже программные методы могут бессильны. Важно помнить о пределе точности Excel:
Value, ни Text не вернут исходные данные. Решение здесь только одно: изначально устанавливать в Excel текстовый формат ячеек перед вводом данных.1.23E+12. При чтении через Value 1С может воспринять это именно как число. Чтобы избежать путаницы, всегда применяйте функцию Формат() к полученным значениям.Подведем итог: Для разовых задач допустимо использовать .Text (при условии широких колонок), но для надежных промышленных решений лучше всего использовать .Value2 в сочетании с функцией Формат(Значение, "ЧГ=0") или очисткой строки от Символы.НПП.