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

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

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 _ Программирование в 1С Предприятие 8.3 _ Обработка XML большого объема

Автор: Vond 19.07.20, 12:46

Мир Вам smile.gif

Коллеги. а никто не пересекался с такой задачей как обработка данных реестра https://pro1c.org.ua/redirect.php?https://data.gov.ua/dataset/1c7f3815-3259-45e0-bdf1-64dca07ddc10 ?
Идея в чем: причесать справочник контрагентов типовой либо не типовой базы согласно данных из открытых данных. Но в лоб как то не особо хорошо вышло. Слишком большой файл для 1С.
Проекты "Пактум Контрагент" и от "Портфель" конечно прекрасны для такой оперативной задачи, но слишком накладно если все за раз и сразу.
Вот ищу хотя бы идей или методу.

Автор: pablo 20.07.20, 15:26

Напишите свою процедуру чтения и разбора файла.

Автор: Vond 20.07.20, 22:28

pablo @ Сегодня, 14:26 * ,
пробовали. на небольших файлах - работает, а вот оригинал в 1Гб - не справляется 1С, тем более что самый большой файл - более 5Гб

Автор: awp 20.07.20, 22:43

В данный момент пишу парсер на Delphi именно для этих 2 файлов smile.gif

Автор: andr_andrey 21.07.20, 9:11

Vond @ Вчера, 23:28 * ,
Парсинг таких больших данных делается специальными библиотеками и неинтерпретируемыми языками, иначе приготовьтесь страдать.
К каждой задаче нужно подходить индивидуально, иначе 1С головного мозга придёт.

Автор: Batchir 21.07.20, 14:46

Пересекался, делал для 8.3.
Основная проблема в том что файлики с https://pro1c.org.ua/redirect.php?https://data.gov.ua/ уж очень большие и нужно время что бы их полностью обработать.
А так писал в служебную базу, а потом через http сервисы обращался к ней за информацией (перенаправлял запросы пактрума на свою базу)

Автор: Vond 28.07.20, 16:31

awp @ 20.07.20, 21:43 * ,
smile.gif и куда будет складывать делфи их? Кстати как с нюансом и новизной которая анонсируется в ближайшее время по госреестру? Делфи гибкая будет и все поймет? smile.gif

Batchir @ 21.07.20, 13:46 * ,
а можно детальнее? 1С все же сама их обработала и сложила все в новую базу куда то? просто я не дождался в свое время, а сейчас по новой к задаче подхожу smile.gif хочется учесть чужой опыт чтоб избежать "граблей"
ну или купить наверное smile.gif

Автор: Vofka 28.07.20, 16:48

Vond, а какой именно файл пытаетесь обработать?

Автор: Vond 30.07.20, 7:43

Vofka,
доброе утро. вот сей файл: https://pro1c.org.ua/redirect.php?https://data.gov.ua/dataset/1c7f3815-3259-45e0-bdf1-64dca07ddc10/resource/06bbccbd-e19c-40d5-9e18-447b110c0b4c

Автор: Batchir 30.07.20, 10:20

Vond,
Фишка в том что есть огромный файл.
Его нужно читать последовательно, а не целиком.
Алгоритм следующий:
1. Читаешь последовательно строки XML с помощью

ЧтениеXML = Новый ЧтениеXML; 
ЧтениеXML.ОткрытьФайл(ИмяФайла);
ЧтениеXML.Прочитать();
// начинаем читать дальше строки файла
        
Пока ЧтениеXML.Прочитать() Цикл  //Цикл по структуре
// .........
КонецЦикла;

В этом случае оперативная память не загружается и в ней находятся только прочитанные на момент чтения строки.
Минус в том что мы не можем контролировать что загружено из файла что нет и если что-то пойдет не так то нам нужно начинать сначала.
2. Поэтому перед тем как выполнять записи в базу я этот большой XML дробил программно на кучу (по 100000 записей, это на усмотрение)
В результате у меня было N количество небольших файлов ожидающих загрузки данных.
3. После того как новые файлы сформированы запускаем уже разбор этих отдельных файлов.
Читаю каждый файл и гружу по нему данные. Если успешно загрузился, то грохаю его, если прошла какая-то ошибка, то пропускаю (перемещаю в отдельный каталог. что бы потом выяснить на чем прошел затык)
И так выполняется пока все они не будут обработаны.

Автор: Vond 30.07.20, 20:39

Спасибо, предположения совпали с опытом других - тоже результат. Сам файл тоже интересно записан, все в 1 строку. пока накусаешь нужных правильных файлов тоже еще тот квест smile.gif ну хоть так

Автор: Batchir 03.08.20, 11:14

Упрощенно код который разбивает файл на куски выглядит так:

                ИмяБезРасширения     = ""; // Чистое имя используется для генерации новых файлов
        ИмяФайла             = ""; // ИмяФайла - закачанный и разархивированный файл XML
        ПутьКНовымФайлам    = ""; // путь куда будут сохраняться новые файлы
        
        Если ЭтоLinuxСервер() ТОгда // отдельная функция которая распознает где крутится сервер 1С
            Слеш = "/";
        Иначе
            Слеш = "\";
        КонецЕсли;
        
        // читаем файл,
        ЧтениеXML = Новый ЧтениеXML;
        ЧтениеXML.ОткрытьФайл(ИмяФайла);
        //Разделяем указанный файл на несколько частей заданного размера, по 100000 записей.
        НомерФайла = 0;
        КоличествоСтрокФайла = 0;
        КоличествоЗаписейДляПрерыванияАлгоритма = 100000;
        
        ЗаписьXML = Неопределено;
        Пока ЧтениеXML.Прочитать() Цикл  //Цикл по структуре
            ИмяЧтения             = ЧтениеXML.Имя;
            ТипУзлаЧтения         = ЧтениеXML.ТипУзла;
            Если ИмяЧтения = "DATA" Тогда
                // этот тег нам не нужен, пропускаем и переходим к записям
                Продолжить;
            КонецЕсли;
            Если ИмяЧтения = "RECORD" И ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
                // увеличиваем счетчик обработанной записи для того что бы как только достигнет нужного числа мы запишем файл и начнем новый
                КоличествоСтрокФайла = КоличествоСтрокФайла + 1;
            КонецЕсли;
            
            // инициируем запись нового файла
            Если КоличествоСтрокФайла = 1 И ЗаписьXML = Неопределено Тогда
                НомерФайла = НомерФайла + 1;
                ЗаписьXML = Новый ЗаписьXML;
                ИмяНовогоФайла = ПутьКНовымФайлам + Слеш + ИмяБезРасширения + "_"+ НомерФайла + ".xml";
                ЗаписьXML.ОткрытьФайл(ИмяНовогоФайла, "UTF-8");
                ЗаписьXML.ЗаписатьОбъявлениеXML(); //
                ЗаписьXML.ЗаписатьНачалоЭлемента("DATA"); // начинаем общий тег для хранения списка записей
            КонецЕсли;
            
            // в упращенном файле используются только начало, конец элемента и текст
            Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
                ЗаписьXML.ЗаписатьНачалоЭлемента(ИмяЧтения);
            ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
                ЗаписьXML.ЗаписатьКонецЭлемента();
            ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
                ЗаписьXML.ЗаписатьТекст(ЧтениеXML.Значение);
            КонецЕсли;
            
            // определяем что в новом файле уже нужное нам количество записей
            Если КоличествоСтрокФайла = КоличествоЗаписейДляПрерыванияАлгоритма И ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента И ИмяЧтения = "RECORD" Тогда
                ЗаписьXML.ЗаписатьКонецЭлемента(); // DATA
                ЗаписьXML.Закрыть();
                // обнуляем значения для того чтоб попало в проверку генерации нового файла
                КоличествоСтрокФайла = 0;
                ЗаписьXML = Неопределено;
            КонецЕсли;
        КонецЦикла;
        
        Если ЗаписьXML <> Неопределено Тогда
            // последний файл с вероятностью 99.99% не записан
            ЗаписьXML.ЗаписатьКонецЭлемента(); // DATA
            ЗаписьXML.Закрыть();
            КоличествоСтрокФайла = 0;
            ЗаписьXML = Неопределено;
        КонецЕсли;


Вырезал куски, у меня просто там куча всего ещё написано для отладки и настройки алгоритмов загрузки.
Но для понимания должно хватить)

Автор: Petre 03.08.20, 12:00

Свои 5 копеек вставлю (во чем-то повторюсь).
1. Про DOM забудьте - только XML.
2. В данных много косяков: ошибки, проблемные символы, фейковые (тестовые) данные...
3. В данных отсутствует идентификатор уникальности записей. Соответственно, возникнет множество коллизий.

Автор: awp 06.08.20, 21:02

Petre @ 03.08.20, 13:00 * ,
Данные внутри полное г. Как такое вообще можно давать на уровне государства? У ФОПов нет ИНН, да и Юриков тоже. Может я не правильно смотрел? Подскажите кто где берет.Спасибо.

ПС: Файл разбил на куски по 80мб кодом на С# - 40сек.

Автор: Petre 07.08.20, 8:22

awp @ Yesterday, 21:02 * ,
Предполагаю, они просто выгрузили из своих dbf-ов "как есть".
ИНН - это уже другая база - https://pro1c.org.ua/redirect.php?https://data.gov.ua/dataset/4c65d66d-1923-4682-980a-9c11ce7ffdfe.

Автор: awp 07.08.20, 9:50

Petre @ Сегодня, 9:22 * ,
У них оракул давно вроде.

Автор: awp 07.08.20, 10:59

Petre @ Сегодня, 9:22 * ,
А как ее связать с реестром? и нет фопов. 64000000.gif по наименованию smile.gif ? Интересно как такие сервисы как пактум и юконтрол это связывают?

Такое ощущение что они просто выполнили требование дать доступ людям, а вот уже что внутри всем пох......... Вангую, что пактумы и юконтролы берут в ином месте smile.gif

Автор: Petre 07.08.20, 11:25

awp @ Today, 10:59 * ,
Значимая часть ЄДРПОУ является началом вхождения в ИНН.

QUOTE (awp @ 07.08.20, 10:59) *
Вангую, что пактумы и юконтролы берут в ином месте

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

Автор: awp 07.08.20, 12:37

Цитата(Petre @ 07.08.20, 12:25) *
Значимая часть ЄДРПОУ является началом вхождения в ИНН.


А по фопам ведь нет ИНН в реестре. Где его брать?



Автор: andr_andrey 07.08.20, 13:55

Цитата(Petre @ 07.08.20, 12:25) *
Думаю, они просто приложили усилия для разбора этой кучи говна

Они заплатили за API сервис (https://nais.gov.ua/pages/api) и сформировали свои базы.
Цитата(awp @ 07.08.20, 13:37) *
А по фопам ведь нет ИНН в реестре. Где его брать?

Мы взяли в юконтрол smile.gif

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