Как настроить разбор размеров и габаритов номенклатуры при импорте из Excel в 1С 7.7?

Программист 1С v7.7 Торговля и дистрибуция
← На главную

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

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

Причины сбоев при парсинге строк

Проанализируем типовой фрагмент кода, предназначенный для разбора размеров одежды:


Таблица.Размер = СтрЗаменить(УбратьНечисловые(Поиск(Значение1, "(\рост\s*)\d{1,}[\S]\d{1,}")), "-", ",") + "-" + УбратьНечисловые(Поиск(Значение1, "(размер\s*)\d{2,3}"));

При обработке позиций вида «Одеяло 205х148» в такой логике возникают следующие проблемы:

  1. Жесткая привязка к ключевым словам: в описании текстиля нет слова «рост». Если функция поиска возвращает 0 или пустую строку, в результирующее поле попадает некорректное значение (например, 0-205).
  2. Удаление знаков-разделителей: вспомогательные функции очистки вроде УбратьНечисловые удаляют символ умножения (*, х, x), превращая габариты 205*148 в слитное число 205148.
  3. Омоглифы и кодировки: знак разделителя размеров может быть введен русской буквой «х», латинской «x», символом «*» или типографским знаком умножения «×».

Способ 1. Использование групп захвата VBScript.RegExp

В платформе 1С 7.7 нет встроенного механизма регулярных выражений, поэтому для парсинга традиционно используется COM-объект VBScript.RegExp. Чтобы не зачищать найденные подстроки дополнительными функциями, правильнее сразу извлекать нужные компоненты с помощью групп захвата (круглые скобки () и свойство SubMatches).

Разберем по шагам алгоритм универсального разбора строки:


Рег = СоздатьОбъект("VBScript.RegExp");
Рег.IgnoreCase = 1;
Рег.Global = 0;

СтрДляПоиска = СокрЛП(Значение1);

// 1. Проверяем наличие линейных габаритов (текстиль, одеяла: 205х148, 205*148)
Рег.Pattern = "(\d{2,4})\s*[*xхXХ×]\s*(\d{2,4})";
Коллекция = Рег.Execute(СтрДляПоиска);

Если Коллекция.Count > 0 Тогда
    Матч = Коллекция.Item(0);
    // Формируем размер в формате Длина*Ширина
    Таблица.Размер = Матч.SubMatches(0) + "*" + Матч.SubMatches(1);
Иначе
    // 2. Если габариты не найдены, выполняем поиск характеристик одежды (рост и размер)
    Рег.Pattern = "(?:рост\s*)(\d{2,3}(?:[-,]\d{2,3})?)";
    КоллекцияРост = Рег.Execute(СтрДляПоиска);
    ЗначРост = "";
    Если КоллекцияРост.Count > 0 Тогда
        ЗначРост = СтрЗаменить(КоллекцияРост.Item(0).SubMatches(0), "-", ",");
    КонецЕсли;

    Рег.Pattern = "(?:размер\s*)(\d{2,3})";
    КоллекцияРазм = Рег.Execute(СтрДляПоиска);
    ЗначРазм = "";
    Если КоллекцияРазм.Count > 0 Тогда
        ЗначРазм = КоллекцияРазм.Item(0).SubMatches(0);
    КонецЕсли;

    // 3. Формируем итоговую строку размера
    Если (ПустаяСтрока(ЗначРост) = 0) И (ПустаяСтрока(ЗначРазм) = 0) Тогда
        Таблица.Размер = ЗначРост + "-" + ЗначРазм;
    Иначе
        Таблица.Размер = СокрЛП(ЗначРост + ЗначРазм);
    КонецЕсли;
КонецЕсли;

Посмотрим на особенности этого шаблона:

  1. Паттерн (\d{2,4})\s*[*xхXХ×]\s*(\d{2,4}) захватывает от 2 до 4 цифр первого измерения, учитывает возможные пробелы, распознает русскую «х», латинскую «x», знак «*» и символ «×», после чего захватывает второе измерение.
  2. Конструкция (?:...) выполняет сопоставление без создания группы захвата, что позволяет извлекать через SubMatches(0) только само числовое значение без ключевых слов «рост» или «размер».

Способ 2. Предварительная нормализация строки

Если в файле Excel разделители и регистр символов сильно различаются, перед запуском поиска целесообразно выполнить предварительную подготовку строки стандартными функциями 1С 7.7:


Стр = НРег(СокрЛП(Значение1));
// Заменяем латинскую 'x' и типографский знак на русскую 'х'
Стр = СтрЗаменить(Стр, "x", "х");
Стр = СтрЗаменить(Стр, "*", "х");

После такой нормализации в регулярных выражениях можно использовать единый символ-разделитель, что упрощает и ускоряет разбор.

Способ 3. Разбор штатными строковыми функциями без RegExp

Если по соображениям переносимости или стабильности требуется отказаться от внешнего объекта VBScript.RegExp, можно реализовать разбор габаритов через позиционный поиск символов разделителя:


Функция ИзвлечьГабариты(Знач ИсходнаяСтрока)
    ИсходнаяСтрока = НРег(ИсходнаяСтрока);
    ИсходнаяСтрока = СтрЗаменить(ИсходнаяСтрока, "x", "х");
    ИсходнаяСтрока = СтрЗаменить(ИсходнаяСтрока, "*", "х");
    
    Поз = Найти(ИсходнаяСтрока, "х");
    Если Поз = 0 Тогда
        Возврат "";
    КонецЕсли;
    
    // Выделяем числа слева и справа от разделителя
    СтрСлева = СокрЛП(Лев(ИсходнаяСтрока, Поз - 1));
    СтрСправа = СокрЛП(Сред(ИсходнаяСтрока, Поз + 1));
    
    // Получаем последние цифры из левой части
    Числ1 = "";
    Для Индекс = 1 По СтрДлина(СтрСлева) Цикл
        Симв = Сред(СтрСлева, СтрДлина(СтрСлева) - Индекс + 1, 1);
        Если (Симв >= "0") И (Симв <= "9") Тогда
            Числ1 = Симв + Числ1;
        Иначе
            Если ПустаяСтрока(Числ1) = 0 Тогда
                Прервать;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    
    // Получаем первые цифры из правой части
    Числ2 = "";
    Для Индекс = 1 По СтрДлина(СтрСправа) Цикл
        Симв = Сред(СтрСправа, Индекс, 1);
        Если (Симв >= "0") И (Симв <= "9") Тогда
            Числ2 = Числ2 + Симв;
        Иначе
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
    Если (ПустаяСтрока(Числ1) = 0) И (ПустаяСтрока(Числ2) = 0) Тогда
        Возврат Числ1 + "*" + Числ2;
    КонецЕсли;
    
    Возврат "";
КонецФункции

Такой подход полностью автономен, не зависит от сторонних библиотек операционной системы и корректно формирует размеры вида 205*148 для текстильных изделий.

← На главную