Добрый день!
Я тут немного занялся автоматизацией импорта банковских выписок в 1С (1С:Предприятие 7.70.027, конфа - БухУч для Украины 7.70.318).
В общем, обработку-переходничок для своего банка дописал (немного нестандартный формат данных был).
Немного повозился с ClientBank.ert и всё заработало.
Контрагенты подтягиваются, а если нет в базе, создаются. Проводки в 97% случаев верные получаются на выходе.
И, вроде бы, все отлично, но я
слишком ленив, чтобы к каждой строчке выписки в графе "Заказ" выбирать нужный договор из списка.
Так что начал парсер внутри ClientBank.ert...
Большинство договоров имеют номер документа типа ***/СД, от этого и оттолкнулся для начала.
Вот код (первый вариант):
//ОТБОР ЗАКАЗОВ - ПАРСЕР
ВхСтр = тВыписка.Содержание;
// проверяем, не вписал ли бухгалтер английскую буковку "С";-)
Если Найти(Врег(ВхСтр),Врег("/СД"))>0 Тогда
СодержНачСимвДог=Найти(Врег(ВхСтр),Врег("/СД"))
Иначе
СодержНачСимвДог=Найти(Врег(ВхСтр),Врег("/CД"))
КонецЕсли;
Сообщить("");
Сообщить(ВхСтр);
Если СодержНачСимвДог = 0 Тогда
СодержДог= "";
Сообщить("Увы, договор в содержании платежа не найден. Хотя, может, его там и нет просто");
Иначе
СодержДог = СокрЛП(СтрЗаменить(Сред(ВхСтр,СодержНачСимвДог-3,6),"№",""));
Сообщить("ЕСТЬ! Найден договор: "+СодержДог);
КонецЕсли;
ВхСтр=СтрЗаменить(ВхСтр," ",РазделительСтрок);
Для пц=1 По СтрКоличествоСтрок(ВхСтр) Цикл
ТекСтр=СтрПолучитьСтроку(ВхСтр,пц);
ТекДата=Дата(ТекСтр);
Если (ПустоеЗначение(ТекДата)<>1) Тогда
Сообщить("Нашли дату: "+ТекДата);
СодержДатаДог=ТекДата;
ДокЗкз = СоздатьОбъект("Документ.Договор");
Если (ДокЗкз.НайтиПоНомеру(СодержДог,СодержДатаДог) = 1) Тогда
Сообщить(ДокЗкз.ПолучитьАтрибут("Контрагент"));
Сообщить(тВыписка.Контрагент);
Если СокрЛП(ДокЗкз.ПолучитьАтрибут("Контрагент")) = СокрЛП(тВыписка.Контрагент) Тогда
Док.Заказ = ДокЗкз.ТекущийДокумент();
сообщить(Док.Заказ);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
//ОТБОР ЗАКАЗОВ - ПАРСЕР
В целом, работает, но количество успешных подхватов едва превышает 60% (тестил на базе выписок за полгода).
Хочется довести до 90% хотя бы...
Но мешают мне
следующие проблемы:1) бухгалтера-"слэшеры", которые любят вводить даты странными способами:
"22/12/2015", "22122015", "22,12,15" и т.п. // тут еще ладно (можно прописать проверку на наличие двух вхождений слэша(запяты) и замянять их на точки перед функцией Дата().
2) бухгалтера-"пробельщики", которые суют свои пробелы куда не попадя:
в в даты "01 .10. 2015", и в номера договоров... //как с этими бороться, ума не приложу - мой парсер основан весь на процедуре с разбивкой строки по пробелам и дальнейшему анализу подстрок. Так каша получается полная
3) бухгалтера-"копипастеры", которые вписывают в назначение платежа старые договора
//тут скорее уже проблема не в процедуре импорта, пожалуй, но все равно раздражает
4) все-таки, хоть большинство договоров и имеют типовой формат, но хотелось бы универсальности.
В общем, я хочу как-то доработать алгоритм, чтобы не тыкать никуда мышкой лишний раз
Но познаний синтаксиса 1С, особенно для работы со строками у меня явно не хватает. Нужна Ваша помощь.
Сегодня с утра появилась идея, но не могу пока оценить, выполнимо ли это в принципе.
Что будет, если завернуть алгоритм в обратную сторону:
Пример назначения платежа:
Сплата за газовий конденсат згiдно дог.№2 22/СД вiд 15.1 1.15р. ПДВ 134166,67 грн.
1) Убираем все пробелы:
Сплатазагазовийконденсатзгiднодог.№222/СДвiд15.11.15р.ПДВ134166,67грн.
2) Формируем список всех договоров по Контрагенту (он уже известен на этом этапе)
3) Циклом проверяем наличии НомерДог и ДатаДог в беспробельном назначении платежа для каждого договора.
4) Если оба нашлись, то устанавливаем заказ, иначе: Сообщить("Облом... ;(");
Вопросы:1) Так может получиться?
2) Как правильно реализовать перебор договоров по отдельному контрагенту циклом, чтобы минимально нагружать систему?
3) Может, я велосипед изобретаю? Ни у кого нет подходящих кусков кода?
Буду крайне благодарен за любой совет, кусок кода или хоть намек!