Как читать и анализировать элементы данных X12 с помощью PowerBuilder?

Содержимое плоского файла:

ST*850*12500001|
BEG*00*NE*71249364**20130103|
CUR*SE*SGD|
REF*BT*SGL169816-7191416|
P01*0000000001*4*EA*0*CP*UP*731304265511*VP*SURT1000XLIQ|
P01*0000000002*10*EA*0*CP*UP*731304265511*VP*SURT1000XLIQ|
P01*0000000003*100*EA*0*CP*UP*731304265511*VP*SURT1000XLIQ|

первые строки файла

Вопрос:

Любой, кто может поделиться идеей о том, как динамически анализировать каждый элемент. Длина каждых данных время от времени различается, например: 12500001, 731304265511 и SURT1000XLIQ. Проблема в том, как я могу получить данные между звездочкой (*) и конвейером (|). Спасибо помог....


person RedHat    schedule 14.04.2013    source источник
comment
просто уведомляю вас: файлы x12 в основном / всегда «обернуты» заголовком ISA и трейлером. Я не думаю, что вы показываете здесь то, что вы на самом деле получите.   -  person eppye    schedule 15.04.2013
comment
Кроме того, сегмент ISA помогает определить терминатор сегмента, разделитель подэлементов и разделитель элементов. Вы можете понять это по своему образцу, но вам также не хватает информации об отправителе/получателе.   -  person Andrew    schedule 16.04.2013
comment
Привет, у меня уже есть полная документация и пример файла 850 до публикации этого. Я только что написал, где должен начинаться парсинг.   -  person RedHat    schedule 22.04.2013


Ответы (4)


Ваш плоский файл выглядит как файл EDI, но не EDIFACT.

Есть некоторые конвертеры (либо с открытым исходным кодом, либо коммерческие) из EDI в XML, может быть, вы можете попробовать с таким инструментом, чтобы иметь возможность читать полученный файл xml в DataWindow или хранилище данных?

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

Пример конвертеров EDI -> XML:

EDIT: я только что наткнулся на древнюю запись в PowerBuilder Developer Journal, посвященную той же теме: "Преобразование X12 EDI в XML" дает дополнительные идеи.

person Seki    schedule 14.04.2013
comment
Зачем конвертировать в XML? Почему бы не сбросить его прямо в базу данных? Или CSV? Или плоский файл? Кажется, все хотят перевести в XML, а я не понимаю. Во многих случаях это просто дополнительный шаг, если этого не требует ваша ERP-система или система промежуточного программного обеспечения (например, преобразование EDI в IDOC для SAP). - person Andrew; 16.04.2013
comment
@Andrew: я предлагаю преобразовать его, потому что ОП просто говорит о файле, не сообщая, создает ли он его или он предоставляется как есть. Кроме того, хотя xml не должен быть золотым молотком, использование его в качестве сводного формата может увеличить количество способов обработки его после в PB (окно данных, хранилище данных, pbdom). Я сомневаюсь, что что-то уже существует для Powerbuilder для обработки файлов EDI. Конечно, другой вариант - сделать свой собственный парсер из спецификаций. - person Seki; 16.04.2013
comment
Ребята, я просто хочу поделиться тем, что я сделал. Я разработал функцию PB, которая будет анализировать данные на основе технического проекта, а затем сбрасывать их в таблицу после процедуры анализа, и это довольно сложно, потому что нужно анализировать множество элементов, и анализ должен вестись динамически, потому что длина символа каждый элемент непостоянен. Спасибо за мысли и идеи. - person RedHat; 22.04.2013

Если бы вы использовали старый добрый PowerBuilder, основами было бы выполнение нескольких Pos() и Mid(); ничего автомагического. Однако в своих тегах вы упоминаете PFC; вы всегда можете добавить функцию String Service of_ParseToArray() после того, как вы прочитали файл, что-то вроде (следующее не проверено, и читатель должен найти ошибки):

long ll_Line, ll_LineCount, ll_Element, ll_ElementCount
string ls_Lines[], ls_Elements[]
n_cst_String lnv_String  

ll_LineCount = lnv_String.of_ParseToArray (ls_FileContents, "|", ls_Lines)
FOR ll_Line = 1 TO ll_LineCount
   ll_ElementCount = lnv_String.of_ParseToArray (ls_Lines[ll_Line], "*", ls_Elements)
   // process the line with the elements separated out...
NEXT

Удачи,

Терри

person Terry    schedule 16.04.2013
comment
Привет, Терри, я думаю, у нас одинаковый подход. Спасибо. - person RedHat; 22.04.2013

Это файл X12, заказ на покупку 850. Как предлагает eppye в комментариях, вам нужно точно выяснить, какому стандарту соответствует файл, который вы получаете. Для начала есть версия 850 здесь. «Черновик MEMA 4010 850» поможет вам разобраться в формате. «GCommerce 4010 850V1.4.doc» — это словарь данных, который сообщает вам, что содержится в каждом элементе. Пожалуйста, поймите, однако, что если вы не продаете автозапчасти, это, вероятно, не точная спецификация файла, с которым вы работаете. Люди, отправляющие вам файл, должны предоставить его вам.

Я бы создал пользовательский объект для каждого сегмента и цикла, а также объект для представления самого заказа на покупку. Заказ на поставку UO нуждается в переменных, которые являются типом данных сегментов и циклов. Не включайте сегменты, которые находятся внутри петель, поместите их в UO для петли. UO для сегмента будет иметь переменные, которые являются стандартными типами данных, такими как строка, целое число, дата и т. д. для элементов данных в сегменте. Обратитесь к Словарю данных для типов данных.

Обратите внимание, что если сегмент повторяется, переменная, содержащая сегмент, является массивом. Переменными для циклов будут массивы.

Ваши объекты, которые обрабатывают сегменты, будут иметь метод, например. of_importLine, который разбивает строку по звездочке и сохраняет значения.

Ваши объекты, которые обрабатывают циклы, будут иметь метод, например. of_readLoop, который читает строки (сегменты), пока не прочитает последний сегмент цикла. Для каждого сегмента он создаст UO для этого типа сегмента, назначит его переменной экземпляра или следующему слоту массива, если сегмент может повторяться, и вызовет of_importLine нового объекта.

Ваш объект, который обрабатывает заказ на покупку, подобен объекту для цикла, за исключением того, что, когда он видит первый сегмент цикла, он создает UO для этого типа цикла, назначает его следующему слоту массива для цикла и вызывает новый объект of_readLoop. Обратите внимание, что пока ваш объект заказа на покупку считывается внутри цикла, он создает новый объект для чтения и сохранения каждого повторения цикла.

Ваши объекты, которые читают циклы, должны регистрировать ошибку и останавливаться, если требуемый сегмент отсутствует или найден сегмент, не принадлежащий циклу. Ошибка должна включать номер строки и ее содержимое. Я не могу дать вам подробное описание того, как проверить сам заказ на поставку, потому что многие сегменты являются необязательными в спецификации, но, вероятно, они не являются необязательными в вашем приложении. Для каждого сегмента и цикла у объекта есть переменная, ему нужна последовательность, в которой появляется элемент, а также минимальное и максимальное количество вхождений. Затем объект PO может проверять сегменты и циклы по мере продвижения.

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

person Hugh Brackett    schedule 15.04.2013
comment
выглядит как обычный заказ x12 850 для меня. Не могли бы вы уточнить, почему это заказ на покупку MEMA 850? - person eppye; 16.04.2013
comment
благодарю вас. Но вроде и т. д. все еще есть. Велика вероятность, что модель 850 следует другому руководству (от другого покупателя); может привести к недоразумениям? - person eppye; 16.04.2013
comment
конечно. люди, отправляющие ему файл, должны сообщить ему, что они отправляют. я отредактировал свой ответ, включив это и уточнив, что предоставленные мной ссылки не обязательно являются точной спецификацией для его файла. - person Hugh Brackett; 17.04.2013

Ниже приведен метод, который я получил.

ls_tranidcode = of_trimdata(is_Message, 4, '*')
ids_edihdr.SetItem(ll_hdrins,'TRANSETIDCODE',ls_tranidcode)

Function:
of_trimdata()

Return Type : String 
Argument Type : 
String arg_msg
Integer pos1
String  s_dlm

Long ll_pos2
String ls_ret

arg_msg = mid(arg_msg, pos1)            
ll_pos2 = POS(arg_msg,s_dlm) 
ls_ret = Mid(arg_msg, 1, ll_pos2 - 1)
arg_msg = Mid(arg_msg, ll_pos2 + 1) 

RETURN ls_ret
person RedHat    schedule 22.04.2013