Почему не загружается количество из Excel в документ 1С и как это исправить

Программист 1С v8.3 (Управляемые формы) Управленческий учет
← На главную

При разработке механизмов импорта данных из внешних файлов, таких как Excel, программисты 1С часто сталкиваются с ситуацией, когда данные до 1000 загружаются корректно, а числа, начиная с 1000 и выше, вызывают ошибку «Преобразование значения к типу Число не может быть выполнено». Это происходит из-за особенностей форматирования ячеек в Excel и того, как 1С интерпретирует текстовое представление этих данных.

В этой статье мы подробно разберем причины возникновения этой ошибки, проанализируем разницу между визуальным представлением данных и их внутренним содержанием, а также составим универсальный алгоритм для безопасного преобразования «грязных» строк в числовой формат 1С.

Разбор причины: почему функция Число() выдает ошибку

Давайте проанализируем ситуацию. Когда мы используем метод ТекущаяОбласть.Текст при чтении ТабличногоДокумента, 1С получает строку в точности так, как она отображается на экране. Excel для удобства пользователя часто добавляет в числа разделители разрядов. Для чисел больше 999 таким разделителем обычно выступает неразрывный пробел.

Важный нюанс: обычный пробел (код символа 32) и неразрывный пробел (код символа 160) — это разные символы для системы. Стандартная функция 1С Число() ожидает на вход строку, состоящую исключительно из цифр и одного десятичного разделителя (запятой или точки, в зависимости от настроек). Любой лишний символ, будь то пробел, неразрывный пробел или символ валюты, приводит к аварийному завершению операции.

Шаг 1. Правильное чтение данных из ячейки

Прежде чем приступать к очистке строки, давайте рассмотрим, как мы получаем данные. Часто в коде встречается следующий подход:


Кол = ТабДок.ПолучитьОбласть("R" + Формат(НомерСтроки, "ЧГ=0") + "C3").ТекущаяОбласть.Текст;

Проблема здесь заключается в использовании свойства Текст. Если наша задача — получить числовое значение, более правильным будет проверить, содержит ли область значение, и обратиться напрямую к нему. Давайте посмотрим, как изменить логику получения данных:


ОбластьЯчейки = ТабДок.Область(НомерСтроки, 3);
Если ОбластьЯчейки.СодержитЗначение Тогда
    ЗначениеКоличества = ОбластьЯчейки.Значение;
Иначе
    ЗначениеКоличества = ОбластьЯчейки.Текст;
КонецЕсли;

Если ячейка в Excel была отформатирована как числовая, 1С при чтении файла методом Прочитать() может автоматически распознать тип и вернуть уже готовое число. В этом случае дополнительные преобразования не потребуются.

Шаг 2. Очистка строки от неразрывных пробелов

Если же мы вынуждены работать с текстовым представлением (например, формат ячейки в Excel был «Текстовый»), нам необходимо гарантированно удалить все разделители разрядов. Как мы выяснили, основной виновник — неразрывный пробел. Рассмотрим, как эффективно его удалить.

В языке 1С существует встроенная константа Символы.НПП, которая соответствует неразрывному пробелу. Проанализируем пример кода для очистки:


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

Иногда разработчики используют Символ(160), что идентично Символы.НПП. Однако использование предопределенной константы делает код более читаемым и понятным.

Шаг 3. Обработка десятичных разделителей (запятые и точки)

Следующая проблема — различие в десятичных разделителях. В зависимости от региональных настроек Windows, разделителем может быть как точка, так и запятая. В Excel часто встречается формат, где разделителем тысяч является запятая, а десятичным разделителем — точка (американский стандарт).

Выясним, как сделать преобразование универсальным. Мы рекомендуем приводить все разделители к запятой (или к точке, в зависимости от того, что понимает ваш сеанс 1С), предварительно удалив разделители тысяч. Посмотрим на программную реализацию:


// Предположим, что запятая — это разделитель тысяч, а точка — десятичный разделитель
// Сначала удаляем запятые (разделители тысяч)
ЧистаяСтрока = СтрЗаменить(ТекКол, ",", "");
// Затем заменяем точку на запятую для корректной работы функции Число() в русской локализации
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, ".", ",");

Попытка
    РезультатЧисло = Число(ЧистаяСтрока);
Исключение
    Сообщить("Не удалось преобразовать значение: " + ТекКол);
    РезультатЧисло = 0;
КонецПопытки;

Шаг 4. Создание универсальной функции преобразования

Чтобы не дублировать код для каждой колонки (Количество, Цена, Сумма), целесообразно вынести логику в отдельную функцию. Это позволит нам централизованно обрабатывать все возможные «грязные» символы, которые могут прийти из Excel.

Рассмотрим пример такой функции:


Функция ПреобразоватьСтрокуВЧисло(Знач ВходнаяСтрока) Экспорт
    
    // Если передано уже число, просто возвращаем его
    Если ТипЗнч(ВходнаяСтрока) = Тип("Число") Тогда
        Возврат ВходнаяСтрока;
    КонецЕсли;
    
    // Удаляем все виды пробелов
    Результат = СтрЗаменить(ВходнаяСтрока, Символы.НПП, "");
    Результат = СтрЗаменить(Результат, " ", "");
    
    // Удаляем возможные кавычки (часто встречаются в CSV или при копировании)
    Результат = СтрЗаменить(Результат, """", "");
    
    // Обрабатываем десятичные знаки. 
    // Если в строке есть и точка, и запятая, значит запятая — разделитель тысяч (1,250.50)
    Если СтрНайти(Результат, ",") > 0 И СтрНайти(Результат, ".") > 0 Тогда
        Результат = СтрЗаменить(Результат, ",", ""); // Удаляем разделитель тысяч
    КонецЕсли;
    
    // Приводим точку к запятой (для стандартной работы Число() в РФ)
    Результат = СтрЗаменить(Результат, ".", ",");
    
    Попытка
        Возврат Число(Результат);
    Исключение
        Возврат 0;
    КонецПопытки;
    
КонецФункции

Практические советы при работе с загрузкой из Excel

Разберем еще несколько важных моментов, которые помогут избежать ошибок при загрузке данных:

  1. Проверка на пустые строки: Всегда проверяйте содержимое ячейки перед преобразованием. Если ячейка пустая, функция Число() выдаст ошибку. Используйте ПустаяСтрока().
  2. Типизация колонок: Если вы сначала загружаете данные в ТаблицуЗначений, убедитесь, что колонка имеет тип ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)). Это предотвратит ошибки при дальнейшей записи в документ.
  3. Отладка: Если загрузка все равно не проходит, используйте в отладчике функцию КодСимвола(Стр, Позиция). Проверьте каждый символ в проблемной строке. Если вы видите код 160 — это неразрывный пробел, если код 8239 — это узкий неразрывный пробел, который также нужно удалять.
  4. Обрезка пробелов: Используйте функцию СокрЛП(), чтобы удалить случайные пробелы в начале и в конце считанной строки.

Проанализировав ситуацию с загрузкой 1000 и более единиц товара, мы видим, что проблема всегда кроется в визуальном форматировании. Применяя вышеописанные методы очистки строк, мы обеспечим стабильную работу нашей обработки загрузки вне зависимости от того, как настроен Excel у пользователя.

← На главную