Sapass

 Simplify SAP R/3 development with Excel VBA/VB RFC  
Home> Design>Design/Code of BomProcessor



Index

Design/Code of BomProcessor

We will check the design and function of BomProcessor.
BomProcessor contains following class, module and forms.
Class
BomSheet
CsapMatBom
Module
Main
Forms
BomHelp

16-Nov-2005


1. BomSheet class - General

Class: BomSheet contains 1 property with 9 methods. The BomSheet class is for manipulating the worksheet that users are going to work on. Like creating new set of worksheet with template or transfer the worksheet data to the function module structure.
VERSION 1.0 CLASS
BEGIN
  MultiUse = -1 'True
END
Attribute VB_Name = "BomSheet"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit

Public Ss As Worksheet

Function ReadHeadText(Optional NameList As Object) As Object
Dim varRow As Variant
Set NameList = New Collection
Set ReadHeadText = New Collection
For Each varRow In ThisWorkbook.Sheets("Head").Rows
   If varRow.Row > 1 Then
      If varRow.Columns(1) = "" Then Exit For
      ReadHeadText.Add varRow.Row - 1, varRow.Columns(1).Value
      NameList.Add varRow.Columns(1).Value
   End If
   DoEvents
Next
End Function

Sub CreateNew()
Dim objDd03p As Object
Dim lngIdx As Long
Dim varRow As Variant
Const lngStartColumn = 1

If ActiveWorkbook Is Nothing Then Workbooks.Add
Set Ss = ActiveWorkbook.Sheets.Add
For Each varRow In ThisWorkbook.Sheets("Head").Rows
   If varRow.Row > 1 Then
      If varRow.Columns(1) = "" Then Exit For
      With Ss.Cells(1, lngStartColumn + lngIdx)
         .Value = varRow.Columns(1)
         .ColumnWidth = varRow.Columns(2)
         .Interior.ColorIndex = varRow.Columns(1).Interior.ColorIndex
         .Font.Color = varRow.Columns(1).Font.Color
         .Orientation = 90
         .HorizontalAlignment = xlCenter
      End With
      lngIdx = lngIdx + 1
   End If
   DoEvents
Next

End Sub

Sub DownLoad(Conn As Object)
Dim rngParent As Range
Dim colParents As New Collection
Dim varDummy As Variant
Dim varStpoLine As Variant
Dim varDepData As Variant
Dim objCsapMatBom As CsapMatBom
Dim objStpo As Object
Dim objStko As Object
Dim objDepOrder As Object
Dim lngRow As Long
Dim lngIdx1 As Long
Dim strDep As String
Dim strPlant As String
Dim objHead As Object
Dim varField As Variant
Dim strUsage As String

lngRow = 2
On Error Resume Next
Set rngParent = Application.InputBox(prompt:="BOM Parent", Type:=8)
For Each varDummy In rngParent
   colParents.Add varDummy.Value, varDummy.Value
Next
If colParents.Count = 0 Then Exit Sub
On Error GoTo 0

Set objHead = ReadHeadText
strPlant = CommandBars("Sapass").Controls("Sapass").Controls("Bom").Controls("Plant").Text
strUsage = CommandBars("Sapass").Controls("Sapass").Controls("Bom").Controls("Usage").Text

For Each varDummy In colParents
   Set objCsapMatBom = New CsapMatBom
   With objCsapMatBom
      Set .Conn = Conn
      .Material = varDummy
      .Plant = strPlant
      .BomUsage = strUsage
   End With
   If objCsapMatBom.Read(EStpo:=objStpo, EStko:=objStko, EDepOrder:=objDepOrder) = vbOK Then
      
      For Each varStpoLine In objStpo.Rows
         Ss.Cells(lngRow, objHead("MATERIAL")) = UCase(varDummy)
         Ss.Cells(lngRow, objHead("VALID_FROM")) = ""
         
         On Error Resume Next
         For Each varField In objStpo.Columns
            Debug.Print varField.Name
            Ss.Cells(lngRow, objHead(varField.Name)) = varStpoLine(varField.Name)
            DoEvents
         Next
         On Error GoTo 0
         
         strDep = ""
         For Each varDepData In objDepOrder.Rows
            If varDepData("ITEM_NODE") = varStpoLine("ITEM_NODE") Then
               strDep = strDep & varDepData("DEP_INTERN") & "=" & varDepData("DEP_LINENO") & ";"
            End If
            DoEvents
         Next
         Ss.Cells(lngRow, objHead("DEPDATA")) = strDep
         lngRow = lngRow + 1
         DoEvents
      Next
   Else
      Ss.Cells(lngRow, objHead("MESSAGE")) = "BOM cannot be found"
   End If
   DoEvents
Next

End Sub

Sub ExecuteUpdate(Conn As Object)

Dim rngParent As Range
Dim colRows As New Collection
Dim varRow As Variant
Dim varDummy As Variant
Dim objCsapMatBom As CsapMatBom
Dim varStpoLine As Variant
Dim varDepLine As Variant
Dim varDepSplit As Variant
Dim lngIdx1 As Long
Dim objStpo As Object
Dim objStko As Object
Dim objDepOrder As Object
Dim objDepData As Object
Dim bolStpoFound As Boolean
Dim bolDepFound As Boolean
Dim lngResult As Long
Dim strBomNo As String
Dim objHead As Object
Dim strPlant As String
Dim strChangeNo As String
Dim colProcess As Object
Dim strUsage As String
On Error Resume Next
Set rngParent = Application.InputBox(prompt:="BOM Parent", Type:=8)
If rngParent Is Nothing Then Exit Sub
For Each varDummy In rngParent
   colRows.Add varDummy.Row, CStr(varDummy.Row)
Next
'And add one dummy object for process everything completely.
colRows.Add 65535, "65535"
On Error GoTo 0

Set objCsapMatBom = New CsapMatBom
Set objCsapMatBom.Conn = Conn
Set objHead = ReadHeadText
With CommandBars("Sapass").Controls("Sapass").Controls("Bom")
   strPlant = .Controls("Plant").Text
   strChangeNo = .Controls("ChgNo").Text
   strUsage = .Controls("Usage").Text
End With
If strChangeNo = "" Then MsgBox "Specify Change Number": Exit Sub

For Each varRow In colRows
   'Check if the current line is same as previous
   With objCsapMatBom
      If .Material = UCase(Ss.Cells(varRow, 1).Value) And _
         .Plant = strPlant And _
         .BomUsage = strUsage Then
      Else
         'Check if this is first loop, if not execute change
         If .Material <> "" Then
            If .Maintain(IStpo:=objStpo, IStko:=objStko, IDepData:=objDepData, IDepOrder:=objDepOrder) <> vbOK Then Exit Sub
         End If
         Set colProcess = New Collection
         Set objCsapMatBom = New CsapMatBom
         Set objCsapMatBom.Conn = Conn
         objCsapMatBom.Material = Ss.Cells(varRow, objHead("MATERIAL")).Value
         objCsapMatBom.Plant = strPlant
         objCsapMatBom.BomUsage = strUsage
         objCsapMatBom.ChangeNo = strChangeNo
         'Read BOM if it exists
         If .Read(EStpo:=objStpo, EStko:=objStko, EDepData:=objDepData, EDepOrder:=objDepOrder) = vbOK Then
         Else
            'Create Header Record in order to create BOM.
            lngResult = AddStko(objStko)
         End If
         .ChangeNo = strChangeNo
         'Exit if reaches to the last one
         If varRow = 65535 Then Exit For
      End If
   End With
   '
   bolStpoFound = False
   For Each varStpoLine In objStpo.Rows
      strBomNo = varStpoLine("BOM_NO")
      If Ss.Cells(varRow, objHead("ITEM_NO")).Value <> "" And CStr(Ss.Cells(varRow, objHead("ITEM_NO")).Value) <> varStpoLine("ITEM_NO") Then
         GoTo NEXTLOOP:
      Else
         If Ss.Cells(varRow, objHead("COMPONENT")).Value <> "" And CStr(Ss.Cells(varRow, objHead("COMPONENT")).Value) <> varStpoLine("COMPONENT") Then
            GoTo NEXTLOOP:
         ElseIf Ss.Cells(varRow, objHead("COMPONENT")).Value = "" And CStr(Ss.Cells(varRow, objHead("ITEM_TEXT1")).Value) <> varStpoLine("ITEM_TEXT1") Then
            GoTo NEXTLOOP:
         End If
      End If
      'Now identified the entry
      bolStpoFound = True
      varStpoLine("IDENTIFIER") = varRow
      lngResult = ModifyStpo(varStpoLine, CLng(varRow))
      
      'Then Dependency
      If Ss.Cells(varRow, objHead("DEPDATA")).Value = "" Then GoTo NEXTLOOP
      varDepSplit = Split(Ss.Cells(varRow, objHead("DEPDATA")), ";")
      For lngIdx1 = 0 To UBound(varDepSplit)
         bolDepFound = False
         For Each varDepLine In objDepData.Rows
            If varDepSplit(lngIdx1) Like varDepLine("DEP_INTERN") & "=*" And _
               varStpoLine("BOM_NO") = varDepLine("BOM_NO") And _
               varStpoLine("ITEM_NODE") = varDepLine("ITEM_NODE") Then
               bolDepFound = True
               lngResult = ModifyDependency(varStpoLine, CStr(varDepSplit(lngIdx1)), varDepLine, objDepOrder.Rows(varDepLine.Index), CLng(varRow))
               Exit For
            End If
            DoEvents
         Next
         If bolDepFound = False Then
            lngResult = AddDependency(varStpoLine, CStr(varDepSplit(lngIdx1)), objDepData, objDepOrder, CLng(varRow))
         End If
         DoEvents
      Next
NEXTLOOP:
      DoEvents
   Next
   
   'If the item is new
   If bolStpoFound = False Then
      'Add STPO line
      lngResult = AddStpo(objStpo, CLng(varRow), strBomNo)
      Set varStpoLine = objStpo.Rows(objStpo.RowCount)
      'Add Dependency and its order line
      varDepSplit = Split(Ss.Cells(varRow, objHead("DEPDATA")), ";")
      For lngIdx1 = 0 To UBound(varDepSplit)
         lngResult = AddDependency(varStpoLine, CStr(varDepSplit(lngIdx1)), objDepData, objDepOrder, CLng(varRow))
      Next
   End If
   DoEvents
Next

End Sub

Function AddStko(Stko As Object) As Long
With Stko
   .FreeTable
   .Rows.Add
   Stko(.RowCount, "BASE_QUAN") = 1
   Stko(.RowCount, "BASE_UNIT") = "EA"
   Stko(.RowCount, "BOM_STATUS") = CommandBars("Sapass").Controls("Sapass").Controls("Bom").Controls("Usage").Text
End With
End Function

Function AddStpo(Stpo As Object, CurrentRow As Long, BomNo As String) As Long
Dim varStpoLine As Variant
Dim lngResult As Long
Stpo.Rows.Add
Set varStpoLine = Stpo.Rows(Stpo.RowCount)
varStpoLine("BOM_NO") = BomNo
lngResult = ModifyStpo(varStpoLine, CurrentRow)
If varStpoLine("ITEM_NO") = "" Then
   '
End If
End Function

Function ModifyStpo(StpoLine As Variant, CurrentRow As Long) As Long
Dim lngIdx1 As Long
Dim lngMaxColumn As Long
Dim bolNoChange As Boolean
Dim objStpoLine As Object
Dim strField As String
Dim strValue As String

bolNoChange = True
lngMaxColumn = Ss.Cells(1, 1).End(xlToRight).Column - 1
Set objStpoLine = StpoLine
For lngIdx1 = 3 To lngMaxColumn
   strField = Ss.Cells(1, lngIdx1).Value
   strValue = Ss.Cells(CurrentRow, lngIdx1).Value
   If strValue <> "" Then
      If strValue = "!" Then
         StpoLine(strField) = ""
         bolNoChange = False
      Else
         If IsNumeric(strValue) Then
            If Val(StpoLine(strField)) <> Val(strValue) Then
               StpoLine(strField) = strValue
               bolNoChange = False
            End If
         ElseIf Trim(StpoLine(strField)) <> Trim(CStr(strValue)) Then
            StpoLine(strField) = UCase(strValue)
            bolNoChange = False
         End If
      End If
   End If
   DoEvents
Next

If bolNoChange = True Then Set StpoLine = objStpoLine: Exit Function 'No Change

StpoLine("IDENTIFIER") = CurrentRow
StpoLine("CHANGE_NO") = CommandBars("Sapass").Controls("Sapass").Controls("Bom").Controls("ChgNo").Text

End Function

Function AddDependency(StpoLine As Variant, DepString As String, DepData As Object, DepOrder As Object, CurrentRow As Long) As Long
Dim varDepDataLine As Variant
Dim varDepOrderLine As Variant
Dim lngResult As Long

If DepString = "" Then Exit Function
'Dependency Data
DepData.Rows.Add
Set varDepDataLine = DepData.Rows(DepData.RowCount)
'Dependency Order
DepOrder.Rows.Add
Set varDepOrderLine = DepOrder.Rows(DepData.RowCount)
'Put fields contents
lngResult = ModifyDependency(StpoLine, DepString, varDepDataLine, varDepOrderLine, CurrentRow)
End Function

Function ModifyDependency(StpoLine As Variant, DepString As String, DepDataLine As Variant, DepOrderLine As Variant, CurrentRow As Long) As Long
Dim varDepItem As Variant
Dim bolNoChange As Boolean
Dim objDepData As Object
Dim objDepOrder As Object

bolNoChange = True

Set objDepData = DepDataLine
Set objDepOrder = DepOrderLine

'Dependency Data
If InStr(DepString, "=") = 0 Then DepString = DepString & "=0000"
varDepItem = Split(DepString, "=")
DepDataLine("OBJECT_ID") = "2"
If DepDataLine("DEP_INTERN") <> varDepItem(0) Then
   DepDataLine("DEP_INTERN") = varDepItem(0)
   bolNoChange = False
End If
DepDataLine("STATUS") = "1"
DepDataLine("BOM_NO") = StpoLine("BOM_NO")
DepDataLine("ITEM_NODE") = StpoLine("ITEM_NODE")
DepDataLine("ITEM_COUNT") = StpoLine("ITEM_COUNT")
If varDepItem(1) = "!" Then
   DepDataLine("FLDELETE") = "X"
End If

'Dependency Order
DepOrderLine("OBJECT_ID") = "2"
If DepOrderLine("DEP_INTERN") <> CStr(varDepItem(0)) Then
   DepOrderLine("DEP_INTERN") = varDepItem(0)
   bolNoChange = False
End If
If varDepItem(1) = "!" Then
   bolNoChange = False
ElseIf Val(DepOrderLine("DEP_LINENO")) <> Val(varDepItem(1)) Then
   DepOrderLine("DEP_LINENO") = varDepItem(1)
   bolNoChange = False
End If
DepOrderLine("BOM_NO") = StpoLine("BOM_NO")
DepOrderLine("ITEM_NODE") = StpoLine("ITEM_NODE")
DepOrderLine("ITEM_COUNT") = StpoLine("ITEM_COUNT")

If bolNoChange = True Then Set DepDataLine = objDepData: Set DepOrderLine = objDepOrder: Exit Function

StpoLine("CHANGE_NO") = CommandBars("Sapass").Controls("Sapass").Controls("Bom").Controls("ChgNo").Text
StpoLine("IDENTIFIER") = CurrentRow
DepDataLine("IDENTIFIER") = CurrentRow
DepOrderLine("IDENTIFIER") = CurrentRow

End Function



16-Nov-2005


1-1. BomSheet class - Properties

Propeties
The class contains 1 property.

Ss
Ss is an input parameter for the class. This will get the worksheet object which sheet to process for BOM download/upload.

08-Dec-2005


1-2. BomSheet class - Methods

Methods
The class contains 9 methods.

ReadHeadText
This BomSheet function requires spread sheet to work on and this function does preparation for creation of the worksheet. It reads Header data information from woksheet "Head" which is hidden in the VBA .xla file and copy returns the field description as collection. Also it returns internal field name as NameList collection object. This function is to be called by Download and Execute update function in this class.
CreateNew
This is the core logic for adding new spread sheet to work on. Refer to the hidden "Head" sheet of the .xla file, create the header row in the created spread sheet. Thus, some of the field needs to be hidden or highlighted with some colors, you can configure them in Head sheet.
Download
This method requires one import parameter for SAP connection and download the BOM from SAP by calling CSAP_MAT_BOM_READ RFC function module. As there is another version of same function in latest version of SAP, it may be better to use the function (CSEP_MAT_BOM_READ) instead of this. This first gets the target ranges for BOM parent through inputbox (it's not inputbox function, but inputbox method. These two are different thing). For the plant and usage parameters, it takes values from the menu bar. Then creates CsapMatBom object and calls Read method of the class. The BOM item information will be returned to the object after the call, loop the BOM item and copy the values to the spread sheet.
ExecuteUpdate
Basically, this takes same steps as Download method does. First of all, this takes target range from the inputbox method. And loop the ranges that user specified, creates the CsapMatBom. In order not to remove/overwrite the fields that users not specified or intended, before it calls BOM change function module, it calls Read method of the class. Based on the loaded BOM, it modifies the necessary entries. These modified entries are passed to SAP through Maintain method which actually calls CSAP_MAT_BOM_MAINTAIN. For performance, if the changes for same BOM parent items will be grouped and does one call.
AddStko
This function is called by ExecuteUpdate procedure. This creates the STKO object (BOM header object) which is required for doing BOM update.
AddStpo
This prepares the parameter STPO (BOM item record) for the CSAP_MAT_BOM_MAINTAIN function. This receives the pointer for the line of the spread sheet currently working on and modify the STPO table entries with the values specified in the line.
ModifyStpo
This function is called in AddStpo function. This updates the STPO records with the specified values.
AddDependency
This function is called in the ExecuteUpdate function. For the configurable BOM, we can allocate dependency rule to the BOM item. This function helps to do for CSAP_MAT_BOM_MAINTAIN.
ModifyDependency
Same as AddStpo and ModifyStpo relation, this method correponsds to AddDependency and updates the entry of dependency rules for CSAP_MAT_BOM_MAINTAIN.

08-Dec-2005


2. CsapMatBom class - General

Class: CsapMatBom class contains 8 property with 2 methods. The CsapMatBom class actually does RFC communication between Excel and SAP. CSAP_MAT_BOM_READ function module is called from Read method and CSAP_MAT_BOM_MAINTAin function module is called from Maintain method.
VERSION 1.0 CLASS
BEGIN
  MultiUse = -1 'True
END
Attribute VB_Name = "CsapMatBom"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit

Public Conn As Object
Public Material As String
Public Plant As String
Public BomUsage As String
Public Alternative As String
Public ValidFrom As String
Public ValidTo As String
Public ChangeNo As String

Function Read(Optional EStpo As Object, Optional EStko As Object, Optional EDepData As Object, Optional EDepOrder As Object) As Long

Dim objRfc As Object
Dim objMaterial As Object
Dim objPlant As Object
Dim objBomUsage As Object
Dim objAlternative As Object
Dim objValidFrom As Object
Dim objValidTo As Object
Dim objChangeNo As Object

Read = vbCancel
Set objRfc = Conn.Add("CSAP_MAT_BOM_READ")
Set objMaterial = objRfc.exports("MATERIAL")
Set objPlant = objRfc.exports("PLANT")
Set objBomUsage = objRfc.exports("BOM_USAGE")
Set objAlternative = objRfc.exports("ALTERNATIVE")
Set objValidFrom = objRfc.exports("VALID_FROM")
Set objValidTo = objRfc.exports("VALID_TO")
Set objChangeNo = objRfc.exports("CHANGE_NO")

objMaterial.Value = UCase(Material)
objPlant.Value = UCase(Plant)
objBomUsage.Value = UCase(BomUsage)
objAlternative.Value = Alternative
objValidFrom.Value = ValidFrom
objValidTo.Value = ValidTo
objChangeNo.Value = ChangeNo

Set EStpo = objRfc.tables("T_STPO")
Set EStko = objRfc.tables("T_STKO")
Set EDepData = objRfc.tables("T_DEP_DATA")
Set EDepOrder = objRfc.tables("T_DEP_ORDER")

EStpo.FreeTable
EStko.FreeTable
EDepData.FreeTable
EDepOrder.FreeTable

If objRfc.Call = False Then Exit Function

Read = vbOK

End Function

Function Maintain(IStpo As Object, IStko As Object, IDepData As Object, IDepOrder As Object) As Long

Dim objRfc As Object
Dim objMaterial As Object
Dim objPlant As Object
Dim objBomUsage As Object
Dim objAlternative As Object
Dim objValidFrom As Object
Dim objChangeNo As Object
Dim objStko As Object
Dim objFlNewItem As Object
Dim objFlBomCreate As Object
Dim Stko As Object
Dim Stpo As Object
Dim DepData As Object
Dim DepOrder As Object
Dim lngCount As Long
Dim varRow As Variant
'Dim ColumnName

Maintain = vbCancel
Set objRfc = Conn.Add("CSAP_MAT_BOM_MAINTAIN")
Set objMaterial = objRfc.exports("MATERIAL")
Set objPlant = objRfc.exports("PLANT")
Set objBomUsage = objRfc.exports("BOM_USAGE")
Set objAlternative = objRfc.exports("ALTERNATIVE")
Set objValidFrom = objRfc.exports("VALID_FROM")
Set objChangeNo = objRfc.exports("CHANGE_NO")
Set objFlNewItem = objRfc.exports("FL_NEW_ITEM")
Set objFlBomCreate = objRfc.exports("FL_BOM_CREATE")
objMaterial.Value = UCase(Material)
objPlant.Value = UCase(Plant)
objBomUsage.Value = UCase(BomUsage)
objAlternative.Value = Alternative
objValidFrom.Value = ValidFrom
objChangeNo.Value = ChangeNo
objFlNewItem.Value = "X"
objFlBomCreate.Value = "X"
Set Stko = objRfc.exports("I_STKO")
Set Stpo = objRfc.tables("T_STPO")
Set DepData = objRfc.tables("T_DEP_DATA")
Set DepOrder = objRfc.tables("T_DEP_ORDER")

'STKO
On Error Resume Next
For lngCount = 1 To Stko.ColumnCount
   Stko(Stko.ColumnName(lngCount)) = IStko(1, Stko.ColumnName(lngCount))
   DoEvents
Next
On Error GoTo 0

'STPO
For Each varRow In IStpo.Rows
   Stpo.Rows.Add
   Stpo(Stpo.RowCount, "ID_ITM_CTG") = varRow("ITEM_CATEG")
   Stpo(Stpo.RowCount, "ID_ITEM_NO") = varRow("ITEM_NO")
   Stpo(Stpo.RowCount, "ID_COMP") = varRow("COMPONENT")
   Stpo(Stpo.RowCount, "ID_CLASS") = varRow("CLASS")
   Stpo(Stpo.RowCount, "ID_CL_TYPE") = varRow("CLASS_TYPE")
   Stpo(Stpo.RowCount, "ID_SORT") = varRow("SORTSTRING")
   Stpo(Stpo.RowCount, "ID_GUID") = varRow("ITEM_GUID")
   For lngCount = 1 To IStpo.Columns.Count
      Stpo(Stpo.RowCount, IStpo.ColumnName(lngCount)) = varRow(IStpo.ColumnName(lngCount))
      DoEvents
   Next
   DoEvents
Next

'DEP_DATA
For Each varRow In IDepData.Rows
   DepData.Rows.Add
   For lngCount = 1 To IDepData.Columns.Count
      DepData(DepData.RowCount, IDepData.ColumnName(lngCount)) = varRow(IDepData.ColumnName(lngCount))
      DoEvents
   Next
   DepOrder.Rows.Add
   For lngCount = 1 To IDepOrder.Columns.Count
      DepOrder(DepOrder.RowCount, IDepOrder.ColumnName(lngCount)) = IDepOrder(varRow.Index, IDepOrder.ColumnName(lngCount))
      DoEvents
   Next
   DoEvents
Next

If objRfc.Call = False Then
   MsgBox "NG"
Else
   Maintain = vbOK
End If

Stpo.FreeTable
Stko.Clear
DepData.FreeTable
DepOrder.FreeTable

End Function



09-Dec-2005


2-1. CsapMatBom class - Properties

Propeties
The class contains 8 properties.

Conn
Conn is an input parameter for the class. This will have the SAP RFC connection object. The class will work with the SAP that the connection specifies.
Material
Material is for the Parent material number for the BOM.
Plant
Plant is a plant that parent material is on. If the material is not on specific plant, this can be left as blank.
BomUsage
BomUsage is for the BOM usage of the BOM for read/update.
Alternative
Alternative is for the Alternative of the BOM for read/update.
ValidFrom
This gets the Valid from date for the BOM that you read/update.
ValidTo
This gets the Valid to date. This works only when you read BOM from SAP.
ChangeNo
ChangeNo is a field for the Change number that you can specify when you read/update the BOM. The valid from date for the specified change number will be retrieved and specified when read/update BOM.

28-Dec-2005