Показать полную графическую версию : [решено] разбить текстовый файл на несколько по условию
Перед отправкой отчета программа ФОМС проверяет отчет на наличие ошибок и формирует текстовый файл. (прикладываю образец файла с первыми двумя пациентами и ошибками по ним) »
Надо понимать так, что поведение программы, выдающей текстовый файл проверки отчета, изменить невозможно? Например, чтобы в итоговый файл, помимо самих ошибок, ещё выводился бы и код ошибки, по которому можно было бы их однозначно идентифицировать?
Необходимо разделить этот файл на несколько файлов которые будут группироваться по ошибкам чтобы раздать мед персоналу для исправления ошибок. »
Это надо понимать так:
В каждый отдельный файл, должны быть выведены только конкретные по типу ошибки, т.е. в каждом файле свои ошибки, привязанные к конкретному пациенту? Ну, нет смысла выводить в каждый файл весь список ошибок, если уж их требуется разделить. Иначе, проще разбить файл на определенное число пациентов, затем вывести их в файлы с полным содержимым ошибок по каждому пациенту...
как вариант можно создать файл с образцами основных ошибок и группировать по ним а если встретятся ошибки не существующие в файле образца ошибок то их собрать в отдельный файл. »
Да-да, правильно выше сказали, что только так, если нет возможности вывода вместе с ошибками и кодов этих ошибок...
megaloman
23-01-2019, 11:03
Как подсознательно чувствовал, кодировка файла 1251. Долой CMD.
ИМХО, в программе ФОМХ (совершенно с ней не знаком) заполняются некие поля.Строка с ошибкой может быть как одинаковой целиком, например "У новорожденного не указан вес (не заполнено поле Weight)"
так и совпадающей только частью строки, например "Значения полей KPG и KSG не соответствуют справочнику KSG.DBF в отчетном периоде : KPG= 16, KSG=110"
где значения "KPG= 16, KSG=110" могут меняться в разных строках ошибок. »Оптимальный вариант, как я вижу — собирать виды ошибок сразу в виде регулярных выражений, для WSH или PoSH. »ИМХО, это достаточно громоздко и не гибко.Rey71, не лучше ли это все было делать в excel »
Если заполняются поля и, кстати, они, похоже, поминаются в аварийном сообщении, то напрашивается решение:
формируем таблицу Excel по шаблону.
В первом столбце шаблона -заголовок секции (то, что начинается с #)
Во втором - ошибка без указания опознанного в строке сообщения поля - наверное, возможно и такое? Как, в принципе: когда имя поля в сообщении отсутствует, так и как упущении при создании Excel-шаблона: айтишник в атаку - дополняй шаблон, если надо.
В последующих - имена всех заполняемых полей. Сюда будут попадать сообщения, в котором помянуто поле в заголовке.
После импорта текстового файла в таблицу, созданную по шаблону, удаляем (скрываем?) столбцы, в которые ничего не попало, для лучшей читаемости.
Похоже, разный медперсонал отвечает за заполнение разных полей.
Флаг в руки! В фильтре таблицы каждый может указать отбор по своим непустым полям.
Вуаля!
ИМХО, довольно объёмная работа и для тестирования понадобится реальный файл.
Обычно я пытаюсь смотреть на инфу глазами конечного пользователя. Что он получает сейчас и что его в этом не устраивает? Сформулируйте, приведите примеры, прежде чем пытаться что-то делать, тыкая пальцем в небо.
Можно пойти по пути Iska, но немного не так.
Без Excel, например, в VBS, сформировать массив со списком полей в виде строки с разделителем для каждого пользователя и формировать столько файлов с копиями секций исходного файла, сколько элементов в этом массиве. Это более простое решение.
Теперь это уже немножко офтопик - мне было интересно решить задачу в первоначальной формулировке на powershell:
$errors = @{}
switch -Regex -CaseSensitive -File 'errors.log' {
'^#.*' {
$section = [System.Collections.Generic.List[String]]$_
continue
}
default {
$section.Add($_)
$errors[$_] += [System.Collections.Generic.List[String]]$section
}
}
$errors.Values | .{begin{$n=0} process{$n++; Add-Content -Path "$n.txt" -Value $_ }}
Ну тогда и я на powershell со своей идефикс, что выводить все ошибки по каждому пациенту в разные файлы иррационально.
Принцип:
для каждой ошибки свой файл, если есть ошибка с привязкой к пациенту, то выводим такую ошибку в определенный для неё файл:
$fle = 'obraz.txt'
$err_out = 'error_out.txt'
gc $fle -enc default|%{$flg,$arr,$err=$true,@(),@()}{
if ($_ -match '#\s*\d+'){$name = $_} else {
$tmp = $_
for ($i=0;$i -lt $arr.count;$i++){
if ($tmp -match $arr[$i]){
$name,$tmp|out-file "$($i+1).txt" -enc default -app
$flg = $false
}
}
if ($flg){
$arr += ($tmp -replace '^([^:\(,]*).*','$1')
$name,$tmp|out-file "$($i+1).txt" -enc default -app
$err+=$tmp
}
$flg=$true
}
}
$err|sc $err_out -enc default
бонусом выводится перечень уникальных ошибок...
megaloman
23-01-2019, 19:42
Rey71, FileIn = "Z:\Box_In\Errors\исходный файл.TXT"
' FileIn = "Z:\Box_In\Errors\obraz.TXT"
BoxOut = "Z:\Box_In\Errors"
Set FSO = CreateObject("Scripting.FileSystemObject")
On Error Resume Next
Set fIn = FSO.OpenTextFile(FileIn, 1, False)
If Err.Number <> 0 Then
MsgBox "Ошибка при открытии" + vbCrLf + FileIn + vbCrLf + vbCrLf + Err.Description
WScript.Quit 2
End If
On Error GoTo 0
Alls = fIn.ReadAll
fIn.Close
MasAll = Split(Alls, vbCrLf)
MasN = Split(Alls, "#")
A0 = LBound(MasAll)
AN = UBound(MasAll)
N0 = LBound(MasN)
NN = UBound(MasN)
Set Alls = Nothing
ReDim MasErr(AN)
ie = A0 - 1
For Each s In MasAll
If Not Len(Replace(s, " ", "")) = 0 Then
If Not Mid(s, 1, 1) = "#" Then
If ie = A0 - 1 Then
ie = A0
MasErr(ie) = s
Else
L = 0
For i = A0 To ie
If s = MasErr(i) Then
L = 1
Exit For
End If
Next
If L = 0 Then
ie = ie + 1
MasErr(ie) = s
End If
End If
End If
End If
Next
DNow = Date
sNow = Mid(CStr(Year(DNow)), 3, 2) + Mid(CStr(Month(DNow) + 100), 2, 2) + Mid(CStr(Day(DNow) + 100), 2, 2)
DNow = Time
sNow = sNow + Mid(CStr(Hour(DNow) + 100), 2, 2) + Mid(CStr(Minute(DNow) + 100), 2, 2) + Mid(CStr(Second(DNow) + 100), 2, 2)
nFile = 10000
On Error Resume Next
Set fErr = FSO.CreateTextFile(BoxOut + "\" + sNow + "_" + Mid(CStr(nFile), 2) + ".txt", True)
If Err.Number <> 0 Then
MsgBox "Ошибка при создании" + vbCrLf + vbCrLf + BoxOut + "\" + sNow + "_" + Mid(CStr(nFile), 2) + ".txt" + vbCrLf + Err.Description
WScript.Quit 2
End If
For Each s In MasErr
nFile = nFile + 1
If nFile - 10000 > ie + 1 - A0 Then Exit For
On Error Resume Next
Set fOut = FSO.CreateTextFile(BoxOut + "\" + sNow + "_" + Mid(CStr(nFile), 2) + ".txt", True)
If Err.Number <> 0 Then
MsgBox "Ошибка при создании" + vbCrLf + vbCrLf + BoxOut + "\" + sNow + "_" + Mid(CStr(nFile), 2) + ".txt" + vbCrLf + Err.Description
WScript.Quit 2
End If
fErr.WriteLine Mid(CStr(nFile), 2) + " " + s
fOut.Write "=== Ошибка " + s + vbCrLf + vbCrLf
On Error GoTo 0
For Each block In MasN
If Not Len(Replace(Replace(block, vbCrLf, ""), " ", "")) = 0 Then
If InStr(1, block, s) <> 0 Then
fOut.Write "#" + block
End If
End If
Next
fOut.Close
Next
fErr.Close
MsgBox "Скрипт завершен"
Всем огромное спасибо.
Понял что с наскока решить не получится.
Буду думать над правильной постановкой задачи.
Понял что с наскока решить не получится.
Буду думать над правильной постановкой задачи. »
Решить-то, как раз можно... вопрос именно только в постановке задачи.
Что в конечном итоге требуется получить?
Особенно, желательно описать подробнее это:
несколько файлов которые будут группироваться по ошибкам чтобы раздать мед персоналу для исправления ошибок. »
т.е. как именно необходимо группировать ошибки? Для одного человека несколько пациентов со всеми ошибками или же для одного человека - только один тип ошибки?
то бишь:
1. Один файл - один тип ошибки, но по разным пациентам, у которых этот тип ошибки присутствует.
2. Один файл - несколько (сколько именно?) пациентов, причем со всеми ошибками по каждому, отобранному пациенту.
3. ... ?
Третьего варианта, лично я не вижу, т.к. при нахождении одного типа ошибки по одному пациенту, выводить все ошибки привязанные к этому пациенту в отдельный файл - не имеет смысл, т.к. не будет никакой упорядоченности, да и собственно, вообще никакого алгоритма отбора информации для вывода в разные файлы, в этом случае тоже не будет.
Надо вычислять какой-то идентификатор строки ошибки. Например, удалить весь известный динамический контент в строке ошибки, (или всё, кроме кириллицы), привести к одному регистру, вычислить md5 от того, что осталось. Это будет ключ для группировки по ошибке (по файлам, или поле в БД).
Sham, если понимать, что такое хэш-таблица, или представлять как устроены БД, то становится очевидным, что все эти велосипеды изобретены и реализованы до вас
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC