Hi,
We are using the following code to add items to a Vault BOM. However, when we look at the Bill of Materials tab in Vault, the DetailID column is blank. We understand that we cannot set the DetailID to a particular value, but we expected it to be auto-populated by Vault.
//==========================================================================================
private bool AddItemToBOM(string assemblyNumber, string itemNumber, int qty)
{
// Note: assemblyNumber and itemNumber have already been verified to be in Vault.
bool success = true, completed = false;
Item itemToAdd = null, parentAssembly = null, existingItem;
string errorMessage = "";
// Get the Item and Assembly objects for the item and assembly numbers passed in.
try
{
itemToAdd = mgr.ItemService.GetLatestItemByItemNumber(itemNumber);
parentAssembly = mgr.ItemService.GetLatestItemByItemNumber(assemblyNumber);
}
catch (Exception e)
{
success = false; // unexpected error.
errorMessage = e.Message;
}
if (success == true) // We have the Item and Assembly objects.
{
//wB added
ItemBOM bom = mgr.ItemService.GetItemBOMByItemIdAndDate(parentAssembly.Id,
System.DateTime.Today, BOMTyp.Tip, BOMViewEditOptions.Defaults);
Item[] itemRevArray = bom.ItemRevArray;
int numberOfItems = itemRevArray.Length; // # of Items currently in parent Assembly BOM.
ItemAssoc[] itemAssocArray = bom.ItemAssocArray; // This array is needed for the item quantity.
//create an array of Ids (longs) using the number of Items in the array
long[] childIds = new long[numberOfItems];
double[] quantities = new double[numberOfItems];
bool[] isStatic = new bool[numberOfItems];
int[] locationInBOM = new int[numberOfItems];
for (int i = 0; i < numberOfItems; i++)
{
// Check if the Item being added is already there.
if (itemToAdd.Id == itemRevArray[i].Id)
{
// The Item being added is already in the BOM (this won't happen if the BOM was initially empty).
i = numberOfItems; // Cancel out of loop; we are done.
success = true;
completed = true;
MessageBox.Show("Note: Item " + itemNumber + " is already in the BOM for Item " + assemblyNumber);
break; // Cancel out of loop; we are done.
}
if (parentAssembly.Id == itemRevArray[i].Id)
{
// Here is a good place to insert the new Item to add; the ItemRevArray includes an
// extra value containing the parent item number; it is not really a BOM Item.
// So, replace the parent Id with the id of the item to add.
childIds[i] = itemToAdd.Id;
quantities[i] = qty;
isStatic[i] = true;
locationInBOM[i] = numberOfItems;
}
else
{
// This is one of the existing BOM Items; add the Id to the array, and make sure the quantity is right.
existingItem = itemRevArray[i];
childIds[i] = existingItem.Id;
// I don't think that I can use the same array index i for the itemAssocArray to get the quantities.
// The arrays are not in the same order.
// Use Linq to get the quantity from the itemAssocArray array item.
var result = from item in itemRevArray
where itemAssocArray != null && item.Id == existingItem.Id
join a in itemAssocArray on item.Id equals a.CldItemID
select new
{
item.Id,
item.ItemNum,
item.Detail,
item.Title,
a.BOMOrder,
Qty = a.CldItemUsage,
AssocId = a.Id,
};
foreach (var component in result) // Should only be one record here.
{
quantities[i] = component.Qty;
}
//quantities[i] = itemAssocArray[i].CldItemUsage; // Re-add the item quantity back in.
//quantities[i] = 1; // Re-add the item quantity back in.
isStatic[i] = true;
locationInBOM[i] = i+1; // Keep current position.
}
}
if (completed != true)
{
Item EditParent = default(Item);
try
{
// Put the parent assembly into Edit mode to add the item to the BOM.
EditParent = mgr.ItemService.EditItem(parentAssembly.RevId);
// Do the actual adding.
ItemBOM BOM = mgr.ItemService.UpdateItemBOMAssociations(EditParent.Id, childIds, quantities,
isStatic, locationInBOM, BOMViewEditOptions.Defaults);
// Commit the assembly, which finalizes the changes.
mgr.ItemService.UpdateAndCommitItem(EditParent, 0, false, null, null, null, null, null, null, numberOfItems);
}
catch (Exception e)
{
success = false;
errorMessage = e.Message;
if ((EditParent != null))
{
// If the parent assembly is in Edit mode, take it out.
mgr.ItemService.UndoEditItems(new long[] { EditParent.Id });
}
}
}
}
if (success == false)
{
MessageBox.Show("An error occurred adding the item " + itemNumber + " to the BOM.\n\n" +
"Message:\n" + errorMessage);
}
return success;
}
There is no way to set the DetailId through the ItemService. The only way to set detail ID, is through a file that gets assigned to an item. For more information on how file data relates to BOM data, see the article on the BOM Pipeline.