При автоматизации загрузки банковских выписок одной из наиболее частых задач является извлечение суммы комиссии из текстового поля Назначение платежа. Сложность заключается в том, что разные банки формируют это поле по-разному: кто-то пишет «комиссия», кто-то «удержано ком.», а сумма может быть отделена пробелом, запятой или точкой. Рассмотрим, как реализовать надежный механизм парсинга этой информации.
Для начала разберем стандартный подход. Мы разбиваем строку назначения платежа в массив слов, используя пробел в качестве разделителя. Затем мы перебираем этот массив в поисках ключевого слова-маркера (например, «ком» или «комиссия») и предполагаем, что следующее за ним «слово» и есть искомая сумма.
Проанализируем пример кода, который часто используют начинающие разработчики:
МассивСлов = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(СтрокаСекции.НазначениеПлатежа, " ", Истина);
ТипЧисло = Новый ОписаниеТипов("Число");
Для Индекс = 0 По МассивСлов.ВГраница() Цикл
Слово = МассивСлов[Индекс];
// Проверяем наличие ключевого слова
Если СтрНайти(НРег(Слово), "ком") > 0 Тогда
// Пытаемся взять следующее значение как число
Комиссия = ТипЧисло.ПривестиЗначение(МассивСлов[Индекс + 1]);
Прервать;
КонецЕсли;
КонецЦикла;
На первый взгляд код кажется рабочим, но на практике он сталкивается с рядом проблем, которые мы разберем далее.
Банки могут писать ключевое слово как «Комиссия», «КОМИССИЯ» или «ком». Для корректной работы всегда приводите анализируемое слово к нижнему регистру с помощью функции НРег(). Также вместо функции СтрНайти() лучше использовать СтрНачинаетсяС(), чтобы избежать ложных срабатываний в середине других слов.
Решение: используйте комбинацию СокрЛП() и НРег() для нормализации текста перед проверкой.
Это самая распространенная причина ошибок. В банковской строке после суммы часто стоит запятая или точка (например, «...комиссия 200.01, Дата выручки...»). При попытке преобразовать строку "200.01," в число через ОписаниеТипов или Число(), 1С выдаст ошибку или вернет 0, так как запятая в конце не является частью числа.
Рассмотрим, как правильно очистить строку от «мусора» перед конвертацией:
// Очищаем строку от лишних символов (запятые, точки в конце, пробелы)
СтрСумма = МассивСлов[Индекс + 1];
// Удаляем запятую, если она приклеилась к числу
СтрСумма = СтрЗаменить(СтрСумма, ",", ".");
// Если в конце строки осталась точка (из-за конца предложения), удалим её
Если Прав(СтрСумма, 1) = "." Тогда
СтрСумма = Лев(СтрСумма, СтрДлина(СтрСумма) - 1);
КонецЕсли;
Комиссия = Число(СтрСумма);
Чтобы сделать код максимально отказоустойчивым, проанализируем ситуацию, когда разделителем дробной части может быть как точка, так и запятая, а в строке могут присутствовать невидимые символы (например, неразрывный пробел). Выясним причину ошибки: функция Число() ожидает строго определенный формат. Создадим вспомогательную функцию для извлечения только цифровых данных.
Функция ИзвлечьЧислоИзСтроки(Знач ИсходнаяСтрока)
// Убираем неразрывные пробелы
ИсходнаяСтрока = СтрЗаменить(ИсходнаяСтрока, Символы.НПП, "");
ИсходнаяСтрока = СтрЗаменить(ИсходнаяСтрока, " ", "");
// Оставляем только цифры и разделители
Результат = "";
ДопустимыеСимволы = "0123456789.,";
Для к = 1 По СтрДлина(ИсходнаяСтрока) Цикл
Символ = Сред(ИсходнаяСтрока, к, 1);
Если СтрНайти(ДопустимыеСимволы, Символ) > 0 Тогда
Результат = Результат + Символ;
КонецЕсли;
КонецЦикла;
// Заменяем запятую на точку для универсальности
Результат = СтрЗаменить(Результат, ",", ".");
Попытка
Возврат Число(Результат);
Исключение
Возврат 0;
КонецПопытки;
КонецФункции
Иногда операторы банков или автоматизированные системы используют визуально похожие буквы латинского алфавита (например, латинская «o» в слове «комиссия»). В этом случае СтрНайти с русским текстом не сработает.
Совет: Перед обработкой строки можно выполнить принудительную замену похожих латинских букв на русские. Это гарантирует, что поиск по ключевым словам «ком» или «комиссия» будет успешным вне зависимости от раскладки источника.
Если задача требует высокой точности, а форматы строк постоянно меняются, рассмотрим использование регулярных выражений (RegExp). Это позволит найти число, которое стоит после слова «комиссия», игнорируя любое количество пробелов, двоеточий или тире между ними.
// Пример использования через COM-объект в Windows
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Ложь;
// Ищем шаблоны типа "ком 100.50" или "комиссия: 100,50"
RegExp.Pattern = "(ком|комиссия)[\s\:]*(\d+[\.,]?\d*)";
Matches = RegExp.Execute(НазначениеПлатежа);
Если Matches.Count > 0 Тогда
СуммаСтрокой = Matches.Item(0).SubMatches.Item(1);
Комиссия = ИзвлечьЧислоИзСтроки(СуммаСтрокой);
КонецЕсли;
Подведем итог: для успешного выделения комиссии необходимо:
НРег).СтрНачинаетсяС или СтрНайти).Число.Использование этих методов позволит вашей системе корректно обрабатывать выписки большинства популярных банков, сводя к минимуму необходимость ручного вмешательства бухгалтера.