При автоматической загрузке банковских выписок по эквайрингу в конфигурациях 1С (в частности, в «Бухгалтерии предприятия 2.0») реквизит НазначениеПлатежа часто содержит детальную расшифровку операции. Типичный пример строки: «Эквайринг, перечислено по реестру от 01.11.2016. (Количество операций 2 на сумму 1,400.00 по мерчанту , удержано: комиссии 25.20, возвратов 0.00/0.00)». Перед разработчиком встает практическая задача: программно выделить числовое значение комиссии банка из этой текстовой строки и заполнить соответствующий реквизит документа.
Разберем детально, какими способами можно решить эту задачу на платформе «1С:Предприятие», какие строковые функции использовать и на какие подводные камни при преобразовании типов следует обратить внимание.
Рассмотрим популярный и компактный прием, когда сложный текст превращается в многострочный фрагмент с помощью разделителя переноса строки Символы.ПС. Это позволяет избежать сложных посимвольных циклов.
Разберем логику работы по шагам:
": комиссии ".СтрЗаменить(). Теперь нужная нам сумма окажется в начале второй строки.СтрПолучитьСтроку() получим второй фрагмент текста.Символы.ПС и возьмем первую строку.Посмотрим на пример реализации на встроенном языке 1С:
ТекстНазначения = "Эквайринг, перечислено по реестру от 01.11.2016. (Количество операций 2 на сумму 1,400.00 по мерчанту , удержано: комиссии 25.20, возвратов 0.00/0.00)";
Маркер = ": комиссии ";
ПозицияМаркера = Найти(ТекстНазначения, Маркер);
Если ПозицияМаркера > 0 Тогда
// Отсекаем начало текста до суммы
ФрагментПослеМаркера = СтрПолучитьСтроку(СтрЗаменить(ТекстНазначения, Маркер, Символы.ПС), 2);
// Отсекаем хвост после суммы по первой запятой
СтрокаСуммы = СтрПолучитьСтроку(СтрЗаменить(ФрагментПослеМаркера, ",", Символы.ПС), 1);
СтрокаСуммы = СокрЛП(СтрокаСуммы);
// В 1С при русской локализации разделителем дробной части является запятая
СтрокаСуммы = СтрЗаменить(СтрокаСуммы, ".", ",");
// Удаляем неразрывные и обычные пробелы на случай разделителей тысяч
СтрокаСуммы = СтрЗаменить(СтрокаСуммы, " ", "");
СтрокаСуммы = СтрЗаменить(СтрокаСуммы, Символ(160), "");
Попытка
СуммаКомиссии = Число(СтрокаСуммы);
Исключение
СуммаКомиссии = 0;
КонецПопытки;
КонецЕсли;
Проанализируем альтернативный подход. Метод разбиения через СтрЗаменить() может дать сбой, если банк изменит знаки препинания после суммы (например, поставит точку с запятой или пробел вместо запятой). Для более надежного разбора подходит посимвольный сбор числа.
Разберем алгоритм по шагам:
"комиссии".Сред().Посмотрим на практический код такой функции:
Функция ПолучитьСуммуКомиссииИзТекста(Знач Текст) Экспорт
Маркер = "комиссии";
Позиция = Найти(НРег(Текст), Маркер);
Если Позиция = 0 Тогда
Возврат 0;
КонецЕсли;
// Смещаем позицию за слово-маркер
Индекс = Позиция + СтрДлина(Маркер);
ДлинаТекста = СтрДлина(Текст);
СтрокаЧисла = "";
СборНачат = Ложь;
Пока Индекс <= ДлинаТекста Цикл
СимволТекста = Сред(Текст, Индекс, 1);
Код = КодСимвола(СимволТекста);
// Цифры 0-9 имеют коды 48-57
ЭтоЦифра = (Код >= 48 И Код <= 57);
ЭтоРазделитель = (СимволТекста = "." Или СимволТекста = ",");
Если ЭтоЦифра Тогда
СтрокаЧисла = СтрокаЧисла + СимволТекста;
СборНачат = Истина;
ИначеЕсли ЭтоРазделитель И СборНачат Тогда
СтрокаЧисла = СтрокаЧисла + ",";
ИначеЕсли СборНачат Тогда
// Если сбор уже начался и встретился нецифровой символ — число закончилось
Прервать;
КонецЕсли;
Индекс = Индекс + 1;
КонецЦикла;
Попытка
Возврат Число(СтрокаЧисла);
Исключение
Возврат 0;
КонецПопытки;
КонецФункции
При написании строковых алгоритмов важно учитывать версию платформы и режим совместимости вашей конфигурации:
Найти(<Строка>, <ПодстрокаПоиска>) — базовый глобальный метод, который работает во всех версиях 1С:Предприятия 8.x. Однако начиная с релиза платформы 8.3.6 данный метод объявлен устаревшим.СтрНайти(<Строка>, <ПодстрокаПоиска>, <НаправлениеПоиска>, <НачальнаяПозиция>, <НомерВхождения>) — современная функция платформы 8.3. Она значительно гибче, так как позволяет искать вхождения с определенной позиции и в обратном направлении. При отключении режима совместимости с устаревшими версиями рекомендуется использовать именно её.Выясним причину возможных сбоев при автоматическом разборе текста выписок и перечислим правила безопасной работы:
Число("25.20") с точкой вызовет исключение при русской локализации информационной базы. Перед вызовом Число() точка всегда должна заменяться на запятую." " его не удалит, поэтому обязательно вызывайте СтрЗаменить(Строка, Символ(160), "").