Code:
Option Explicit
Dim myShape As Excel.Shape
Dim Conn As Shape
Public Type TopLeft
Y As Long
X As Long
End Type
' light blur for male and light red for female
Const Mcolor = 16758883 'RGB(99, 184, 255)
Const Kcolor = 12957183 'RGB(255, 181, 197)
Const Ucolor = 10025880 'RGB(152, 251, 152)
Const ParSammen = ColorConstants.vbGreen
Const ParSkilt = ColorConstants.vbRed
' sizes for the node-shapes
Const Pbredde = 250
Const Phøjde = 50
Const W3kant = 45
Const H3kant = 38.9711431702997
Public Sub danPar(Id1 As Long, Id2 As Long)
'Connect Id1 and Id2, move Id2 if necessary
setSammeTop Id1, Id2: setSammeLeft Id1, Id2
flytShape Trim(Str(Id2)), 1, "R"
make3kant Id1, Id2, "G"
End Sub
Public Function getXY(ID As Long) As TopLeft
' return (Left,Top) as (X,Y) for ID
Dim tl As TopLeft
If Excel.ActiveSheet.Shapes.Count > 0 Then
Excel.ActiveSheet.Shapes(Trim(Str(ID))).Select
tl.X = Excel.Selection.left
tl.Y = Excel.Selection.top
getXY = tl
End If
End Function
Public Sub setSammeTop(Id1 As Long, Id2 As Long)
' make Top for Id2 = Top for Id1
Dim tl As TopLeft
If Excel.ActiveSheet.Shapes.Count > 0 Then
tl = getXY(Id1)
Excel.ActiveSheet.Shapes(Trim(Str(Id2))).Select
Excel.Selection.top = tl.Y
End If
End Sub
Public Sub setSammeLeft(Id1 As Long, Id2 As Long)
' make Left for Id2 = Left for Id1
Dim tl As TopLeft
If Excel.ActiveSheet.Shapes.Count > 0 Then
tl = getXY(Id1)
Excel.ActiveSheet.Shapes(Trim(Str(Id2))).Select
Excel.Selection.left = tl.X
End If
End Sub
Public Sub visEnPerson(ID As Long, MK As String, Navn As String, Fdato As String, FSted As String, Ddato As String, DSted As String)
' Show a person with some data in a box
makeBox ID, MK
With myShape.TextFrame
.Characters.Font.Color = vbBlack
.Characters.Text = ID & " " & Navn & vbCrLf & _
"Født: " & Fdato & " " & FSted & vbCrLf & _
"Død : " & Ddato & " " & DSted
.Characters(1, Len(ID & " " & Navn)).Font.Bold = True
End With
End Sub
Public Sub make3kant(PId1 As Long, PId2 As Long, RGcolor As String)
' Make a triangle
' Tegner en 3kant med farve RGColor lige under PId2 (= moderen).
' Lidt nedrykket og med sort ramme
' Hvis PId1 allerede indgår i et andet forhold, tegnes en 3kant med
' farve RGColor lige under PId2 (= moderen) - ydeligere nedrykket
Dim left As Long, top As Long
' left = ved venstre kan af PId2
left = getXY(PId2).X - W3kant / 2 ' lige midt imellem = (getXY(PId1).X + getXY(PId2).X) / 2 + Pbredde / 2 - W3kant / 2
' top = 1,5 personhøjde under - Id1 og Id2 forudsættes på samme niveau
' men hvis PId1 allerede ingår i et forhold - flyttes 1,5 persomhøjde mere ned
top = getXY(PId1).Y + Phøjde * 1.5
setSammeTop PId1, PId2
Set myShape = ActiveSheet.Shapes.AddShape(msoShapeIsoscelesTriangle, left, top, W3kant, H3kant)
With myShape
.Line.ForeColor.RGB = RGB(0, 0, 0) ' rammefarve
.Line.Weight = 2 ' rammetykkelse
If RGcolor = "R" Then 'Fyldfarve
.Fill.ForeColor.RGB = ParSkilt
Else: .Fill.ForeColor.RGB = ParSammen
End If
.Name = PId1 & "+" & PId2
End With
setArrowsOn PId1, PId2
Set myShape = Nothing
End Sub
Public Sub setArrowsOn(PId1 As Long, PId2 As Long)
' Connect PId1 and PId2 and triangle named PId1+PId2 with arrows
Set Conn = ActiveSheet.Shapes.AddConnector(msoConnectorElbow, 100, 100, 100, 100)
With Conn
.Line.EndArrowheadStyle = msoArrowheadOpen
.ConnectorFormat.BeginConnect ActiveSheet.Shapes(Trim(Str(PId1))), 3
.ConnectorFormat.EndConnect ActiveSheet.Shapes(PId1 & "+" & PId2), 2
End With
Set Conn = ActiveSheet.Shapes.AddConnector(msoConnectorElbow, 100, 100, 100, 100)
With Conn
.Line.EndArrowheadStyle = msoArrowheadOpen
.ConnectorFormat.BeginConnect ActiveSheet.Shapes(Trim(Str(PId2))), 3
.ConnectorFormat.EndConnect ActiveSheet.Shapes(PId1 & "+" & PId2), 6
End With
Set Conn = Nothing
End Sub
Public Sub arrowToChild(PId1 As Long, PId2 As Long, PIdC As Long)
' Connects triangle for parents PId1+PId2 with child PIdC
Set Conn = ActiveSheet.Shapes.AddConnector(msoConnectorElbow, 100, 100, 100, 100)
With Conn
.Line.EndArrowheadStyle = msoArrowheadOpen
.ConnectorFormat.BeginConnect ActiveSheet.Shapes(PId1 & "+" & PId2), 4
.ConnectorFormat.EndConnect ActiveSheet.Shapes(Trim(Str(PIdC))), 2
End With
Set Conn = Nothing
End Sub
Public Sub makeBox(PId As Long, MK As String)
' Makes a rectangle in sex color
' Tegner en personbox med farve efter køn og sort ramme
' M/m giver lyseblå, K/k giver lyserød baggrundsfarve
Set myShape = ActiveSheet.Shapes.AddShape(msoShapeRectangle, 10, 10, Pbredde, Phøjde)
With myShape
' rammefarve
.Line.ForeColor.RGB = RGB(0, 0, 0)
' rammetykkelse
.Line.Weight = 2
If MK = "M" Or MK = "m" Then
.Fill.ForeColor.RGB = Mcolor 'RGB(202, 225, 255)
Else
.Fill.ForeColor.RGB = Kcolor 'RGB(255, 230, 255)
End If
.Name = PId
End With
End Sub
Public Sub flytShape(Navn As String, ant As Long, LRUD As String)
'Moves shape named Navn some units LRUD = Left right Up Down
' Flytter shapen med NAVNET Navn (ikke Id'en) et ant
' Left/Right (generationer) eller Up/down (personer)
ActiveSheet.Shapes(Navn).Select
Select Case LRUD
Case "l", "L"
Excel.Selection.left = Excel.Selection.left - 300 * ant
Case "r", "R"
Excel.Selection.left = Excel.Selection.left + 300 * ant
Case "d", "D"
Excel.Selection.top = Excel.Selection.top + 70 * ant
Case "u", "U"
Excel.Selection.top = Excel.Selection.top - 70 * ant
End Select
End Sub
Public Sub insertSpace()
Rows("1:5").Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
' Columns("A:A").Select
' Selection.Insert Shift:=xlRight, CopyOrigin:=xlFormatFromLeftOrAbove
End Sub
The tree shown in the attached file is VERY SMALL and made manually with the macros in the intermediate window - the ID's is in the upper left corner of the rectangles and the triangles have just the ID's from the parents with a + in between.