|
楼主

楼主 |
发表于 2009-8-5 09:42:31
|
只看该作者
再问下“死猪头” :D
<!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D --> 如果我现在是求每次采购的商品的加权平均库存时间,对你那个程序稍微改动一下就可以实现,不过必须对数据进行适当排序(一定要卖出排在采购前面)才行,程序附后。
[color=#800000:1sub4pu6]现在的问题是:[/color:1sub4pu6] 由于我的实际数据比较复杂,比如第8行(Note=0),那120个商品是供应商免费送的(不能单独计算其库存时间),需要把他分配到还没卖完的进货批次中(无需其他的操作)。具体来说,供应商免费送货只分配给还没卖完的进货批次,按照加权平均的原则分配。比如如果供应商免费送货之前还有2次的进货还没卖完,假设免费送货数量为x,两次没卖完的进货声誉数量分别为y1和y2,那么y1=y1+x*y1/(y1+y2), y2=y2+x*y2/(y1+y2) 。如果送货之前有更多次的进货没卖完,按照相同的方法分配。
另外,对于还没有卖完的进货,其库存时间也是不必计算的。
数据说明:ID为商品编号,Date为采购或卖出时间,Num为采购或卖出数量,Act识别是采购还是卖出, Note是备注。
data a;
input ID$ Date yymmdd8. Num Act Note;
format Date yymmdd10.;
cards;
001 08-07-01 100 1 .
001 08-07-02 20 0 .
001 08-07-05 100 1 .
001 08-07-06 80 0 .
001 08-07-07 40 0 .
001 08-07-08 40 0 .
001 08-07-09 100 1 .
001 08-07-10 120 1 0
001 08-07-12 240 0 .
002 08-07-01 100 1 .
002 08-07-02 20 0 .
002 08-07-05 80 0 .
002 08-07-06 100 1 .
002 08-07-08 50 0.
;
proc sort data=a;
by ID Act;
%let QUEUE_SIZE=1000;
data zhutou(drop = head tail tmp_num total);
array queue[0:&QUEUE_SIZE, 1:2] _temporary_;
head = 0;
tail = -1;
do until(last.id);
set a end=eof;
by id;
if Act=0 then do;
tail = mod(tail+1, &QUEUE_SIZE);
if mod(tail+1, &QUEUE_SIZE) = head then do;
put "Error - QUEUE overflow: bigger QUEUE_SIZE wanted";
stop;
end;
queue[tail,1] = num;
queue[tail,2] = date;
avg = .;
end;
else do;
total = 0;
tmp_num = num;
do while(tmp_num > 0 and head ne mod(tail+1, &QUEUE_SIZE));
if tmp_num>queue[head,1] then do;
tmp_num = tmp_num-queue[head,1];
total = total + queue[head,1]*(-date+queue[head,2]);
queue[head,1]=0;
head = mod(head+1, &QUEUE_SIZE);
if head = mod(tail+1, &QUEUE_SIZE) then do;
avg = .;
end;
else do;
avg = total / num;
end;
end;
else do;
total = total + tmp_num*(-date+queue[head,2]);
queue[head,1] = queue[head,1]-tmp_num;
tmp_num=0;
avg = total / num;
end;
end;
end;
output;
end;
run; |
|