Версия для печати темы (https://pro1c.org.ua/index.php?showtopic=30988)

Нажмите сюда для просмотра этой темы в обычном формате

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 _ Программирование в 1С Предприятие 7.7 _ Найти договор из содержания платежа (импорт банк.выписок)

Автор: Redneck 22.07.16, 10:59

Добрый день!

Я тут немного занялся автоматизацией импорта банковских выписок в 1С (1С:Предприятие 7.70.027, конфа - БухУч для Украины 7.70.318).
В общем, обработку-переходничок для своего банка дописал (немного нестандартный формат данных был).
Немного повозился с ClientBank.ert и всё заработало.
Контрагенты подтягиваются, а если нет в базе, создаются. Проводки в 97% случаев верные получаются на выходе.

И, вроде бы, все отлично, но я слишком ленив, чтобы к каждой строчке выписки в графе "Заказ" выбирать нужный договор из списка. 64000000.gif

Так что начал парсер внутри 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) все-таки, хоть большинство договоров и имеют типовой формат, но хотелось бы универсальности.

В общем, я хочу как-то доработать алгоритм, чтобы не тыкать никуда мышкой лишний раз 64000000.gif
Но познаний синтаксиса 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) Может, я велосипед изобретаю? Ни у кого нет подходящих кусков кода?

Буду крайне благодарен за любой совет, кусок кода или хоть намек!

Автор: Sharzem 22.07.16, 11:47

А что если:
1. Смотреть в задолженность в разрезе договоров, если задолженность только по 1-му договору - то подставлять только его независимо от того что написано в назначении.
2. Предоплату искать по Вашему алгоритму по вхождению "попередня", "предоплата" в строке без пробелов с поиском по номеру договора;
3. Попробовать вычислить "просроченную" задолженность по договорам, ведь может быть 1 платеж по нескольким и распределить сумму по ним.

В любом случае, оплата может быть и согласно счета, и как пример "за медикаменти та вироби медичного призначення" без указания № договора или счета, и еще как угодно, залезет 1 строчкой в выписку, а разделить нужно на несколько.

Мои бухи все правят ручками, привыкли наверное, подобного не просили (а может просили, только им когда-то вежливо отказали)

Автор: andrey.v.m 24.07.16, 20:34

Redneck @ 22.07.16, 11:59 http://pro1c.org.ua/index.php?act=findpost&pid=114735: 1
 


Автор: Redneck 28.07.16, 14:33

Sharzem @ 22.07.16, 12:47 http://pro1c.org.ua/index.php?act=findpost&pid=114738,
Большое спасибо за совет. Я уже "перелопатил" с нуля почти алгоритм.
По сути, теперь отошел от необходимости искать отдельно даты и номера договоров.
Удаляю все пробелы в назначении платежа и в получившейся строке перебираю все договора с контрагентом (НомДог и ДатаДог) в ОБРАТНОМ порядке.
Результаты пока очень порадовали. Примерно 9 из 10 цепляет отлично.

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7
https://pro1c.org.ua