📄 mmps.cpp
字号:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "mMps.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
TsdMrp *sdMrp;
//---------------------------------------------------------------------------
__fastcall TsdMrp::TsdMrp()
:TsdCustomMidBase()
{
}
//---------------------------------------------------------------------------
void __fastcall TsdMrp::ValidHeadValues()
{
}
//---------------------------------------------------------------------------
void __fastcall TsdMrp::CmdExec(AnsiString Param)
{
GenMrp(Param);
}
//---------------------------------------------------------------------------
void __fastcall TsdMrp::DeCodeParam(AnsiString sParam)
{
AnsiString tmp,sPlanner,sIsSupply,sBalance,sFlag;
int iLen,iPos;
if(sParam == NULL)
throw Exception("计划参数不能为空");
tmp=sParam;
iLen=sParam.Length();
sFlag=tmp.SubString(1,1); //截取首字符做为分割符
tmp=tmp.SubString(2,iLen-1);
iLen=tmp.Length();
iPos=tmp.AnsiPos(sFlag);
if(iPos == 0)
sPlanner="";
else
sPlanner=tmp.SubString(1,iPos-1);
tmp=tmp.SubString(iPos+1,iLen-iPos);
iLen=tmp.Length();
iPos=tmp.AnsiPos(sFlag);
if(iPos == 0)
IsSupply=true;
else
{
sIsSupply=tmp.SubString(1,iPos-1);
if(sIsSupply == "1")
IsSupply=true;
else
IsSupply=false;
}
tmp=tmp.SubString(iPos+1,iLen-iPos);
iLen=tmp.Length();
iPos=tmp.AnsiPos(sFlag);
if(iPos == 0)
bBalance=true;
else
{
sBalance=tmp.SubString(1,iPos-1);
if(sBalance == "1")
bBalance=true;
else
bBalance=false;
}
}
//---------------------------------------------------------------------------
void __fastcall TsdMrp::GenMrp(AnsiString FPlanner)
{
int TierCounter,MaxTier;
TADOQuery *MrpQuery=new TADOQuery(Application);
MrpQuery->Connection=Connection;
TADOQuery *BomQuery=new TADOQuery(Application);
BomQuery->Connection=Connection;
struct LinkRec * BufferHead; //缓冲区链头指针
struct LinkRec * QueueHead; //物料层次队列头指针
struct LinkRec * OldHead; //上层物料队列头指针
BufferHead=NULL;
QueueHead=NULL;
OldHead=NULL;
//分解传入的参数字串
// DeCodeParam(FPlanner);
//计划校验
PlanValidate();
//初试化物料需求缓冲区
BufferInit(&BufferHead);
//读取最大的物料低层码
/* MrpQuery->Close();
MrpQuery->SQL->Clear();
MrpQuery->SQL->Add("select Max(GoodsLlc) MaxTier from sdGoods ");
MrpQuery->Open();
if(MrpQuery->RecordCount < 1)
{
delete MrpQuery;
throw Exception("物料基本资料的低层码无效");
}
MaxTier=MrpQuery->FieldValues["MaxTier"]; //最大的物料低层码
MrpQuery->Close(); */
//清空原MRP计划数据
ClearMrp();
//计算物料供应
//if(IsSupply)
PlanIn(); // SdMrp_CaleSupply
//按层次分解产品BOM,计算MRP需求
/// for(TierCounter=0;TierCounter <= MaxTier;TierCounter++)
// {
//将缓冲区内低层码等于TierCounter的物料入队列
BufferToQueue(TierCounter,&BufferHead,&QueueHead);
// if(QueueHead == NULL)
//{
//队列为空,该层物料无需求,继续下层计算
// continue;
// }
struct LinkRec * tmp;
tmp=QueueHead;
while(tmp != NULL)
{
if(tmp->Rec->LowLevel == TierCounter)
{
//计算队列所有低层码等于TierCounter的物料毛需求
PlanGross(tmp->Rec->Code,tmp->Rec->ReqDate,tmp->Rec->ReqQty);
}
tmp=tmp->Next;
}
AnsiString sql;
OldHead=QueueHead;
QueueHead=NULL;
tmp=OldHead;
//计算队列低层码等于当前TierCounter物料的净需求
while(tmp != NULL)
{
if(tmp->Rec->LowLevel == TierCounter)
{
struct LinkRec * tmp2;
bool Flag;
tmp2=OldHead;
Flag=false;
while(tmp2 != tmp) //判断该物料是否已经做了计算
{
if(UpperCase(tmp2->Rec->Code) == UpperCase(tmp->Rec->Code))
{
Flag=true;
break;
}
tmp2=tmp2->Next;
}
if(Flag == false) //该物料之前没有计算净需求
{
//计算净需求 sdmrp_CaleNet
PlanNet(tmp->Rec->Code);
//平衡物料需求
if(bBalance == true)
BalanceMrp(tmp->Rec->Code);
if(tmp->Rec->From == 2) //该物料是制造件,将其BOM结构中下一层的物料入队列
{
sql =" select MrpdRDate,MrpdQty from sdMrpd,sdGoods where MrpdGoods=GoodsCode ";
sql+=" and mrpdType=6 and MrpdQty>0 and MrpdGoods='"+tmp->Rec->Code+"'";
MrpQuery->Close();
MrpQuery->SQL->Clear();
MrpQuery->SQL->Add(sql);
MrpQuery->Open();
if(MrpQuery->RecordCount >0)
{
sql =" select BomdGoods,GoodsFrom,BomdShl,BomdQty,GoodsLlc from sdBomd,sdGoods where BomdGoods=GoodsCode ";
sql+=" and BomdPgoods='"+tmp->Rec->Code+"' order by BomdSn";
BomQuery->Close();
BomQuery->SQL->Clear();
BomQuery->SQL->Add(sql);
BomQuery->Open();
MrpQuery->First();
while(!MrpQuery->Eof)
{
double MrpdQty;
MrpdQty=MrpQuery->FieldValues["MrpdQty"];
BomQuery->First();
while(!BomQuery->Eof)
{
double BomdQty,BomdShl;
struct GoodsRec NewRec;
BomdQty=BomQuery->FieldValues["BomdQty"];
BomdShl=BomQuery->FieldValues["BomdShl"];
//下层物料毛需求=上层物料计划下达数量*定额消耗*(1+损耗率)
BomdQty=MrpdQty*BomdQty*(1+BomdShl);
NewRec.Code=BomQuery->FieldValues["BomdGoods"];
NewRec.ReqQty=BomdQty;
NewRec.ReqDate=MrpQuery->FieldValues["MrpdRDate"];
NewRec.From=BomQuery->FieldValues["GoodsFrom"];
NewRec.LowLevel=BomQuery->FieldValues["GoodsLlc"];
//将下层物料记录重新入队列
LinkAddRec(NewRec,&QueueHead);
BomQuery->Next();
}
MrpQuery->Next();
}// of while
BomQuery->Close();
MrpQuery->Close();
}// of if(MrpQuery->RecordCount >0)
} //if if(tmp->Rec->From == 2)
} // of if(flag ==false)
}
else
{
if(tmp->Rec->LowLevel > TierCounter) //低层码大于当前TierCounter,入缓冲
{
struct GoodsRec tmpRec2;
tmpRec2.Code=tmp->Rec->Code;
tmpRec2.ReqDate=tmp->Rec->ReqDate;
tmpRec2.ReqQty=tmp->Rec->ReqQty;
tmpRec2.LowLevel=tmp->Rec->LowLevel;
tmpRec2.From=tmp->Rec->From;
LinkAddRec(tmpRec2,&BufferHead);
// tmp->Rec=NULL;
}
else //下层物料低层码不能小于上层物料低层码
{
AnsiString tmpcode;
tmpcode=tmp->Rec->Code;
DestroyLink(OldHead);
DestroyLink(QueueHead);
DestroyLink(BufferHead);
delete MrpQuery;
delete BomQuery;
throw Exception("物料<"+tmpcode+">低层码错误");
}
}//of else
tmp=tmp->Next;
}// of while
DestroyLink(OldHead); //释放原队列空间
} //of for
DestroyLink(BufferHead);
DestroyLink(QueueHead);
delete MrpQuery;
delete BomQuery;
}
//---------------------------------------------------------------------------
//计划计算之前的相关数据校验
void __fastcall TsdMrp::PlanValidate()
{
AnsiString RstStr,SqlStr;
int PeriodType,PeriodLen,MrpFrom;
TADOQuery *McrQuery;
McrQuery=new TADOQuery(Application);
McrQuery->Connection=Connection;
McrQuery->Close();
McrQuery->SQL->Clear();
McrQuery->SQL->Add("select parametervalue from sdParameter where Parametercode='10911'");
McrQuery->Open();
if(McrQuery->RecordCount<=0)
{
McrQuery->Close();
delete McrQuery;
throw Exception("系统计划周期类型参数被破坏");
}
RstStr=McrQuery->FieldValues["ParameterValue"];
McrQuery->Close();
if(RstStr.IsEmpty())
{
delete McrQuery;
throw Exception("系统计划周期类型值出错!");
}
PeriodType=RstStr.ToInt();
McrQuery->SQL->Clear();
McrQuery->SQL->Add("select parametervalue from sdParameter where Parametercode='10901'");
McrQuery->Open();
if(McrQuery->RecordCount<=0)
{
McrQuery->Close();
delete McrQuery;
throw Exception("系统计划展望期参数被破坏");
}
RstStr=McrQuery->FieldValues["ParameterValue"];
McrQuery->Close();
if(RstStr.IsEmpty())
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -