2010-03-01 12 views
7

I Jon Skeet's EBCDIC implementation in .NET bin mit einer VSAM-Datei im Binär-Modus mit FTP von einem Mainframe-System heruntergeladen zu lesen. Es funktioniert sehr gut zum Lesen/Schreiben in dieser Kodierung, aber es hat nichts, um gepackte Dezimalwerte zu lesen. Meine Datei enthält diese und ich muss sie entpacken (natürlich auf Kosten von mehr Bytes).Auspacken EBCDIC Verpackt Dezimalzahlen (COMP-3) in einer ASCII-Konvertierung

Wie kann ich das tun?

sind meine Felder als PIC S9(7)V99 COMP-3.

+0

gepackt-dezimal Teil des EBCDIC-Format, oder ist das nur eine Datei, die beide zu verwenden, geschieht? Ich bin mit diesem Format nicht vertraut, ich habe Angst :( –

+0

Es ist eine Datei, die beide benutzt. Es ist eine alte Schule Art und Weise Zahlen drücken Bytes zu speichern. A -99999.99 kann in 4 Bytes gespeichert werden. –

+0

http://www.3480-3590-data-conversion.com/article-packed-fields.html –

Antwort

3

Ahh, BCD definiert. Honk, wenn Sie es in 6502 Montage verwendet haben.

Natürlich ist die beste Wette ist, die COBOL-MOVE tun, um die Arbeit für Sie zu lassen! Eine dieser Möglichkeiten kann helfen.

(Möglichkeit # 1) Angenommen, Sie haben Zugriff auf den Mainframe und den Quellcode, und die Ausgabedatei ist nur für Ihre Verwendung, ändern Sie das Programm, so verschiebt es nur den Wert zu einem unverpackten PIC S9 (7) V99.

(Möglichkeit # 2) Angenommen, es ist nicht so einfach (zB Datei wird für andere PGMS eingegeben oder kann den Code nicht ändern), können Sie ein anderes COBOL-Programm auf dem System schreiben, das diese Datei liest und eine andere schreibt . Schneiden Sie das Dateisatzlayout mit dem BCD aus und fügen Sie es in das neue Programm für Eingabe- und Ausgabedateien ein. Ändern Sie die Ausgabeversion so, dass sie nicht gepackt ist. Lesen Sie einen Datensatz, machen Sie einen "Umzug entsprechend", um die Daten zu übertragen, und schreiben Sie bis eof. Dann übertragen Sie , dass Datei.

(Möglichkeit # 3) Wenn Sie den Mainframe nicht berühren können, notieren Sie sich die Beschreibung im Artikel Sie in Ihrem Kommentar verknüpft. BCD ist relativ einfach. Es könnte so einfach wie diese (vb.net):

Private Function FromBCD(ByVal BCD As String, ByVal intsz As Integer, ByVal decsz As Integer) As Decimal 
    Dim PicLen As Integer = intsz + decsz 
    Dim result As Decimal = 0 
    Dim val As Integer = Asc(Mid(BCD, 1, 1)) 
    Do While PicLen > 0 
     result *= 10D 
     result += val \ 16 
     PicLen -= 1 
     If PicLen > 0 Then 
      result *= 10D 
      result += val Mod 16 
      PicLen -= 1 
      BCD = Mid(BCD, 2) 
     End If 
     val = Asc(Mid(BCD, 1, 1)) 
    Loop 
    If val Mod 16 = &HD& Then 
     result = -result 
    End If 
    Return result/CDec(10^decsz) 
End Function 

ich es mit ein paar Variationen dieses Aufrufs getestet:

MsgBox(FromBCD("@" & Chr(13 + 16), 2, 1)) 

Z. B. ist -40,1. Aber nur ein paar. Es könnte also immer noch falsch sein.

Also dann, wenn Ihre comp-3 beginnt, sagen wir, bei Byte 10 des Eingangssatzaufbau, das es lösen wäre: für die Anzahl der Bytes

dim valu as Decimal = FromBCD(Mid(InputLine,10,5), 7,2)) 

Anbetracht der Formeln aus der Datenumwandlungs Artikel in, und der # 9 die vor und nach der V.

das Ergebnis in einem Dezimal zu senden Rundungsfehler zu vermeiden. Esp, wenn es $$$ ist. Float & Double wird dir Kummer bereiten! Wenn Sie es nicht verarbeiten, ist sogar eine Zeichenfolge besser.

es natürlich könnte härter sein. Wo ich arbeite, ist der Mainframe 9 Bits pro Byte. Ernst. Das macht die ersten beiden Möglichkeiten so herausragend. Natürlich, was sie wirklich besser macht, ist die Tatsache, dass Sie vielleicht nur ein PC-Programmierer sind und das ist eine großartige Ausrede, um einen Mainframe-Programmierer dazu zu bringen, die Arbeit für Sie zu erledigen! Wenn Sie das Glück haben, dass die Option haben ...

Frieden, -Al

+1

Danke Al! Möglicherweise ist es möglich, das COBOL-Programm zu ändern oder ein anderes zu entpacken zu lassen, aber das Ziel ist, dies in .NET zu erreichen, so dass wir einfach nur VSAM -> FTP-Aufgaben ausführen können. Woher weiß ich, wo das V (Dezimal) basierend auf der binären Darstellung ist? Ist das überhaupt möglich? Wie weiß der Mainframe? Nochmals vielen Dank, ich schätze Ihre Hilfe. –

+0

Josh, du kannst nicht wissen, wo das V nur aus den Daten ist; Du brauchst den PIC. Der Mainframe verfolgt dies vom PIC aus. Typische schlanke, bitsparende Lösung aus den Lochkarten-Tagen. Aber wenn Sie darüber nachdenken, gibt es nie einen Fall, in dem das System nicht die Informationen hat, die es braucht. Verdammt, wenn du das Plattenlayout nicht selbst sehen kannst, musst du es sowieso hacken! – FastAl

+0

Ja, du hast Recht, ich dachte nicht, dass es einen Weg geben würde. Ich habe alle Offsets bestimmt und das Layout des Datensatzes ist hier, ich war nur neugierig, ob es einen Weg gab, die Dezimalstelle programmatisch herauszufinden. Okay, ich werde dieser Funktion morgen einen Wirbel geben und euch wissen lassen, wie es funktioniert! Nochmals vielen Dank für Ihre Hilfe, ich wünschte, ich könnte zweimal upvote. –