Variablengröße ändern ohne Verschiebung der Spalte

Hallo Freunde,
gibt es die Möglichkeit, eine Character-Variable in einer gefüllten Tabelle zu vergrößern, ohne dass die Spalte dann in der Reihenfolge nach vorn verschoben wird?

Wenn ich es mit dem Befehl "length" mache, rutscht die Spalte immer an den Anfang der Tabelle (siehe Code-Beispiel).

/** Tabelle anlegen **/
data zzz;
input nr name $;
datalines;
1 fred
2 horst
3 benedikt
;
run;

/** Char-Variable nachträglich vergrößern **/
data zzz;
length name $20.;
set zzz;
run;

Ergebnis: Spalte verschoben.

name        nr
-----------------
fred         1
horst        2
benedikt     3

Gibt's einen Weg, das zu vermeiden?

Danke und Gruß
Frederik

Makro zum kontrollierten Handling der Spaltenlängen

Hallo.

Ich hab dazu mal ein Makro geschrieben, welches sich diesem Thema annimmt. Allerdings weist dieses die Länge auf Grund des Inhalts der vorhandenen Variablen automatisch zu. Aber zu Studienzwecken gebe ich es gerne hier wieder:

/*
Decription: Macro to resign field length on maximum needed length plus 10 percent
Parameter:
dsn: Inputdataset (default: &syslast),
out_dsn: (default: the input dataset),
pct = offset for length (default: 10 percent)
Author: Dubravko Dolic (dsquare.de)
Date: 2009-09-09
Revision: 0.1
*/

%macro optimize_length(dsn = &syslast, out_dsn =, pct = 10);
%local cc vars thisvar lenstr lib ret_vars dsid rc;

%let lib = WORK;
%let dsn = %upcase(&dsn);
/* Wenn der Eingabedatensatz vom Anwender als LIBRARY.TABELLE angegeben wurde, muessen die Makrovariablen LIB und DSN neu definiert werden. */
%if %index(&dsn, %str(.)) > 1 %then %do;
%let lib = %upcase(%scan(&dsn, 1, %str(.)));
%let dsn = %upcase(%scan(&dsn, 2, %str(.)));
%end;

/* Holen aller Felder vom Typ CHAR und erzeugen einer Makrovariablen, in der die Reihenfolge der Felder gespeichert ist. */
%let dsid=%sysfunc(open(&lib..&dsn.,i));
%let ret_vars = ;
%let vars = ;
%do cc=1 %to %sysfunc(attrn(&dsid,nvars));
%let ret_vars = &ret_vars %sysfunc(varname(&dsid,&cc));
%if (%sysfunc(vartype(&dsid,&cc)) = C) %then %let vars = &vars %sysfunc(varname(&dsid,&cc));
%end;
%let rc=%sysfunc(close(&dsid));

%put NOTE: Input order of variables was: &ret_vars..;

%let cc = 1;
%let pct = 1.&pct;
%let lenstr = length ;

%do %while(%scan(&vars, &cc) ne); /* <- Rolliere durch jedes Feld vom Typ CHAR */
%let thisvar = %scan(&vars, &cc);
proc sql noprint;
select
max(length(&thisvar)) into :thislen /* Ressourcenintensiver Teil */
from &lib..&dsn;
quit;
%let lenstr = &lenstr &thisvar $ %sysevalf(&thislen * &pct, ceil);
/*
Hier wird ein String erzeugt, der spaeter die Laengen der einzelnen Felder definiert.
Der fertige String in LENSTR enthaelt das Statement LENGTH $ ...
*/
%let cc = %eval(&cc + 1);
%end;

/* Hier kann der Datenload erfolgen. */
%if &out_dsn eq %then %let out_dsn = &lib..&dsn;
data &out_dsn;
&lenstr.; /*<- diese Makrovariable setzt die ermittelten Laengen */
set &lib..&dsn;
run;

data &out_dsn;
retain &ret_vars; /* <- Retain Statement regelt die Feldreihenfolge. Darf leider nicht gemeinsam mit length in einen data step. */
set &out_dsn;
run;

%mend optimize_length;

/* Makro ausfuehren */
options mprint symbolgen mlogic;
%optimize_length(dsn = testdaten)

Hab was kürzeres gefunden

Wow, vielen Dank, dolic!
Das werd ich mir auf jeden Fall an die Seite legen. Für meine bescheidenen Zwecke hab ich aber was kürzeres gefunden. Per SQL-Befehl "alter" kann man die Feldlänge verändern, ohne dass die Spalte verschoben wird.

proc sql;
alter table zzz
modify name char(100) format=$100.;
quit;

Trotzdem danke für die Hilfe!

Gruß Frederik