:: Visual Foxpro, Foxpro for DOS
Re: Импорт больничных листов их XML - файла.
FoxShip

Сообщений: 458
Дата регистрации: 27.06.2007
Тут только частный самый простой случай. Без продления больничного, нарушений, стационаров, санаторий и т.д.
Но принцип понятен должен быть.
lcFName = GETFILE('XML','Выберите файл ЛН !','Выбрать')
IF EMPTY(lcFName)
RETURN
ENDIF
oXml=CREATEOBJECT('MSXML2.DOMDocument')
oXml.ASYNC=.F.
oXml.ValidateOnParse = .F.
oXml.LOAD(lcFName)
IF oXml.DocumentElement.Nodename != 'S:Envelope'
MESSAGEBOX('Неверный XML - файл',16)
RETURN
ENDIF
oDocument = oXml.Childnodes(1)
FOR N = 0 TO oDocument.Childnodes.Length - 1
IF ATC(oDocument.Childnodes(N).Nodename,'SOAP-ENV:Header,S:Body') = 0
MESSAGEBOX('Неверный XML - файл',16)
RETURN
ENDIF
ENDFOR
SELECT VRACHB
ZAP
SELECT BOLNMU
ZAP
APPEND BLAN
REPL GOD WITH nYear,MES WITH nMes
oFileOperations = oDocument.Childnodes(1).Childnodes(0).Childnodes(0)
FOR N = 0 TO oFileOperations.Childnodes.Length - 1
IF oFileOperations.Childnodes(N).Nodename = 'ns1:STATUS'
cStatus = oFileOperations.Childnodes(N).Text
ELSE
cStatus = ''
ENDIF
IF oFileOperations.Childnodes(N).Nodename = 'ns1ATA'
oRow = oFileOperations.Childnodes(N).Childnodes(0).Childnodes(0)
FOR K = 0 TO oRow.Childnodes.Length - 1
DO CASE
CASE oRow.Childnodes(K).Nodename = 'ns1:SNILS'
* Вытаскиваем СНИЛДС
cSnils = SUBS(oRow.Childnodes(K).Text,1,3)+'-'+SUBS(oRow.Childnodes(K).Text,4,3)+'-'+SUBS(oRow.Childnodes(K).Text,7,3)+' '+SUBS(oRow.Childnodes(K).Text,10,2)
* Тут команды для заполнения вашего курсора(ов)
* Не все данные я беру из XLM - файла, все что можно вытаскиваю из своей БД.
CASE oRow.Childnodes(K).Nodename = 'ns1:LN_CODE'
* вытаскиваю номер ЛН
cListn = oRow.Childnodes(K).Text
SELECT BOLN
SET ORDER TO LISTN
=SEEK(cListn)
IF !EOF()
MESSAGEBOX(cListn +' - лист нетрудоспособности уже введен !',16)
RETURN
ELSE
SELECT BOLNMU
REPL LISTN WITH cListn
ENDIF
CASE oRow.Childnodes(K).Nodename = 'ns1:PRIMARY_FLAG'
* первичный или нет ЛН
cPrim = oRow.Childnodes(K).Text
IF cPrim = '0'
SELECT BOLNMU
REPL PROD WITH .T.
ENDIF
CASE oRow.Childnodes(K).Nodename = 'ns1:LN_DATE'
* дата ЛН
cData = oRow.Childnodes(K).Text
SELECT BOLNMU
REPL DATAL WITH CTOD(SUBS(cData,9,2)+'.'+SUBS(cData,6,2)+'.'+SUBS(cData,1,4))
CASE oRow.Childnodes(K).Nodename = 'ns1:LPU_NAME'
* наименование леч. учр-я.
cLu_name = oRow.Childnodes(K).Text
CASE oRow.Childnodes(K).Nodename = 'ns1:LPU_ADDRESS'
* адрес леч. учр-я.
cLu_address = oRow.Childnodes(K).Text
CASE oRow.Childnodes(K).Nodename = 'ns1:LPU_OGRN'
* ОГРН леч. учр-я.
cLu_ogrn = oRow.Childnodes(K).Text
CASE oRow.Childnodes(K).Nodename = 'ns1:REASON1'
* причина заб-я
cReason = oRow.Childnodes(K).Text
SELECT BOLNSP
=SEEK(VAL(cReason))
SELECT BOLNMU
REPL IDB WITH BOLNSP.IDB,NKART WITH BOLNSP.NKART
DO CASE
CASE IDB = 5
REPL IDP WITH 3
CASE IDB = 4 OR IDB = 7
REPL IDP WITH 7
OTHER
REPL IDP WITH 2
ENDCASE
CASE oRow.Childnodes(K).Nodename = 'ns1:LN_RESULT'
* дата выхода на работу
cData = oRow.Childnodes(K).Childnodes(0).Text
SELECT BOLNMU
REPL DATAR WITH CTOD(SUBS(cData,9,2)+'.'+SUBS(cData,6,2)+'.'+SUBS(cData,1,4))
CASE oRow.Childnodes(K).Nodename = 'ns1:TREAT_PERIODS'
* периоды продления и врачи
FOR J = 0 TO oRow.Childnodes(K).Childnodes.Length - 1
oTread = oRow.Childnodes(K).Childnodes(J)
FOR G = 0 TO oTread.Childnodes.Length - 1
oPeriod = oTread.Childnodes(G)
SELECT VRACHB
APPEND BLAN
REPL TABN WITH BOLNMU.TABN,PODR WITH BOLNMU.PODR
FOR I = 0 TO oPeriod.Childnodes.Length - 1
DO CASE
CASE oPeriod.Childnodes(I).Nodename = 'ns1:TREAT_DT1'
cDatan = oPeriod.Childnodes(I).Text
REPL DATAN WITH CTOD(SUBS(cData,9,2)+'.'+SUBS(cData,6,2)+'.'+SUBS(cData,1,4))
CASE oPeriod.Childnodes(I).Nodename = 'ns1:TREAT_DT2'
cDatan = oPeriod.Childnodes(I).Text
REPL DATAK WITH CTOD(SUBS(cData,9,2)+'.'+SUBS(cData,6,2)+'.'+SUBS(cData,1,4))
CASE oPeriod.Childnodes(I).Nodename = 'ns1:TREAT_DOCTOR_ROLE'
cRule = oPeriod.Childnodes(I).Text
CASE oPeriod.Childnodes(I).Nodename = 'ns1:TREAT_DOCTOR'
cFio = ALLT(oPeriod.Childnodes(I).Text)
ENDCASE
ENDFOR
ENDFOR
ENDFOR
ENDCASE
ENDFOR
ENDIF
ENDFOR
Ratings: 0 negative/0 positive
Re: Импорт больничных листов их XML - файла.
FoxShip

Сообщений: 458
Дата регистрации: 27.06.2007
FoxShip
Тут только частный самый простой случай. Без продления больничного, нарушений, стационаров, санаторий и т.д.
И конечно урезанный код. Т.е. не полностью показано (чтобы не загромождать пост) заполнение моих курсоров.
Но принцип понятен должен быть.
lcFName = GETFILE('XML','Выберите файл ЛН !','Выбрать')
IF EMPTY(lcFName)
RETURN
ENDIF
oXml=CREATEOBJECT('MSXML2.DOMDocument')
oXml.ASYNC=.F.
oXml.ValidateOnParse = .F.
oXml.LOAD(lcFName)
IF oXml.DocumentElement.Nodename != 'S:Envelope'
MESSAGEBOX('Неверный XML - файл',16)
RETURN
ENDIF
oDocument = oXml.Childnodes(1)
FOR N = 0 TO oDocument.Childnodes.Length - 1
IF ATC(oDocument.Childnodes(N).Nodename,'SOAP-ENV:Header,S:Body') = 0
MESSAGEBOX('Неверный XML - файл',16)
RETURN
ENDIF
ENDFOR
SELECT VRACHB
ZAP
SELECT BOLNMU
ZAP
APPEND BLAN
REPL GOD WITH nYear,MES WITH nMes
oFileOperations = oDocument.Childnodes(1).Childnodes(0).Childnodes(0)
FOR N = 0 TO oFileOperations.Childnodes.Length - 1
IF oFileOperations.Childnodes(N).Nodename = 'ns1:STATUS'
cStatus = oFileOperations.Childnodes(N).Text
ELSE
cStatus = ''
ENDIF
IF oFileOperations.Childnodes(N).Nodename = 'ns1ATA'
oRow = oFileOperations.Childnodes(N).Childnodes(0).Childnodes(0)
FOR K = 0 TO oRow.Childnodes.Length - 1
DO CASE
CASE oRow.Childnodes(K).Nodename = 'ns1:SNILS'
* Вытаскиваем СНИЛС
cSnils = SUBS(oRow.Childnodes(K).Text,1,3)+'-'+SUBS(oRow.Childnodes(K).Text,4,3)+'-'+SUBS(oRow.Childnodes(K).Text,7,3)+' '+SUBS(oRow.Childnodes(K).Text,10,2)
* Тут команды для заполнения моего курсора(ов)
* Не все данные я беру из XLM - файла, все что можно вытаскиваю из своей БД.
CASE oRow.Childnodes(K).Nodename = 'ns1:LN_CODE'
* вытаскиваю номер ЛН
cListn = oRow.Childnodes(K).Text
SELECT BOLN
SET ORDER TO LISTN
=SEEK(cListn)
IF !EOF()
MESSAGEBOX(cListn +' - лист нетрудоспособности уже введен !',16)
RETURN
ELSE
SELECT BOLNMU
REPL LISTN WITH cListn
ENDIF
CASE oRow.Childnodes(K).Nodename = 'ns1:PRIMARY_FLAG'
* первичный или нет ЛН
cPrim = oRow.Childnodes(K).Text
IF cPrim = '0'
SELECT BOLNMU
REPL PROD WITH .T.
ENDIF
CASE oRow.Childnodes(K).Nodename = 'ns1:LN_DATE'
* дата ЛН
cData = oRow.Childnodes(K).Text
SELECT BOLNMU
REPL DATAL WITH CTOD(SUBS(cData,9,2)+'.'+SUBS(cData,6,2)+'.'+SUBS(cData,1,4))
CASE oRow.Childnodes(K).Nodename = 'ns1:LPU_NAME'
* наименование леч. учр-я.
cLu_name = oRow.Childnodes(K).Text
CASE oRow.Childnodes(K).Nodename = 'ns1:LPU_ADDRESS'
* адрес леч. учр-я.
cLu_address = oRow.Childnodes(K).Text
CASE oRow.Childnodes(K).Nodename = 'ns1:LPU_OGRN'
* ОГРН леч. учр-я.
cLu_ogrn = oRow.Childnodes(K).Text
CASE oRow.Childnodes(K).Nodename = 'ns1:REASON1'
* причина заб-я
cReason = oRow.Childnodes(K).Text
SELECT BOLNSP
=SEEK(VAL(cReason))
SELECT BOLNMU
REPL IDB WITH BOLNSP.IDB,NKART WITH BOLNSP.NKART
DO CASE
CASE IDB = 5
REPL IDP WITH 3
CASE IDB = 4 OR IDB = 7
REPL IDP WITH 7
OTHER
REPL IDP WITH 2
ENDCASE
CASE oRow.Childnodes(K).Nodename = 'ns1:LN_RESULT'
* дата выхода на работу
cData = oRow.Childnodes(K).Childnodes(0).Text
SELECT BOLNMU
REPL DATAR WITH CTOD(SUBS(cData,9,2)+'.'+SUBS(cData,6,2)+'.'+SUBS(cData,1,4))
CASE oRow.Childnodes(K).Nodename = 'ns1:TREAT_PERIODS'
* периоды продления и врачи
FOR J = 0 TO oRow.Childnodes(K).Childnodes.Length - 1
oTread = oRow.Childnodes(K).Childnodes(J)
FOR G = 0 TO oTread.Childnodes.Length - 1
oPeriod = oTread.Childnodes(G)
SELECT VRACHB
APPEND BLAN
REPL TABN WITH BOLNMU.TABN,PODR WITH BOLNMU.PODR
FOR I = 0 TO oPeriod.Childnodes.Length - 1
DO CASE
CASE oPeriod.Childnodes(I).Nodename = 'ns1:TREAT_DT1'
cDatan = oPeriod.Childnodes(I).Text
REPL DATAN WITH CTOD(SUBS(cData,9,2)+'.'+SUBS(cData,6,2)+'.'+SUBS(cData,1,4))
CASE oPeriod.Childnodes(I).Nodename = 'ns1:TREAT_DT2'
cDatan = oPeriod.Childnodes(I).Text
REPL DATAK WITH CTOD(SUBS(cData,9,2)+'.'+SUBS(cData,6,2)+'.'+SUBS(cData,1,4))
CASE oPeriod.Childnodes(I).Nodename = 'ns1:TREAT_DOCTOR_ROLE'
cRule = oPeriod.Childnodes(I).Text
CASE oPeriod.Childnodes(I).Nodename = 'ns1:TREAT_DOCTOR'
cFio = ALLT(oPeriod.Childnodes(I).Text)
ENDCASE
ENDFOR
ENDFOR
ENDFOR
ENDCASE
ENDFOR
ENDIF
ENDFOR



Исправлено 2 раз(а). Последнее : FoxShip, 18.04.18 09:46
Ratings: 0 negative/0 positive
Re: Импорт больничных листов их XML - файла.
Igor Korolyov
Автор

Сообщений: 34580
Дата регистрации: 28.05.2002
Худший вариант из возможных... Впрочем, этого и стоило ожидать.

Читать про методы SelectNodes(), SelectSingleNode() и к ним язык XPath (хотя бы самую основу, для понимания принципа адресации в дереве XML-я).
И все эти убогие километровые .Childnodes(N).Childnodes(0).Childnodes(0) заменятся на вполне понятный код наподобии (т.к. самого XML-я мы так и не увидели, то лишь умозрительные имена элементов и можно тут прописать) вот такого:
FOREACH oRow IN oXml.SelectNodes('//ns1:data/ns1:row')
lcCode = oRow.SelectSingleNode('ns1:LN_CODE').Text
...
ENDFOR


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Импорт больничных листов их XML - файла.
FoxShip

Сообщений: 458
Дата регистрации: 27.06.2007
Igor Korolyov
Худший вариант из возможных... Впрочем, этого и стоило ожидать.
Читать про методы SelectNodes(), SelectSingleNode() и к ним язык XPath (хотя бы самую основу, для понимания принципа адресации в дереве XML-я).
И все эти убогие километровые .Childnodes(N).Childnodes(0).Childnodes(0) заменятся на вполне понятный код наподобии (т.к. самого XML-я мы так и не увидели, то лишь умозрительные имена элементов и можно тут прописать) вот такого:
FOR EACH oRow IN oXml.SelectNodes('//ns1:data/ns1:row')
lcCode = oRow.SelectSingleNode('ns1:LN_CODE').Text
...
ENDFOR
Да, конечно. Первый блин комом.
Вам спасибо за подсказку. Изначально знал, что можно реализовать лучше.
Только не уверен, что
FOR EACH oRow IN oXml.SelectNodes('//ns1:data/ns1:row')
сработает в VFP6.
Буду пробовать.
Ratings: 0 negative/0 positive
Re: Импорт больничных листов их XML - файла.
Igor Korolyov
Автор

Сообщений: 34580
Дата регистрации: 28.05.2002
В VFP5 появился FOR EACH. Впрочем, он без особого труда заменяется на
oNodes = oXml.SelectNodes(...)
FOR ln1 = 0 TO m.oNodes.length-1
oRow = m.oNodes(m.ln1) && WITH m.oNodes(m.ln1) с обращением вида .SelectSingleNode('ns1:LN_CODE').Text внутри блока WITH
...

Можно даже WITH применить в таком случае для того что в oRow будет, и избавится от этой явной переменной. Это уже мелочи - не мелочь это уход от "позиционного" разбора на разбор по именам элементов. Ну и правильная работа с неймспейсами (т.к. вовсе не ns1 является неймспейсом - на месте префикса может быть что угодно, или даже вообще ничего - а "суть" документа останется прежней).

Если взять очень грубую аналогию, то это всё вместе будет как разница между работой с записями по значениям ключевого поля (что есть правильно) и "по номерам записей", а то ещё и "по порядковым номерам полей" - что есть совершенно неправильно в 99% случаев, особенно для "не своих" данных.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Импорт больничных листов их XML - файла.
FoxShip

Сообщений: 458
Дата регистрации: 27.06.2007
Igor Korolyov
Худший вариант из возможных... Впрочем, этого и стоило ожидать.
Читать про методы SelectNodes(), SelectSingleNode() и к ним язык XPath (хотя бы самую основу, для понимания принципа адресации в дереве XML-я).
И все эти убогие километровые .Childnodes(N).Childnodes(0).Childnodes(0) заменятся на вполне понятный код наподобии (т.к. самого XML-я мы так и не увидели, то лишь умозрительные имена элементов и можно тут прописать) вот такого:
FOR EACH oRow IN oXml.SelectNodes('//ns1:data/ns1:row')
...
ENDFOR
Данная конструкция в версиях выше VFP5 вызывает ошибку
Expression evaluator failed
А версии VFP5
Function argument value, type, or count is invalid.



Исправлено 1 раз(а). Последнее : FoxShip, 26.04.18 13:18
Ratings: 0 negative/0 positive
Re: Импорт больничных листов их XML - файла.
FoxShip

Сообщений: 458
Дата регистрации: 27.06.2007
А вот так работает
oNodes = oXml.SelectNodes('S:Envelope')
FOR EACH oRow IN m.oNodes
....
ENDFOR
Ratings: 0 negative/0 positive
Re: Импорт больничных листов их XML - файла.
Igor Korolyov
Автор

Сообщений: 34580
Дата регистрации: 28.05.2002
Да, видимо в фоксе какой-то косячок есть при работе с этой хитрой коллекцией, без промежуточной переменной не хочет...


------------------
WBR, Igor
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 18 (Гостей: 18)

© 2000-2024 Fox Club 
Яндекс.Метрика