老兄,我的这个是纸箱生产企业的选料程序,代码我不知道往那里发,就贴上来了,有时间
的话可以参考一下,不过可能帮助不是很大!这是我选料分析单元。看不懂的话你再问我
好了!
unit AsSayFrm;
interface
uses SysUtils,Dialogs;
type
TSpecs=record
SpecsId:integer;
StockLong,StockWidth:integer;
StockCount,AllUsesCount,ReallyUsesCount:integer;
UsesThisWidthFlag:boolean;
SquanderScale
ouble;
end;
TAcceptResult=record
Long,Width,Counts:integer;
QiPaoLong:double;
end;
TAcceptSpecs=record
AllAcceptResult:array of TAcceptResult;
IfAccept:boolean;
Areas:double;
LongUnitCount:integer;
end;
procedure AssayMaterial(const AWaBie,AMaterial:string;ALong,AWidth,AHeight:double;
ProduceCount:integer;ARepeatFlag:boolean;var AllAcceptSpecs:TAcceptSpecs);
procedure InitVars();
implementation
uses DmFrm, FunUnit;
var
MinSpecsWidth:integer=850;
MaxSpecsWidth:integer=1600;
SingleMaxLong:integer=2300;
do
ubleMaxLong:integer=2380;
MaxSquander:double=0.05;
AllSpecs:array of TSpecs;
procedure GetUseLongWidth(AWaBie,AMaterial:string;ALong,AWidth,AHeight:integer;
ARepeatFlag:boolean;var SpecsLong,SpecsWidth,LongUsesCount:integer);
begin
LongUsesCount:=1;
if AWaBie='1' then
begin
SpecsLong:=(ALong+AWidth)*2+30;
if (SpecsLong>SingleMaxLong) and (SpecsLong<=2*SingleMaxLong) then
begin
SpecsLong:=ALong+AWidth+30;
LongUsesCount:=2;
end;
if SpecsLong>2*SingleMaxLong then
begin
SpecsLong:=ALong+AWidth+30;
LongUsesCount:=4;
end;
end;
if AWaBie='2' then
begin
SpecsLong:=(ALong+AWidth)*2+40;
if (SpecsLong>DoubleMaxLong) and (SpecsLong<=2*DoubleMaxLong) then
begin
SpecsLong:=(ALong+AWidth)+40;
LongUsesCount:=2;
end;
if SpecsLong>2*DoubleMaxLong then
begin
SpecsLong:=ALong+AWidth+40;
LongUsesCount:=4;
end;
end;
if (SpecsLong mod 10)<>0 then
SpecsLong:=SpecsLong+10-(SpecsLong mod 10);
SpecsWidth:=AWidth+AHeight+10;
if ARepeatFlag then
SpecsWidth:=2*AWidth+AHeight+10;
end;
function GetBestWidth(AWidth:integer;var Multiple:integer):integer;
var
i1,i2,icounts,TmpSquander1,TmpSquander2,TmpWidth:integer;
begin
icounts:=MaxSpecsWidth div AWidth;
TmpSquander1:=AWidth;
for i1:=1 to icountsdo
begin
for i2:=(MinSpecsWidth div 50) to (MaxSpecsWidth div 50)do
begin
TmpSquander2:=(50*i2)-AWidth*i1;
if (TmpSquander2<TmpSquander1) and (TmpSquander2>=0) then
begin
TmpSquander1:=TmpSquander2;
Result:=(50*i2);
Multiple:=i1;
end;
end;
end;
end;
procedure ReadAllMaterial(AWaBie,AMaterial:string;ALong,AWidth:integer);
var i1:integer;
begin
with DmForm.QryPub1do
begin
Close;
Sql.Clear;
Sql.Add('select 规格代号,库存数量,长度,宽度 from 视图库存');
Sql.Add('where 瓦别代号='+AWaBie);
Sql.Add('and 原料代号='+AMaterial);
Sql.Add('and 长度>='+inttostr(ALong div 10));
Sql.Add('and 宽度>='+inttostr(AWidth div 10));
Open;
SetLength(AllSpecs,RecordCount+1);
i1:=1;
while not Eofdo
begin
AllSpecs[i1].SpecsId:=FieldByName('规格代号').AsInteger;
AllSpecs[i1].StockCount:=FieldByName('库存数量').AsInteger;
AllSpecs[i1].StockWidth:=FieldByName('宽度').AsInteger;
AllSpecs[i1].StockLong:=FieldByName('长度').AsInteger;
Next;
Inc(i1);
end;
end;
end;
procedure SortMaterial();
var i1,j1:integer;
begin
for i1:=2 to high(AllSpecs)do
begin
AllSpecs[0].SpecsId:=AllSpecs[i1].SpecsId;
AllSpecs[0].StockLong:=AllSpecs[i1].StockLong;
AllSpecs[0].StockWidth:=AllSpecs[i1].StockWidth;
AllSpecs[0].StockCount:=AllSpecs[i1].StockCount;
AllSpecs[0].AllUsesCount:=AllSpecs[i1].AllUsesCount;
AllSpecs[0].SquanderScale:=AllSpecs[i1].SquanderScale;
j1:=i1-1;
while AllSpecs[0].SquanderScale<AllSpecs[j1].SquanderScaledo
begin
AllSpecs[j1+1].SpecsId:=AllSpecs[j1].SpecsId;
AllSpecs[j1+1].StockLong:=AllSpecs[j1].StockLong;
AllSpecs[j1+1].StockWidth:=AllSpecs[j1].StockWidth;
AllSpecs[j1+1].StockCount:=AllSpecs[j1].StockCount;
AllSpecs[j1+1].AllUsesCount:=AllSpecs[j1].AllUsesCount;
AllSpecs[j1+1].SquanderScale:=AllSpecs[j1].SquanderScale;
dec(j1);
end;
AllSpecs[j1+1].SpecsId:=AllSpecs[0].SpecsId;
AllSpecs[j1+1].StockLong:=AllSpecs[0].StockLong;
AllSpecs[j1+1].StockWidth:=AllSpecs[0].StockWidth;
AllSpecs[j1+1].StockCount:=AllSpecs[0].StockCount;
AllSpecs[j1+1].AllUsesCount:=AllSpecs[0].AllUsesCount;
AllSpecs[j1+1].SquanderScale:=AllSpecs[0].SquanderScale;
end;
end;
function SetUsesEd(AAllUsesCount:integer;var AllAcceptSpecs:TAcceptSpecs):boolean;
var
i1,ProduceCount:integer;
begin
result:=False;
SetLength(AllAcceptSpecs.AllAcceptResult,0);
ProduceCount:=AAllUsesCount;
if Length(AllSpecs)=1 then
Exit;
for i1:=1 to high(AllSpecs)do
begin
if AllSpecs[i1].SquanderScale<=MaxSquander then
begin
if AllSpecs[i1].StockCount>=ProduceCount then
begin
AllSpecs[i1].ReallyUsesCount:=ProduceCount;
SetLength(AllAcceptSpecs.AllAcceptResult,length(AllAcceptSpecs.AllAcceptResult)+1);
AllAcceptSpecs.AllAcceptResult[High(AllAcceptSpecs.AllAcceptResult)].Long:=AllSpecs[i1].StockLong;
AllAcceptSpecs.AllAcceptResult[High(AllAcceptSpecs.AllAcceptResult)].Width:=AllSpecs[i1].StockWidth;
AllAcceptSpecs.AllAcceptResult[High(AllAcceptSpecs.AllAcceptResult)].Counts:=AllSpecs[i1].ReallyUsesCount;
AllAcceptSpecs.IfAccept:=False;
Result:=True;
Exit;
end
else
begin
ProduceCount:=ProduceCount-AllSpecs[i1].StockCount;
AllSpecs[i1].ReallyUsesCount:=AllSpecs[i1].StockCount;
SetLength(AllAcceptSpecs.AllAcceptResult,length(AllAcceptSpecs.AllAcceptResult)+1);
AllAcceptSpecs.AllAcceptResult[High(AllAcceptSpecs.AllAcceptResult)].Long:=AllSpecs[i1].StockLong;
AllAcceptSpecs.AllAcceptResult[High(AllAcceptSpecs.AllAcceptResult)].Width:=AllSpecs[i1].StockWidth;
AllAcceptSpecs.AllAcceptResult[High(AllAcceptSpecs.AllAcceptResult)].Counts:=AllSpecs[i1].ReallyUsesCount;
AllAcceptSpecs.IfAccept:=False;
end;
end
else
begin
Break;
end;
end;
end;
procedure InitVars();
begin
with DmForm.QryPub1do
begin
Close;
Sql.Clear;
Sql.Add('select * from AsSayConst');
Open;
if not IsEmpty then
begin
MinSpecsWidth:=FieldByName('MinSpecsWidth').AsInteger;
MaxSpecsWidth:=FieldByName('MaxSpecsWidth').AsInteger;
SingleMaxLong:=FieldByName('SingleMaxLong').AsInteger;
do
ubleMaxLong:=FieldByName('DoubleMaxLong').AsInteger;
MaxSquander:=FieldByName('MaxSquander').AsCurrency;
end
else
begin
MinSpecsWidth:=850;
MaxSpecsWidth:=1600;
SingleMaxLong:=2300;
do
ubleMaxLong:=2380;
MaxSquander:=0.05;
end;
end;
end;
function ReturnAFull(ADividend,ADivisor:integer):integer;
begin
Result:=iif((ADividend mod ADivisor)=0,ADividend,ADividend+ADivisor-(ADividend mod ADivisor));
end;
procedure AssayMaterial(const AWaBie,AMaterial:string;ALong,AWidth,AHeight:double;
ProduceCount:integer;ARepeatFlag:boolean;var AllAcceptSpecs:TAcceptSpecs);
var
i1,TmpUsesLong,TmpUsesWidth,UsesLong,UsesWidth,UsesHeight,AllUsesCount,
UnitDivCount,TmpStockLong,TmpStockWidth,LongUsesCount,BestWidth:integer;
TmpQiPaoLong
ouble;
begin
UsesLong:=Round(ALong*10);
UsesWidth:=Round(AWidth*10);
UsesHeight:=Round(AHeight*10);
if Trim(AWaBie)='3' then
begin
if UsesHeight>0 then
begin
if (UsesWidth+UsesHeight)>1200 then
begin
TmpUsesWidth:=ReturnAFull((UsesWidth+UsesHeight) div 2,10);
LongUsesCount:=2;
end
else
begin
TmpUsesWidth:=ReturnAFull(UsesWidth+UsesHeight,10);
LongUsesCount:=1;
end;
end
else
begin
if UsesWidth*2>1200 then
begin
TmpUsesWidth:=ReturnAFull(UsesWidth,10);
LongUsesCount:=2;
end
else
begin
TmpUsesWidth:=ReturnAFull(2*UsesWidth,10);
LongUsesCount:=1;
end;
end;
TmpUsesWidth:=ReturnAFull(TmpUsesWidth,10);
SetLength(AllAcceptSpecs.AllAcceptResult,1);
AllAcceptSpecs.Areas:=(ProduceCount*ALong*TmpUsesWidth/10)*LongUsesCount;
AllAcceptSpecs.AllAcceptResult[0].QiPaoLong:=ProduceCount*ALong;
AllAcceptSpecs.AllAcceptResult[0].Long:=1;
AllAcceptSpecs.AllAcceptResult[0].Width:=TmpUsesWidth div 10;
with DmForm.QryPub1do
begin
Close;
Sql.Clear;
Sql.Add('select 库存数量 from 视图库存 where 瓦别代号=3 and 宽度='+IntToStr(AllAcceptSpecs.AllAcceptResult[0].Width));
Open;
if Fields[0].Value>=AllAcceptSpecs.AllAcceptResult[0].QiPaoLong then
begin
AllAcceptSpecs.IfAccept:=False;
AllAcceptSpecs.AllAcceptResult[0].Counts:=0;
end
else
begin
AllAcceptSpecs.IfAccept:=true;
TmpQiPaoLong:=(AllAcceptSpecs.AllAcceptResult[0].QiPaoLong-Fields[0].AsCurrency)*100;
AllAcceptSpecs.AllAcceptResult[0].Counts:=ReturnAFull(Round(TmpQiPaoLong),1200000) div 100;
end;
end;
Exit;
end;
GetUseLongWidth(AWaBie,AMaterial,UsesLong,UsesWidth,UsesHeight,ARepeatFlag,TmpUsesLong,TmpUsesWidth,LongUsesCount);
BestWidth:=GetBestWidth(TmpUsesWidth,UnitDivCount);
AllAcceptSpecs.Areas:=(TmpUsesLong div 10)*(BestWidth div 10)*(ReturnAFull(ProduceCount,UnitDivCount) div UnitDivCount)*LongUsesCount;
AllAcceptSpecs.LongUnitCount:=LongUsesCount;
if (iif(ProduceCount mod UnitDivCount=0,ProduceCount,ProduceCount+UnitDivCount-ProduceCount mod UnitDivCount) div UnitDivCount)>100 then
begin
SetLength(AllAcceptSpecs.AllAcceptResult,1);
AllAcceptSpecs.AllAcceptResult[0].Long:=TmpUsesLong div 10;
AllAcceptSpecs.AllAcceptResult[0].Width:=BestWidth div 10;
AllAcceptSpecs.AllAcceptResult[0].Counts:=(iif(ProduceCount mod UnitDivCount=0,ProduceCount,ProduceCount+UnitDivCount-ProduceCount mod UnitDivCount) div UnitDivCount)* LongUsesCount;
AllAcceptSpecs.AllAcceptResult[0].Counts:=iif((UnitDivCount div LongUsesCount>=1) and (LongUsesCount mod 2=0) and (ProduceCount mod 2<>0),AllAcceptSpecs.AllAcceptResult[0].Counts-(UnitDivCount div LongUsesCount),AllAcceptSpecs.AllAcceptResult[0].Counts);
AllAcceptSpecs.IfAccept:=True;
exit;
end;
ReadAllMaterial(AWaBie,AMaterial,TmpUsesLong,BestWidth);
UnitDivCount:=BestWidth div TmpUsesWidth;
if ProduceCount mod UnitDivCount=0 then
AllUsesCount:=(ProduceCount div UnitDivCount)*LongUsesCount
else
AllUsesCount:=((ProduceCount+(UnitDivCount-(ProduceCount mod UnitDivCount))) div UnitDivCount) * LongUsesCount;
for i1:=1 to High(AllSpecs)do
begin
TmpStockLong:=AllSpecs[i1].StockLong*10;
TmpStockWidth:=AllSpecs[i1].StockWidth*10;
if (TmpStockWidth<BestWidth) or (TmpStockLong<TmpUsesLong) then
begin
AllSpecs[i1].SquanderScale:=10000;
AllSpecs[i1].AllUsesCount:=10000;
Continue;
end
else
begin
AllSpecs[i1].SquanderScale:=(TmpStockWidth*TmpStockLong-BestWidth*TmpUsesLong)*1.0/(TmpStockWidth*TmpStockLong);
AllSpecs[i1].AllUsesCount:=AllUsesCount;
end;
end;
SortMaterial();
if not SetUsesEd(AllUsesCount,AllAcceptSpecs) then
begin
//应去订货。所有小于3%的规格总和不够生产该数量的产品
SetLength(AllAcceptSpecs.AllAcceptResult,1);
AllAcceptSpecs.AllAcceptResult[0].Long:=(TmpUsesLong div 10);
AllAcceptSpecs.AllAcceptResult[0].Width:=BestWidth div 10;
AllAcceptSpecs.AllAcceptResult[0].Counts:=(iif(ProduceCount mod UnitDivCount=0,ProduceCount,ProduceCount+UnitDivCount-(ProduceCount mod UnitDivCount)) div UnitDivCount) * LongUsesCount;
AllAcceptSpecs.AllAcceptResult[0].Counts:=iif((UnitDivCount div LongUsesCount>=1) and (LongUsesCount mod 2=0) and (ProduceCount mod 2<>0),AllAcceptSpecs.AllAcceptResult[0].Counts-(UnitDivCount div LongUsesCount),AllAcceptSpecs.AllAcceptResult[0].Counts);
AllAcceptSpecs.IfAccept:=True;
exit;
end;
end;
end.