(1)可以在产品表加入SMD_ID,DIP_ID,ASSM_ID,PACK_ID分别对应前四个表的关系,再增加SMD_用量,DIP_用量,ASSM_用量,PACK_用量分别对应前四个表的用量.以上设计可以根据产品的库存量(生产量)计算出各原料的用量,再与各原料表对照数量就可以进行查询库存,结余,进货.(2)可以使用join连接,where id=id等关联.(3)关于怎样设计才更合理,可能还是在现场了解最清楚.
调试欢乐多
李宏 徐利红
[请作者提供详细的邮政地址给我们]
---- 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 BooleanPrivate 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 SubPrivate 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 构造的手段,在实际构造中还有许多问题要考虑,如单位用量的输入、错误的修正、结果的存储,在这里不一并给出。
作者:流方 主页:http://liulee.yeah.net 最近收到网友一个问题,关于Oracle的层次查询的问题,发现Oracle 8i中一个非常有用的查询子句:
select level,rowid,...
from ...
where ...
start with ...
connect by expression;
语法说明:
*****************************************************
start with ...
connect by
(这是一个字句,不能拆开来写)
语法的详细参考,请参考 ORACLE Release 8.0.5 Documentation Library中的 SELECT 帮助
文件位置 doc\database.804\a58225\ch4l.htm
简单说明:
start with ... connect by : 建立一个层次查询("Hierarchical Queries")
start with ... 子句:用户根记录的条件
connect by 子句:用于子记录合父记录的连接方式。是一个特定的条件表达式,必须为其中之一:
PRIOR expr comparison_operator expr
expr comparison_operator PRIOR expr 如果定义了start with... connect by子句,level就返回当前记录的层次号。
*****************************************************这个语法通过定义一个cursor或视图就可以得到一个层次型的结果集,非常有用,特别是对于象生产企业的EBOM树的生成而言,
将明显改变BOM树生成的执行效率,因此,我将这个语法的内容做了分析:给定这样的数据:
DOC_PR DOC_CH TITLE
--------- -------------------- -----------------------
DOC A A类
A A2 A-2
A A3 A-3
A A1 A-1
A1 A11 A1-1
DOC B B类
B B1 B-1
B B2 B-2
B B3 B-3
B3 B31 B-3-1
DOC C C类
C C1 test C1
定义一个cursor
Declare curTree Cursor For
select level, doc_ch, title, rowid
from doc_tree
start with doc_pr = 'DOC'
connect by doc_pr = Prior doc_ch;
返回结果集如下:
LEVEL DOC_CH TITLE ROWID
-------- -------------------- ---------------------------------------- ------------------
1 A A类 AAAAi+AADAAAAyNAAE
2 A2 A-2 AAAAi+AADAAAAyNAAM
2 A3 A-3 AAAAi+AADAAAAyNAAN
2 A1 A-1 AAAAi+AADAAAAyNAAP
3 A11 A1-1 AAAAi+AADAAAAyNAAS
1 B B类 AAAAi+AADAAAAyNAAF
2 B1 B-1 AAAAi+AADAAAAyNAAO
2 B2 B-2 AAAAi+AADAAAAyNAAQ
2 B3 B-3 AAAAi+AADAAAAyNAAR
3 B31 B-3-1 AAAAi+AADAAAAyNAAB
1 C C类 AAAAi+AADAAAAyNAAG
2 C1 test C1 AAAAi+AADAAAAyNAAC
这段语法的ORACLE内部逻辑我分析如下:
选择 level,doc_ch,title,rowid
从 doc_tree
以 doc_pr = "DOC"开始
用 doc_pr = 上一个结果的 doc_ch来连接
取出第一个结果集后, as_start自动转换为 当前行的 doc_ch,然后执行
select level, doc_ch, title, rowid
from doc_tree where doc_pr = prior doc_ch
这样循环本层次结果集,然后再开始下一个结果集的处理。
这是内部的逻辑,而返回给用户的是一个按层次完成的结果集
有了这样一个结果集,对于建立treeview是非常方便的,只要循环所有记录就可以轻松实现了。 在Sybase,MS SQL Server中不知有没有这样的语法,我不是太清楚,如果您知道,请告诉我。现在我在MS SQL Server中的实现是这样的:
加入字段level而不是伪列。实现原理同上面是一致的。
---->>>原始材料库1.元材料表SMD
--------------------------------------------------------------------SMD_编号 新料号 品名 单重 总重 料号 单价 库存数 生产工厂 入库时间2.元材料表DIP
--------------------------------------------------------------------
DIP_编号 新料号 品名 单重 总重 料号 单价 库存数 生产工厂 入库时间3.组装表ASSM
--------------------------------------------------------------------
ASSM_编号 新料号 品名 单重 总重 料号 单价 库存数 生产工厂 入库时间4.外包装表PACK
--------------------------------------------------------------------
PACK_编号 新料号 品名 单重 总重 料号 单价 库存数 生产工厂 入库时间
---->>>产品所对应的原始材料,用量,及位置5.产品对应SMD表
--------------------------------------------
产品编号 SMD_编号 用量 位置
6.产品对应DIP表
--------------------------------------------
产品编号 DIP_编号 用量 位置
7.产品对应ASSM表
--------------------------------------------
产品编号 ASSM_编号 用量 位置
8.产品对应PACK表
--------------------------------------------
产品编号 PACK_编号 用量 位置
---->>>产品库9.产品库
--------------------------------------------
产品编号 产品名称 产品型号
请求:这个BOM大置就是要反应这么多内容,
请大家想想办法!简化表的个数及合理的设计,
使之在程序里面操纵更简单更高效。
目的:要算出生产一个产品,所需要的各部件的个数,及金额!
一个产品由那些部件所构成,随时了解零部件的库存的数量。谢谢!e_mail:[email protected]