Top.Mail.Ru
31 ИЮЛЯ, 17:00 МСК
БЕСПЛАТНО
Online MeetUp «Индекс в 1С: разбираем реальные кейсы»

Как я доработал обмен ЗУП с личным кабинетом сотрудника, не ломая код на «1С: Элементе»

Идея статьи родилась при доработке функционала личного кабинета сотрудника под требования заказчика.

В настоящее время работаю в Programming Store. Я специализируюсь на конфигурации «1С:ЗУП». В процессе работы приходится решать различные задачи в интересах заказчиков. С одной из них я хотел бы вас познакомить. 

Как родилась идея доработки

Задача от клиента выглядела в принципе несложно: внедрить личный кабинет сотрудника. Но как всегда дьявол покопался в деталях. У заказчика существовало достаточно большое количество внутренних заявлений, до реализации которых у компании 1С руки не дошли. Для таких случаев в личном кабинете сотрудника существует произвольное обращение. Но там есть маленький нюанс: параметры, которые мы создаем в произвольном шаблоне, не передаются в «1С:ЗУП».  И тем не менее они нужны для дальнейшей обработки заявлений: автоматического отклонения обращений, создания документов и прочего.

На момент написания статьи компания 1С вроде бы разрешила доработку личного кабинета сотрудника, написанного на «1С:Элементе», но меня терзали сомнения, что обновление доработанного функционала будет происходить гладко. Очень не хотелось оставлять заказчику такую проблему. Очень, очень не хотелось. Если честно, меня охватило уныние: дорабатывать личный кабинет чревато проблемами, а параметры никак не хотели прилетать в обращениях сотрудников.

Единственное, что приходило из личного кабинета в «1С:ЗУП», — это приложенный файл формата pdf. Хороший формат, удобный. 1С даже умеет в него писать. Но не умеет читать. Кому в здравом уме придет в голову программно читать файл pdf? Я в своей практике такого не помню.  Предыдущий опыт говорил, что это невозможно. Но для очистки совести решил погуглить. Результат меня очень удивил: оказывается, есть утилита РdfToText, которая преобразовывает pdf-файл в текстовый (если, конечно, файл pdf был собран из текста, а не из картинок). В заявлении, которое приходит из личного кабинета в виде pdf-файла, есть все параметры, необходимые нам. Таким образом, если мы сможем преобразовать файл в текст, а затем распарсить, у нас появляется возможность получить так необходимые нам параметры.

Примеры по работе с утилитой PdfToText можно найти на Инфостарте. Правда, при использовании данного примера меня поджидала неприятность: антивирус на сервере заказчика заблокировал выполнение утилиты «hstart.exe». Но оказалось, что она не обязательна —  удалось написать скрипт без нее.

Код функции для чтения рdf-файла

Привожу код функции, которая читает pdf-файл и дальше отправляет его на анализ содержимого: 

Процедура ПрочитатьПараметрыОбращения() Экспорт

               КаталогВременныхФайлов = КаталогВременныхФайлов();

               МакетУтилиты = ПолучитьОбщийМакет("кэдо_PDFToText");

               Адрес = ПоместитьВоВременноеХранилище(МакетУтилиты, Новый УникальныйИдентификатор);

               ФайлУтилиты1 = КаталогВременныхФайлов + "pdftotext.exe";

               ДанныеХранилища = ПолучитьИзВременногоХранилища(Адрес);

               УдалитьИзВременногоХранилища(Адрес);

               ДанныеХранилища.Записать(ФайлУтилиты1);

               Запрос = Новый Запрос;

               Запрос.Текст = "ВЫБРАТЬ
                              |             ОбращениеКабинетСотрудникаПрисоединенныеФайлы.Ссылка КАК Ссылка
                              |ИЗ
                              |             Справочник.ОбращениеКабинетСотрудникаПрисоединенныеФайлы КАК ОбращениеКабинетСотрудникаПрисоединенныеФайлы
                              |ГДЕ
                              |             ОбращениеКабинетСотрудникаПрисоединенныеФайлы.ВладелецФайла = &ВладелецФайла";                             

               Запрос.УстановитьПараметр("ВладелецФайла", ЭтотОбъект.Ссылка);

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

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

               Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
                             

                    Попытка

                              ДанныеФайла = РаботаСФайлами.ДанныеФайла(ВыборкаДетальныеЗаписи.ССылка, РаботаСФайламиКлиентСервер.ПараметрыДанныхФайла());

                    Исключение

                              ИменаСобытийЖР = ИнтеграцияКабинетСотрудника.ИменаСобытийЖР();

                              ИнтеграцияУправлениеПерсоналомОбмен.ЗаписатьОшибкуПолученияДанныхФайла(ИменаСобытийЖР, ВыборкаДетальныеЗаписи.ССылка, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

                              Возврат ;

                    КонецПопытки;

              
                    ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(ДанныеФайла.СсылкаНаДвоичныеДанныеФайла);

                    ИмяФайла = ИнтеграцияУправлениеПерсоналом.ИмяФайлаБезРасширения(ДанныеФайла.ИмяФайла, ДанныеФайла.Расширение);
              

               КонецЦикла;     

Если  ДанныеФайла <> Неопределено тогда  

               ПолноеИмяФайла = КаталогВременныхФайлов + ДанныеФайла.ИмяФайла; 

               полноеИмяТекстовогоФайла = ИмяФайла + ".txt";

               ПолноеИмяФайла =  КаталогВременныхФайлов + "temp.pdf"; 

               ДвоичныеДанныеФайла.Записать(ПолноеИмяФайла);           

               ТекстКоманды = "" + КаталогВременныхФайлов + "pdftotext.exe -enc UTF-8 """ + ПолноеИмяФайла + """ """ + КаталогВременныхФайлов + "temp.txt""";

               WshShell = Новый COMОбъект("WScript.Shell");

               WshShell.Run(ТекстКоманды, 5, 1);

               Текст = Новый ЧтениеТекста(КаталогВременныхФайлов+"temp.txt",КодировкаТекста.UTF8);

               Стр = Текст.ПрочитатьСтроку();

               ПолнаяСтрока = Стр;

               Пока Стр <> Неопределено Цикл

                    Стр = Текст.ПрочитатьСтроку();

                    ПолнаяСтрока = ПолнаяСтрока + Стр; 

               КонецЦикла;  

               Текст.Закрыть();

               УдалитьФайлы(КаталогВременныхФайлов + "temp.txt");

               УдалитьФайлы(КаталогВременныхФайлов + "pdftotext.exe");

               УдалитьФайлы(ПолноеИмяФайла);              

               ОбщегоНазначенияКлиентСервер.ЗаменитьНедопустимыеСимволыXML(ПолнаяСтрока," ");

               ПроанализироватьСтрокуИЗаполнитьРеквизиты(ПолнаяСтрока);

КонецЕсли;      

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

Анализ параметров, которые нам требуется извлечь, позволил их разделить на две части: различные даты и все остальное. Для всего остального я планировал использовать метод шаблона: задаю пару слов, программно ищу их, что оказалось между ними — считаю параметром. Для дат использовалась следующая идея: месяцев у нас 12, даты идут в виде «1 мая 2025 года».  Таким образом я по очереди ищу название месяца, если нахожу, то символы перед — это число даты, символы после — год даты. Поскольку дат может быть несколько, то мы их просто нумеруем: к примеру, первая дата — это дата заявления, вторая дата – дата начала отпуска, третья дата – дата окончания.

Эти настройки мы прикрепляем к шаблону, вот так (ну естественно, шаблон доработан):

Резюме

Подведу итоги. Клиент получил то, что хотел: внедренный кабинет сотрудника с реализованными требованиями. Причем требования внедрены с минимальным вмешательством в существующее решение. «1С:ЗУП» доработан с помощью расширения, личный кабинет сотрудника оставлен вообще без изменений. То есть грядущие преобразования конфигурации и личного кабинета нам не так страшны, как если бы мы поменяли их. Реализованная доработка достаточно несложно расширяется, что позволит заказчику в случае необходимости с небольшими затратами расширить функционал.

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

Comments

So empty here ... leave a comment!

Добавить комментарий

Sidebar