用TreeView 控件构造BOM
李宏 徐利红
--- TreeView 是VB 中的一个控件,位于MSCOMCTL32。OCX 文件中,用于显示 Node 对象的等级体系结构,适合于表达具有层次结构的信息,如磁盘上的文件和目录、公司结构图等。
---- BOM 是Bill of Material 的缩写,称为材料清单,是MRP II的几个基本文件之一,它将一个产品层层分解,直至最底层的外购零件,具有良好的层次结构.例如电脑整机,对其生产商而言,首先可将其分解为显示器、主机、键盘、鼠标、电源线等,主机又可分解为机箱、主机板、CPU、内存、显示卡、软驱、光驱等几部分。如何将这种结构清晰地表达出来,对于产生、维护BOM 有重大的帮助。从前面对TreeView的介绍可以看出, 它用于此是合适的。
---- 下面举例说明如何通过拖动由零件料号直接在TreeView中构造BOM。
---- 本例中主要使用一个List 控件、一个Label 控件和一个TreeView 控件。List控件中有建立此BOM 所需的料号。TreeView 控件用于显示构造的BOM,最初为空,Label 控件用于拖动过程,表示所选的料号。本例通过将List控件中的料号拖到TreeView 中建立BOM。其主要代码如下。图中用向右指的箭头表示当前正在增加子件的料号,TreeView 中料号后的X1 表示其单位用量为1。
---- ‘以下二窗体变量用于确定拖动的来源, 保证在TreeView1 内的拖动无效
Dim bool_ListDrag As Boolean ‘
Dim bool_TreeDrag As Boolean
Private Sub Form_Load()
‘产生ListBox 中的内容
For i = 0 To 25
List1.AddItem Chr(65 + i) & Chr(65 + i)
Next i ‘
初始化设置
bool_ListDrag = False
bool_TreeDrag = False
End Sub
Private Sub Form_MouseUp(Button As Integer,
Shift As Integer, X As Single, Y As Single)
bool_ListDrag = False
End Sub
‘在List1 中选取要拖动的料号
Private Sub List1_MouseDown(Button As Integer,
Shift As Integer, X As Single, Y As Single)
Dim DY
DY = TextHeight("A") 注释: 获得列表框中一行的高度
Label1.Move List1.Left, List1.Top + Y - DY / 2,
List1.Width, DY
Label1.Drag 注释: 实际拖动的是Label1
bool_ListDrag = True
End Sub
‘将拖动的料号放在TreeView 对应的动作
Private Sub TreeView1_DragDrop(Source As Control,
X As Single, Y As Single)
Dim oNodex As Node
Dim skey As String
Dim iIndex As Integer
On Error GoTo myerr
‘只接受来自List1 的拖动
If bool_TreeDrag = True Then
bool_TreeDrag = False
Exit Sub
End If
If bool_ListDrag = True Then
‘取得一个键值
skey = GetNextKey() ‘为新增节点产生键值
注释:如TreeView1中有料号被选中,则新拖入的料号为其子件,
注释:否则本句出错程序至myerr 处,新拖入
的料号加在同一阶的最后
iIndex = TreeView1.SelectedItem.Index
skey = GetNextKey() 注释: 为新增节点产生键值
Set oNodex = TreeView1.Nodes.Add(iIndex,
tvwChild,
skey, List1.Text & " X1", 2, 1) ’新增节点
oNodex.EnsureVisible 注释:确保新增节点可见
Exit Sub
myerr:
TreeView1.Nodes.Add , tvwLast, skey,
List1.Text
& " X1", 2, 1 ’新增节点加在最后
End If
End Sub
‘为新增节点产生一个键值,其初始值为1_,
以后的值依次加1
Private Function GetNextKey() As String
Dim sNewKey As String
Dim iHold As Integer
Dim i As Integer
On Error GoTo myerr
iHold = Val(TreeView1.Nodes(1).Key)
For i = 1 To TreeView1.Nodes.Count
If Val(TreeView1.Nodes(i).Key) > iHold Then
iHold = Val(TreeView1.Nodes(i).Key)
End If
Next
iHold = iHold + 1
sNewKey = CStr(iHold) & "_"
GetNextKey = sNewKey
Exit Function
myerr:
注释:当TreeView 为空时,返回值为1_
GetNextKey = "1_"
Exit Function
End Function
‘在TreeView 中按下鼠标键时对应的动作
Private Sub TreeView1_MouseDown(Button As Integer,
Shift As Integer, X As Single, Y As Single)
‘左键选择料号
If Button = vbLeftButton Then
Set TreeView1.DropHighlight
= TreeView1.HitTest(X, Y)
If Not TreeView1.DropHighlight Is Nothing Then
TreeView1.SelectedItem
= TreeView1.HitTest(X, Y)
End If
Set TreeView1.DropHighlight = Nothing
bool_TreeDrag = True
End If
End Sub
---- 以上程序使用VB6.0编写,在pentium 166 机器上通过。
---- 本文仅涉及了BOM 构造的手段,在实际构造中还有许多问题要考虑,如单位用量的输入、错误的修正、结果的存储,在这里不一并给出。