Hallo,
ich komme bei einem proc format nicht weiter 😞 Mein Wissen dazu ist aber zugegebener Weise auch ziemlich dürftig...
Meine Quelldaten kommen aus DB2 und liegen dort z.T. als DECIMAL in unterschiedlichen Längen vor. Diese will ich nun umformatieren in ein festes Format, vorgenullt und inkl. Vorzeichen, um dies in einer txt-Datei zu speichern.
Beispiele:
DB2-Format | Quellwert | Zieltext |
---|---|---|
DECIMAL(4, 0) | 2222 | +2222 |
DECIMAL(4, 0) | -333 | -0333 |
DECIMAL(5, 2) | -123,45 | -12345 |
DECIMAL(7, 2) | 1234,00 | +0123400 |
Das proc format, was ich mir schon zurechtgeschustert habe funktioniert soweit, aber flexibel bin ich damit so gar nicht, denn ich muss für jedes Quellformat ein eigenes Ausgabeformat definieren. Das geht doch bestimmt besser, oder?
PROC FORMAT ;
/*DECIMAL(5, 0) als SAS-Format DEC50_6. */
PICTURE DEC50_ LOW-<0 = 99999 ( MULTIPLIER=1 PREFIX='-')
0-HIGH = 99999 ( MULTIPLIER=1 PREFIX='+')
;
/* DECIMAL(5, 0) als SAS-Format DEC40_5. */
PICTURE DEC40_ LOW-<0 = 9999 ( MULTIPLIER=1 PREFIX='-')
0-HIGH = 9999 ( MULTIPLIER=1 PREFIX='+')
;
/* DECIMAL(15, 2) als SAS-Format DEC152_16. */
PICTURE DEC152_ LOW-<0 = 999999999999999 ( MULTIPLIER=100 PREFIX='-')
0-HIGH = 999999999999999 ( MULTIPLIER=100 PREFIX='+')
;
RUN;
Als SAS-Format schwebt mir da natürlich sowar ganz einfaches wie DEC4.0 oder DEC7.2 vor, die dann genau das gewünschte Ergbnis liefern... Aber das wäre nur der Optimalfall 🙂 Vielleicht gibt es ja ein PROC-FORMAT-Könner hier 🙂 Danke!
Gruß aus Hamburg
Marco Schmidt
P.S. Bonusfrage 🙂 Der Code reicht mir soweit, aber wer mir dann noch erklärt, wie ich das in die Anwendungsroutine "Format erstellen" im Enterprise Guide einklicken kann... 🙂
Hallo,
das sieht mit dem Format doch schon ganz gut aus.
Ein Picture-Format kann meines Wissens nicht über eine Anwendungsroutine erstellt werden.
Vielleicht lässt sich das Thema schon beim Laden der Daten in SAS lösen? Z.B. mit entsprechender Umformung und ggf. Pass-Through.
Ansonsten könnte es einfacher werden, wenn man das in einem Data Step mit verschiedenen IF-Statements (und Array) löst?
Dazu sollte dann klar sein, welche Umformungsregeln gelten. Das ist mir aus den Beispielen nicht ersichtlich.
Das hängt meines Erachtens sehr stark davon ab, wieviele Spalten es gibt und wie komplex die anzuwendenden Regeln sind. Gegebenenfalls lässt sich so die Umformung recht elegant in einem Schritt lösen, es kann aber auch sein, dass das die Sache nur verkompliziert.
Eventuell könnte ein Workaround auch sein die Metadaten auszulesen und dementsprechend dann die Picture-Formate zuzuordnen. So würde man sich das manuelle Zuordnen sparen.
Viele Grüße
Michael
Hallo,
bezüglich eines Formats kann ich leider nicht weiterhelfen. Aber mit einem kleinen Makro (siehe unten) würde es vielleicht auch gehen...?
%macro dec(x, a, b);
%local flen;
%let flen=%eval(&a. + 1);
input(put(&x., S370FZDS&flen..&b.), $EBCDIC&flen..)
%mend;
data Test;
x1 = -123.45;
y1 = %dec(x1, 5, 2);
x2 = 1234.00;
y2 = %dec(x2, 7, 2);
run;
Zunächst wird die Feldlänge berechnet, da hier 1 für das Vorzeichen addiert werden muss.
Dann wird das Format S370FZDSw.d benutzt, welches genau die gesuchte Transformation anwendet,
leider aber nur im EBCDIC-Format. Daher muss mit dem Informat $EBCDICw. von EBCDIC nach ASCII
konvertiert werden.
Ich hoffe, das hilft. Schöne Grüße,
Daniel Enache.
Hallo Marco,
im EG kann man meines Wissens kein Picture-Format erstellen. Es ist aber möglich, ein Programm zu schreiben, dass die Pictureformate automatisch erstellt.
Ich bin davon ausgegangen, dass die Decimalformate als Tabelle vorliegen. Man extrahiert die Längeninformationen und baut sich dann mit call execute dass entsprechende Proc format Statement.
Anschließend sind die Formate dem System bekannt und können verwendet werden.
Data test;
informat format $13. value Best9.;
input Format $13. value;
cards;
DECIMAL(4, 0) 2222
DECIMAL(4, 0) -333
DECIMAL(5, 2) -123.45
DECIMAL(7, 2) 1234.00
run;
Data test1;
set test;
/* extrahieren der Längeninformationen */
before = Input(compress(scan(format,1,","),,'kd'), best32.);
after = Input(compress(scan(format,2,","),,'kd'), best32.);
/* berechnen des Multiplikators */
multiplier = 10**after;
/* Erzeugen des Picturetexts */
Picture = repeat('9', before-1);
/* Der Name des SAS-Formats wird zugiesen */
fmtname = cats('Dec',put(before,z2.),after,'_.');
/* Die Format Prozedur wird aufgerufen */
call execute ('Proc Format;');
call execute (' ' || cats('picture Dec',put(before,z2.),after,'_'));
call execute ("low - < 0 = '-" || strip(picture) || "'( MULTIPLIER = " || put(Multiplier, best32.) || " PREFIX='-')");
call execute ("0 - high = '+" || strip(picture) || "'( MULTIPLIER = " || put(Multiplier, best32.) || " PREFIX='+')");
call execute (";");
call execute ("run;");
run;
Data _null_;
set test1;
Text = putN(value,fmtname);
put value= @16 Fmtname= @34 Text= @50 Format=;
run;
Viele Grüße
Jan
Bitte habe die Begriff was da herum geht.
Vom db2 nach SAS wirden die zahlen umgesetzt aus db2 nach floating numerics. Die SAS/access soll die Umsetzung machen und das Format Type im SAS gut setzen.
Wenn sie ein anderes Format einsetzen wollen ist das gut zumachen mit die sashelp.v-members womit die gelieferte Information gibt. Mit gewunschte Änderung kann Proc datasets benutzt wirden.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!