19.03.2022 17:44
Очень много задач, а решать их дюже лениво выбирая из них, требующую меньше напрягов мозга вспомнил, что ФСРАР уже третий раз за год поменял справочник кодов вида алкопродукции (КВАП): https://olegon.ru/showthread.php?t=36485. Как всегда это сделано без предупреждений на сайте: в предположении, что юзеры ЕГАИС его ежедневно анализируют. Вторая "засада", что они не создают документа по изменениям данного очень важного справочника... Конечно он весьма критичен для производства, но и розницу касательно затрагивает, например, когда она не сможет сдавать декларацию, подаваемую в разрезе КВАП или когда "прилетит" штраф за продажу ниже МРЦ

Взялся за эту задачку - анализ изменения справочника кодов КВАП с обычным подходом: открываю 2 Pdf - старый и новый. Глазками смотреть оба документа построчно и выявлять изменения, но на 4 станице бросил это тупое занятие... и решил придумать автоматизацию этого процесса, тем более этот справочник изменяется ежемесячно... Обратил внимание, что код КВАП в текстовом документе формально сохраняется в отдельной строке - вот и зацепка для создания алгоритма, например:
Код:
Спирт-сырец этиловый из пищевого сырья
010
11.01.10.710
ЭС
2207 10 000 0
Спирт этиловый ректификованный из пищевого сырья
020
11.01.10.720
ЭС
2207 10 000 0
Спирты этиловые из пищевого сырья прочие
0201
Ну, а дальше дело техники, благо, что работать сегодня было лень, а это какое ни было развлечение. Желающие могут изучить алгоритмы по исходнику:

Исходный код программы:
Код:
 ==================================================================================================
*   Проверка изменения списка кодов КВАП алкогольной продукции.
*   Разработка:   Жуков Андрей Николаевич                                          Автор: Жуков А.Н.
*   
*   Pdf файл списка КВАП сохраняем в текстовом файле каталога программы с любым именем. Программа
*   определяет список файлов *.txt своего каталога, выбирая из них самые свежие по шаблонам:
*   Last*.txt       - результат последней предыдущей проверки. Получаю массив aLast:={КВАП}
*   НЕ Last*.txt    - полагая его свежим списком КВАП. Перекачка в массив памяти aNew строки по
*       шаблону: длина строки 3-5 знаков и все знаки цифровые... полагая это кодами КВАП
*   Сличаю старый и новый массив, делаю лог расхождения *.log, сохраняю новый массив в Last*.txt
* ==================================================================================================
#include "..\LACK\LS\PRG\laks.ch"

* --------------------------------------------------------------------------------------------------
*   Головной модуль программы
PROC Main()
    LOCA cStr:="", cC:="", aTxt:=Directory("*.txt"), nI:=0, nL:=0, nS:=0, nLast:=0, nNew:=0, nN:=0
    LOCA cfLast:="", cfNew:="", aLast:={}, aNew:={}, dLast:=Ctod(""), dNew:=Ctod(""), dT:=Date()
    LOCA lBad:=TRUE, nJ:=0, cLog:=""

    //  Глобальные системные установки пакета.
    SET DATE GERMAN
    SET DELE ON
    SET ESCA ON
    SET SCOR OFF
    SET WRAP ON
    SET CENT OFF
    SET CURS OFF

    //  Стандартная цветовая гамма программы
    PRIV cMainc_c   := "GR+/B,N+/W,,,N/W",  cMainc_m    := "W/N,N/W,,,N/W+"
    PRIV cColor_c   := "N/W,GR+/B,,,N/G",   cColor_m    := "W/N,N/W,,,N/W+"
    PRIV cError_c   := "W+/R,W/N,,,W/B",    cError_m    := "W+/N,N/W,,,W/N"
    PRIV cHelpc_c   := "N/G,R/G,,,N/G+",    cHelpc_m    := "N/W,W/N,,,N/W+"
    PRIV cOther_c   := "N+/G,W/N,,,B/G",    cOther_m    := "N/W,W/N,,,N/W"
    PRIV cMainc     := IF(ISCOLOR(),cMainc_c,cMainc_m)
    PRIV cColor     := IF(ISCOLOR(),cColor_c,cColor_m)
    PRIV cError     := IF(ISCOLOR(),cError_c,cError_m)
    PRIV cHelpc     := IF(ISCOLOR(),cHelpc_c,cHelpc_m)
    PRIV cOther     := IF(ISCOLOR(),cOther_c,cOther_m)
    PRIV l_mus      := TRUE

    IF (nL:=Len(aTxt)) <= 0 THEN fErrQuit("В каталоге программы нет файлов *.txt для сравнения!",cError)
    pWind("Сличение новых кодов КВАП с раннее сохраненными. Версия 19.03.2022","test.ico")
    CLS

    //  Определяю имена самых свежих файлов сохраненного списка КВАП и файла от ФСРАР
    FOR nI := 1 TO nL
        IF At("LAST",Upper(aTxt[nI,1])) == 1        //  Сохранение списков КВАП. Может отсутствовать
            dT  := CToD(Subs(aTxt[nI,1],5,8))       //  Дата сохраненного файла, прописанная в имени
            IF dT >= dLast
                dLast   := dT
                nLast   := nI
            ENDI
        ELSE                                        //  Прочие файлы. Полагаю преобразования PDF от РАР в TXT 
            dT  := aTxt[nI,3]                       //  Системная дата сохраненного файла
            IF dT >= dNew
                dNew    := dT
                nNew    := nI
            ENDI
        ENDI
    NEXT
    IF nNew <= 0 THEN fErrQuit("В каталоге нет преобразованного в *.txt файла от ФСРАР!",cError)
    
    //  Перегоняю подходящие строки из файла от ФСРАР в массив памяти
    cStr    := MemoRead(aTxt[nNew,1])
    nN      := NumToken(cStr,CRLF)
    FOR nI := 1 TO nN
        X_DEMO
        cC  := Alltrim(Token(cStr,CRLF,nI))         //  Строка из текстового файла от ФСРАР
        
        //  Проверяю её на шаблон: длина строки 3-5 знаков и все знаки цифровые
        IF !(Len(cC)>=3 .AND. Len(cC)<=5) THEN LOOP
        
        lBad    := FALSE
        FOR nJ := 1 TO Len(cC)
            IF !IsDigit( Subs(cC,nJ,1) ) THEN lBad := TRUE
        NEXT nJ
        
        //  Подходящую строку с типа кодом КВАП добавляю в массив памяти
        IF !lBad THEN aadd(aNew,cC)
    NEXT nI
    
    //  При наличии предыдущего списка кодов перегоняю его в массив памяти и произвожу сличение списков
    IF nLast > 0    
        cStr    := MemoRead(aTxt[nLast,1])
        nN      := NumToken(cStr,CRLF)
        FOR nI := 1 TO nN
            X_DEMO
            cC  := Alltrim(Token(cStr,CRLF,nI))     //  Строка из текстового файла сохраненных кодов. Проверок не произвожу
            aadd(aLast,cC)
        NEXT nI
        
        lBad    := FALSE                            //  Признак наличия расхождения кодов
        cC      := Hb_OemToAnsi("Новый Старый")+CRLF
        FOR nI := 1 TO Len(aNew)                    //  Появился новый код КВАП
            X_DEMO
            nJ  := ascan(aLast,{|x|x==aNew[nI]})
            IF nJ <= 0
                cC      += aNew[nI]+Spac(6)+CRLF
                lBad    := TRUE
            ENDI
        NEXT nI
        FOR nI := 1 TO Len(aLast)                   //  Нереально - удалили код КВАП в новой таблице
            X_DEMO
            nJ  := ascan(aNew,{|x|x==aLast[nI]})
            IF nJ <= 0
                cC      += Spac(6)+aLast[nI]+CRLF
                lBad    := TRUE
            ENDI
        NEXT nI
        
        //  При наличии расхождений вывожу в текущий каталог файл логов. Сообщение зависит от результата
        IF lBad
            cLog    := "Rash_"+Dtos(Date())+"_"+StrTran(Time(),":")+".log"
            ErrMess("Расхождения! Смотрите в файле "+cLog,cError)
            MemoWrit( cLog, cC )
        ELSE
            ErrMess("Расхождений в списке кодов КВАП не обнаружено!",cColor)
        ENDI
    ENDI
    
    //  Сохраняю свежий список КВАП от РАР в файле последних кодов
    cC      := ""
    FOR nI := 1 TO Len(aNew) DO cC += aNew[nI]+CRLF
    MemoWrit( "Last"+Dtos(Date())+".txt", cC )

    fErrQuit("Спасибо за работу со мной!",cMainc)
    RETU


Суть анализатора:

В папке программы лежат два типа *.txt файлов любой кодировки:

1. С именами Last*.txt - файлы сохраненного справочника КВАП предыдущих проверок;
2. Иные файлы *.txt полагаю сохраненным в текстовом формате высеры ФСРАР с данным справочником.

Программа выбирает из самых свежих файлов данного типа старый и новый список КВАП, а затем сличает их в два прохода.


Руководство пользователя:

Распакуйте архив с программой в любое место на диске, флэшки, карте памяти... В дальнейшем не удаляйте папку, т.к. в ней будет накапливаться статистика для дальнейших анализов. Изначально в ней лежат справочники ФСРАР от января и марта, а так же результаты анализов.

При обновлении справочника на сайте: . Сохраните Pdf файл и сохраните его в формате *.txt с любым именем, в каталог программы, например через Adobe Reader:





Затем просто запустите программу - файл kvap.exe из папки с программой. Программа проведёт сличение старого и нового справочника КВАП, выдаст сообщение, например при обнаружении расхождений:





… и создаст в своём каталоге 1/2 тестовых файла windows кодировки:

LastТекущаяДата.txt - список свежих кодов КВАП и если было обнаружено расхождение, то
RashТекущаяДата_Время.log - реестр расхождение... Появились новые коды, удалены старые коды
Вложения
Тип файла: 7z ChecKVAP.7z (444.6 Кб, 38 просмотров)