Клиент-банк, поиск плательщиков по назначению платежа

Решение задачи рассмотрим на примере загрузки и разнесения банковской выписки по договорам и контрагентам из текста назначения платежа.

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

  1. Назначение платежа — произвольный текст..
  2. Лицевые счета — Справочник связанный через регистр сведений с договорами контрагентов. Наименование — номер лицевого счета.

Решение: Неизвестно  ГДЕ  в тексте назначения платежа располагается номер лицевого счета, но известно ЧТО имено может быть номером лицевого счета, это одно из наименований справочника Лицевые счета, Т.е. решение задачи сводиться к поиску вхождения номера в текст назначения платежа. Для этого можно использовать перебор, а можно запрос из двух таблиц с условием связи ПОДОБНО, первая таблица — Номера лицевых счетов, вторая — Назначения платежа.  

 Пример с использованием запроса в конфигурации 1С:Учет в управляющих компаниях ЖКХ, ТСЖ и ЖСК, редакция 3.0 

&НаСервере
Процедура ДляКнопкиРасширенияОбработкиКлиентБанкНаСервере()

//Таблица с номерами ЛС
//Убираем лишние пробелы в наименовании ЛС и получаем длину номера ЛС.
//Номера ЛС уникальны, но возможна ситуация когда более короткий ЛС может
//встретиться в более длинном. В  такой ситуации запрос свяжет назначение с несколькими ЛС,
//правильным считаем тот у которого длина больше

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КВП_ЛицевыеСчета.Наименование КАК НаименованиеБезПробелов,
| КВП_ЛицевыеСчета.Ссылка КАК ЛицевойСчет,
| 0 КАК ДлинаНаменования
|ИЗ
| Справочник.КВП_ЛицевыеСчета КАК КВП_ЛицевыеСчета";

ТаблицаЛСБезПобелов = Запрос.Выполнить().Выгрузить();

Для Каждого Строка Из ТаблицаЛСБезПобелов Цикл
Строка.НаименованиеБезПробелов = СокрЛП(Строка.НаименованиеБезПробелов);
Строка.ДлинаНаменования        = СтрДлина(Строка.НаименованиеБезПробелов);
КонецЦикла;


// Таблица Назначения платежа
ТаблицаВыписки = ДокументыКИмпорту.Выгрузить(,"СуммаПоступило,НазначениеПлатежа,ИдентификаторОперации");

//Сам запрос поиска номеров ЛС в назначениях платежа
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТаблицаВыписки.СуммаПоступило,
| ТаблицаВыписки.НазначениеПлатежа,
| ВЫРАЗИТЬ(ТаблицаВыписки.ИдентификаторОперации КАК СТРОКА(6)) КАК ИдентификаторОперации
|ПОМЕСТИТЬ ВТ_Выписка
|ИЗ
| &ТаблицаВыписки КАК ТаблицаВыписки
|ГДЕ
| ТаблицаВыписки.СуммаПоступило > 0
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТаблицаЛСБезПобелов.ЛицевойСчет,
| ТаблицаЛСБезПобелов.НаименованиеБезПробелов,
| ТаблицаЛСБезПобелов.ДлинаНаменования
|ПОМЕСТИТЬ ВТ_ТаблицаЛСБезПобелов
|ИЗ
| &ТаблицаЛСБезПобелов КАК ТаблицаЛСБезПобелов
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ДополнительныеСведения.Объект
|ПОМЕСТИТЬ ВТ_КонтрагентыЗапретОбменаССайтом
|ИЗ
| РегистрСведений.ДополнительныеСведения КАК ДополнительныеСведения
|ГДЕ
| ДополнительныеСведения.Свойство = &СвойствоЗапретОбменаСсайтом
| И ДополнительныеСведения.Значение = ИСТИНА
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| УПЖКХ_СведенияДляВзаиморасчетовПоЛССрезПоследних.Договор,
| УПЖКХ_СведенияДляВзаиморасчетовПоЛССрезПоследних.Контрагент,
| УПЖКХ_СведенияДляВзаиморасчетовПоЛССрезПоследних.ЛицевойСчет,
| ВТ_ТаблицаЛСБезПобелов.НаименованиеБезПробелов,
| ВТ_ТаблицаЛСБезПобелов.ДлинаНаменования
|ПОМЕСТИТЬ ВТ_ЛС
|ИЗ
| РегистрСведений.УПЖКХ_СведенияДляВзаиморасчетовПоЛС.СрезПоследних(
|   ,
|   НЕ Контрагент В
|     (ВЫБРАТЬ
|      ВТ_КонтрагентыЗапретОбменаССайтом.Объект
|     ИЗ
|      ВТ_КонтрагентыЗапретОбменаССайтом КАК ВТ_КонтрагентыЗапретОбменаССайтом)) КАК УПЖКХ_СведенияДляВзаиморасчетовПоЛССрезПоследних
|  ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ТаблицаЛСБезПобелов КАК ВТ_ТаблицаЛСБезПобелов
|  ПО УПЖКХ_СведенияДляВзаиморасчетовПоЛССрезПоследних.ЛицевойСчет = ВТ_ТаблицаЛСБезПобелов.ЛицевойСчет
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТ_Выписка.ИдентификаторОперации,
| ВТ_Выписка.НазначениеПлатежа,
| ВТ_ЛС.Договор,
| ВТ_ЛС.Контрагент,
| ВТ_ЛС.НаименованиеБезПробелов,
| ВТ_ЛС.ЛицевойСчет,
| ВТ_ЛС.ДлинаНаменования
|ПОМЕСТИТЬ ВТ_РезультатСопостовления
|ИЗ
| ВТ_Выписка КАК ВТ_Выписка
|  ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_ЛС КАК ВТ_ЛС
|  ПО (ВТ_Выписка.НазначениеПлатежа ПОДОБНО ""%"" + ВТ_ЛС.НаименованиеБезПробелов + ""%"")
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТ_РезультатСопостовления.ИдентификаторОперации,
| МАКСИМУМ(ВТ_РезультатСопостовления.ДлинаНаменования) КАК ДлинаНаменования
|ПОМЕСТИТЬ ВТ_НужныеЛС
|ИЗ
| ВТ_РезультатСопостовления КАК ВТ_РезультатСопостовления
|
|СГРУППИРОВАТЬ ПО
| ВТ_РезультатСопостовления.ИдентификаторОперации
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТ_НужныеЛС.ИдентификаторОперации,
| ВТ_РезультатСопостовления.НазначениеПлатежа,
| ВТ_РезультатСопостовления.Договор,
| ВТ_РезультатСопостовления.Контрагент,
| ВТ_РезультатСопостовления.НаименованиеБезПробелов,
| ВТ_РезультатСопостовления.ЛицевойСчет,
| ВТ_РезультатСопостовления.ДлинаНаменования
|ИЗ
| ВТ_НужныеЛС КАК ВТ_НужныеЛС
|  ЛЕВОЕ СОЕДИНЕНИЕ ВТ_РезультатСопостовления КАК ВТ_РезультатСопостовления
|  ПО ВТ_НужныеЛС.ИдентификаторОперации = ВТ_РезультатСопостовления.ИдентификаторОперации
|   И ВТ_НужныеЛС.ДлинаНаменования = ВТ_РезультатСопостовления.ДлинаНаменования";

ПВХМенеджер                 = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения;
СвойствоЗапретОбменаСсайтом = ПВХМенеджер.НайтиПоНаименованию("Запретить обмен с сайтом (Контрагенты)");
Запрос.УстановитьПараметр("СвойствоЗапретОбменаСсайтом", СвойствоЗапретОбменаСсайтом);
Запрос.УстановитьПараметр("ТаблицаВыписки", ТаблицаВыписки);
Запрос.УстановитьПараметр("ТаблицаЛСБезПобелов", ТаблицаЛСБезПобелов);

ТаблицаРезультат = Запрос.Выполнить().Выгрузить();

Для каждого Строка Из ТаблицаРезультат Цикл

Отбор = Новый Структура;
Отбор.Вставить("ИдентификаторОперации", СокрЛП(Строка.ИдентификаторОперации));
НайденныеСтроки = ДокументыКИмпорту.НайтиСтроки(Отбор);
Если НайденныеСтроки.Количество() > 0 Тогда
НайденныеСтроки[0].Контрагент  = Строка.Контрагент;
НайденныеСтроки[0].Договор     = Строка.Договор;
НайденныеСтроки[0].ВидОперации = Перечисления.ВидыОперацийПоступлениеДенежныхСредств.ОплатаПокупателя;
КонецЕсли;

//Скопировал штатную процедуру т.к. в штатной подбирается договор, а нам этого не нужно
ДляРасширения_УточнитьХозяйственнуюОперациюДаннымиВведеннымиПользователем(НайденныеСтроки[0], "Контрагент,Договор,ВидОперации")

КонецЦикла;


КонецПроцедуры

 

14 Comments

  1. Scottlinch

    А почему нельзя было воспользоваться регулярными выражениями? Ну скажем из вашего примера подошло бы что то «s(d{2}-d{1,3}-d{1,3}(-)?(d{1})?)s|s(d{2}-d{1,3})s». Разумеется я не знаю какие в принципе у Вас еще бывают л/с, но готов поспорить могу и к ним ключик подобрать =)

    Reply
  2. duhh

    (1) В том то и дело,. что я считаю, нет шаблона у л/с. Хотя кто знает, вот условия: длина произвольная, русские английские буквы, цифры. «-«. Встречаются с пробелами. бывают похожие например 111, 111-2, к-111, кк-111-1. ss-ss-111-1. Более того в тексте могут указать номер квартиры, дома что тоже можно принять за л/с.

    Reply
  3. Scottlinch

    (2) согласен не очень приятный набор л/с. И с тем учётом что не всегда пробелы стоят до и после л/с дела плохи. А на сколько быстро работает ваш запрос?

    Reply
  4. duhh

    (3) На моих данных порядка 20-30 сек. Но главное то, что это ГОРАЗДО быстрей бухгалтера.

    Reply
  5. Scottlinch

    (4) 20-30 сек на какое количество платежей?

    Reply
  6. duhh

    (5) приблизительно 200 платежей, 7000 лс

    Reply
  7. Scottlinch

    ясно у нас 100 000 и 20 000 платежей по времени тоже 1 минуту ищем правда немного другим способом. У Вас очень правильный и интересный способ.

    Reply
  8. user902158

    Добрый день.

    Извините за тупой вопрос, я немного не понял куда этот код воткнуть и что должно произойти по нажатию кнопки ?

    Reply
  9. duhh

    (8)Воткнуть можно в обработку «КлинтБанк». Идея такая, сначала в обработке загружается файл из банка, а потом по нажатию кнопки по назначениям платежа подбираются плательщики (контрагенты, договоры), далее штатными средствами формируются документы. Можно скачать расширение и подключить к своей конфе.

    Reply
  10. user902158

    Добавил в обработку «Клиент-Банк» Этот код убрал все ошибки, но вот с одной бьюсь уже второй день может кто подскажет где я туплю ?

    Вот код ошибки:

    ВнешняяОбработка.КлиентБанк.Форма.Форма.Форма(155,3)}: Процедура или функция с указанным именем не определена (ДляРасширения_УточнитьХозяйственнуюОперациюДаннымиВведенными­Пользователем)

    <<?>>ДляРасширения_УточнитьХозяйственнуюОперациюДаннымиВведенны­миПользователем(НайденныеСтроки[0], «Контрагент,Договор,ВидОперации») (Проверка: Толстый клиент (обычное приложение))

    Reply
  11. duhh
    Reply
  12. user902158

    Появилось время заняться этим вопросом, добавил процедуру, но теперь вот такая ошибка. Я раньше не сталкивался с <wbr> если ставлю скобку как просит то другая ошибка.

    {ВнешняяОбработка.КлиентБанк.МодульОбъекта(101,70)}: Ожидается символ ‘(‘

    Процедура ДляРасширения_УточнитьХозяйственнуюОперациюДаннымиВведенным<­<?>> <wbr>иПользователем(СтрокаДокументыКИмпорту, ИменаВведенныхДанных)экспорт (Проверка: Толстый клиент (обычное приложение))

    {ВнешняяОбработка.КлиентБанк.МодульОбъекта(101,71)}: Ожидается имя формального параметра

    Процедура ДляРасширения_УточнитьХозяйственнуюОперациюДаннымиВведенным(<<?>><wbr>иПользователем(СтрокаДокументыКИмпорту, ИменаВведенныхДанных)экспорт (Проверка: Толстый клиент (обычное приложение))

    Reply
  13. duhh

    <wbr> убрать

    Reply
  14. user902158

    Спасибо за помощь =)

    Правда появилась куча других ошибок, но с ними я постараюсь сам разобраться.

    {ВнешняяОбработка.КлиентБанк.МодульОбъекта(135,63)}: Переменная не определена (АдресХранилищаРаспознанныеДанныеИзБанка)

    РаспознанныеДанныеИзБанка = ПолучитьИзВременногоХранилища(<<?>>АдресХранилищаРаспознанныеДанныеИзБанка); (Проверка: Толстый клиент (обычное приложение))

    {ВнешняяОбработка.КлиентБанк.МодульОбъекта(137,29)}: Переменная не определена (ЗагрузкаВыпискиПоБанковскомуСчету)

    ХозяйственнаяОперация = <<?>>ЗагрузкаВыпискиПоБанковскомуСчету.УточнитьХозяйственнуюОперациюДаннымиВведеннымиПользователем( (Проверка: Толстый клиент (обычное приложение))

    {ВнешняяОбработка.КлиентБанк.МодульОбъекта(152,67)}: Переменная не определена (Объект)

    ПодготовитьОтображениеПредупреждений(СтрокаДокументыКИмпорту, <<?>>Объект.СоздаватьНенайденныеЭлементы); (Проверка: Толстый клиент (обычное приложение))

    {ВнешняяОбработка.КлиентБанк.МодульОбъекта(2534,52)}: Переменная не определена (ДокументыКВыгрузке)

    Запрос.УстановитьПараметр(«ДокументыКВыгрузкеТЗ», <<?>>ДокументыКВыгрузке); (Проверка: Толстый клиент (обычное приложение))

    {ВнешняяОбработка.КлиентБанк.МодульОбъекта(2540,3)}: Переменная не определена (ДокументыКВыгрузке)

    <<?>>ДокументыКВыгрузке[Выборка.НомерСтроки — 1].ЗаявкаНаРасходованиеДенежныхСредств = (Проверка: Толстый клиент (обычное приложение))

    {ВнешняяОбработка.КлиентБанк.МодульОбъекта(2742,10)}: Переменная не определена (ДокументыКВыгрузке)

    Возврат <<?>>ДокументыКВыгрузке.НайтиСтроки(Отбор); (Проверка: Толстый клиент (обычное приложение))

    {ВнешняяОбработка.КлиентБанк.МодульОбъекта(142,9)}: Процедура или функция с указанным именем не определена (НастройкиЗагрузки)

    <<?>>НастройкиЗагрузки()); (Проверка: Толстый клиент (обычное приложение))

    {ВнешняяОбработка.КлиентБанк.МодульОбъекта(149,5)}: Процедура или функция с указанным именем не определена (ЗаполнитьСтрокуПоХозяйственнойОперации)

    <<?>>ЗаполнитьСтрокуПоХозяйственнойОперации(РаспознанныеДанныеИзБанка, СтрокаДокументыКИмпорту, ХозяйственнаяОперация); (Проверка: Толстый клиент (обычное приложение))

    {ВнешняяОбработка.КлиентБанк.МодульОбъекта(151,5)}: Процедура или функция с указанным именем не определена (РазместитьПредупреждение)

    <<?>>РазместитьПредупреждение(СтрокаДокументыКИмпорту); (Проверка: Толстый клиент (обычное приложение))

    {ВнешняяОбработка.КлиентБанк.МодульОбъекта(152,5)}: Процедура или функция с указанным именем не определена (ПодготовитьОтображениеПредупреждений)

    <<?>>ПодготовитьОтображениеПредупреждений(СтрокаДокументыКИмпорту, Объект.СоздаватьНенайденныеЭлементы); (Проверка: Толстый клиент (обычное приложение))

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *