2.Where-used (Top Where-used) / 用途(父件产品及顶层产品)
Where-used一般用于查询物料的用途,即在哪些BOM中用到了该物料。而Top Where-used则用于查询该物料所用于的最终产品信息。在制造业中,这些都是非常有用的资料,比如在一个ECN中需要更改一个物料,那么通过Top Where-used即可以马上知道这个ECN会影响到哪些产品。
在Where-used的算法中,关键是是否要考虑BOM的版本,以及生效/失效日期等。
以下是一个经典的Where-used (Top Where-used) 的示例程序。其中用到了Container来储存信息,其实用数据表(Table) 也是同样可以的。
void Whereused(sourceItemId, bomDate = today())
{
BOM BOM_A, BOM_B;
BOMVersion bomVersion;
Set tmpContainer, tmpWhereusedItems, tmpWhereusedTopItems;
SetEnumerator se;
ItemId tmpItemId;
;
// Initialization
tmpContainer = new Set(Types::String);
tmpWhereusedItems = new Set(Types::String);
tmpWhereusedTopItems = new Set(Types::String);
// Get all the active boms
while select BOM_A
where BOM_A.ItemId == sourceItemId
&& (!BOM_A.ToDate || BOM_A.ToDate >= bomDate)
&& (!BOM_A.FromDate || BOM_A.FromDate <= bomDate)
{
select firstonly bomVersion
where bomVersion.BOMId == BOM_A.BOMId
&& bomVersion.Active == true
&& bomVersion.Approved == true
&& (!bomVersion.FromDate || bomVersion.FromDate <= bomDate)
&& (!bomVersion.ToDate || bomVersion.ToDate >= bomDate);
if (bomVersion
&& (!tmpWhereusedItems.in(bomVersion.ItemId)
&& !tmpContainer.in(bomVersion.ItemId)))
{
tmpContainer.add(bomVersion.ItemId);
}
}
//loop the program while the temporary container have ItemId
se = tmpContainer.getEnumerator();
while (!tmpContainer.empty())
{
// get the first one
se.moveNext();
tmpItemId = se.current();
// remove -> reduce the element count
tmpContainer.remove(tmpItemId);
tmpWhereusedItems.add(tmpItemId);
se.reset();
select firstonly BOM_B
where BOM_B.ItemId == tmpItemId
&& (!BOM_B.ToDate || BOM_B.ToDate >= bomDate)
&& (!BOM_B.FromDate || BOM_B.FromDate <= bomDate);
if (BOM_B) //if the tmpItemId is still used in other boms
{
//get all ItemIds which consists the tmpItemId
while select BOM_B
where BOM_B.ItemId == tmpItemId
&& (!BOM_B.ToDate || BOM_B.ToDate >= bomDate)
&& (!BOM_B.FromDate || BOM_B.FromDate <= bomDate)
{
select firstonly bomVersion
where bomVersion.BOMId == BOM_B.BOMId
&& bomVersion.Active == true
&& bomVersion.Approved == true
&& (!bomVersion.FromDate || bomVersion.FromDate <= bomDate)
&& (!bomVersion.ToDate || bomVersion.ToDate >= bomDate);
if (bomVersion
&& (!tmpWhereusedItems.in(bomVersion.ItemId)
&& !tmpContainer.in(bomVersion.ItemId)))
{
// for SET, there will ensure no duplication
tmpContainer.add(bomVersion.ItemId);
}
}
}
else // if the tmpItemId is not used in other boms, this is the topest layer ItemId
{
select firstonly bomVersion
where bomVersion.ItemId == tmpItemId
&& bomVersion.Active == true
&& bomVersion.Approved == true
&& (!bomVersion.FromDate || bomVersion.FromDate <= bomDate)
&& (!bomVersion.ToDate || bomVersion.ToDate >= bomDate);
if (bomVersion)
{
// get the ItemId, and put it to another container
{
tmpWhereusedTopItems.add(tmpItemId);
}
}
}
}
}