|
Const mm As Double = 1 / 25.4
Const 行距 = 10 * mm
Const 列距 = 15 * mm
Const X0 = 10 * mm
Const Y0 = 280 * mm
Private Sub Command1_Click()
Call 开始
End Sub
'***********************************************
'从根节点绘制形状,调用递归过程一直到所有的子孙节点都绘制完成.
'如果族人成员太多,需要分级分页绘制,就需要自己添加每页绘制的代数,每页的开始节点,以及如何循环添加visio的页等
'***********************************************
Sub 开始() '加载根节点
'要引用 Microsoft Visio 12.0 Type Library '我这里使用的是Visio2007
Dim Rec As New ADODB.Recordset, i, Y
Dim vs As New Visio.Application, vsoDoc As Visio.Document, shp As Visio.Shape
Rec.Open "select * from 族人信息 where nz(承上码,0)=0 order by 族人代码", Conn, adOpenStatic, adLockReadOnly
Set vsoDoc = vs.Documents.AddEx("basicd_m.vst", visMSDefault, 0) '打开visio程序并基于"basicd_m.vst"模板新建文件
For i = 1 To Rec.RecordCount
If i > 1 Then '把"BASIC_M.VSS"模具的"Rectangle"形状绘制到页面上
Set shp = vsoDoc.Pages(1).Drop(vs.Documents.Item("BASIC_M.VSS").Masters.ItemU("Rectangle"), X0, GetMinY(vsoDoc) - 行距)
Else
Set shp = vsoDoc.Pages(1).Drop(vs.Documents.Item("BASIC_M.VSS").Masters.ItemU("Rectangle"), X0, Y0)
End If
With shp '设置形状属性
.CellsSRC(visSectionObject, visRowXFormOut, visXFormWidth).FormulaU = "10 mm" '形状宽度
.CellsSRC(visSectionObject, visRowXFormOut, visXFormHeight).FormulaU = "5 mm" '形状高度
.CellsSRC(visSectionCharacter, 0, visCharacterSize).FormulaU = "6 pt" '形状字号
.Name = CStr(Rec!族人代码) '形状名称
.Characters.Text = CStr(Rec!姓名) '形状文本
End With
'记录集有按照树形的上下顺序排序的字段,就不需要递归了
递归 Rec!族人代码, vsoDoc '调用递归过程完成根节点下的所有节点
Rec.MoveNext
Next i
'添加首行的世代信息
Rec.MoveFirst
Dim minD, maxD
minD = Rec!世代
maxD = DMax("世代", "族人信息")
For i = minD To maxD
Set shp = vsoDoc.Pages(1).Drop(vsoDoc.Application.Documents.Item("BASIC_M.VSS").Masters.ItemU("Rectangle"), X0 + (i - minD) * 列距, Y0 + 行距)
shp.CellsSRC(visSectionObject, visRowXFormOut, visXFormWidth).FormulaU = "10 mm"
shp.CellsSRC(visSectionObject, visRowXFormOut, visXFormHeight).FormulaU = "5 mm"
shp.CellsSRC(visSectionCharacter, 0, visCharacterSize).FormulaU = "6 pt"
shp.Characters.Text = CStr("第" & i & "世")
Next i
End Sub
Sub 递归(BM, vsoDoc As Visio.Document)
Dim Rec As New ADODB.Recordset, i, N, X, Y
Dim shp As Visio.Shape, vsoCellA As Visio.Cell, vsoCellB As Visio.Cell, vsoChar As Visio.Characters
Dim PX, PY, BX, B '父亲/哥哥的位置
PX = vsoDoc.Pages(1).Shapes(CStr(BM)).CellsSRC(visSectionObject, visRowXFormOut, visXFormPinX)
PY = vsoDoc.Pages(1).Shapes(CStr(BM)).CellsSRC(visSectionObject, visRowXFormOut, visXFormPinY)
Rec.Open "select * from 族人信息 WHERE 承上码=" & BM & " order by 族人代码", Conn, adOpenStatic, adLockReadOnly
For i = 1 To Rec.RecordCount
N = DCount("*", "族人信息", "承上码=" & Rec!承上码 & " and 族人代码<" & Rec!族人代码) '成员的哥哥的数量
If DCount("*", "族人信息", "承上码=" & Rec!族人代码) = 0 Then '成员的后代数量
B = DMax("族人代码", "族人信息", "承上码=" & Rec!承上码 & " and 族人代码<" & Rec!族人代码) '最小的哥哥的编号
If Nz(B, 0) > 0 Then
Y = vsoDoc.Pages(1).Shapes(CStr(B)).CellsSRC(visSectionObject, visRowXFormOut, visXFormPinY) - 行距 '以最小的哥哥的Y坐标为基准,再偏移一个行距
Else
Y = PY '以父亲的Y坐标为基准
End If
Else
If N = 0 Then
Y = PY
Else
Y = GetMinY(vsoDoc) - 行距
End If
End If
X = PX + 列距
Set shp = vsoDoc.Pages(1).Drop(vsoDoc.Application.Documents.Item("BASIC_M.VSS").Masters.ItemU("Rectangle"), X, Y)
shp.CellsSRC(visSectionObject, visRowXFormOut, visXFormWidth).FormulaU = "10 mm"
shp.CellsSRC(visSectionObject, visRowXFormOut, visXFormHeight).FormulaU = "5 mm"
shp.CellsSRC(visSectionCharacter, 0, visCharacterSize).FormulaU = "6 pt"
shp.Name = CStr(Rec!族人代码)
shp.Characters.Text = CStr(Rec!姓名)
If Nz(Rec!承上码, 0) > 0 Then
'添加连接线
Set shp = vsoDoc.Pages(1).Drop(vsoDoc.Application.ConnectorToolDataObject, 1.968504, 9.055118)
shp.Name = "L" & CStr(Rec!族人代码)
'连接上级
Set vsoCellA = vsoDoc.Pages(1).Shapes("L" & CStr(Rec!族人代码)).CellsU("BeginX")
Set vsoCellB = vsoDoc.Pages(1).Shapes(CStr(Rec!承上码)).CellsSRC(7, 1, 0)
vsoCellA.GlueTo vsoCellB
'连接下级
Set vsoCellA = vsoDoc.Pages(1).Shapes("L" & CStr(Rec!族人代码)).CellsU("EndX")
Set vsoCellB = vsoDoc.Pages(1).Shapes(CStr(Rec!族人代码)).CellsSRC(7, 3, 0)
vsoCellA.GlueTo vsoCellB
End If
递归 Rec!族人代码, vsoDoc
Rec.MoveNext
Next i
End Sub
Function GetMinY(vsoDoc As Visio.Document) As Variant '获得页面上所有形状的最小的Y坐标
Dim shp As Visio.Shape, Y As Double
Y = Y0
For Each shp In vsoDoc.Pages(1).Shapes
If IsNumeric(shp.Name) Then
If shp.CellsSRC(visSectionObject, visRowXFormOut, visXFormPinY) < Y Then
Y = shp.CellsSRC(visSectionObject, visRowXFormOut, visXFormPinY)
End If
End If
Next
GetMinY = Y
End Function |
|