我写的这段VBA代码是在COREL DRAW 12上运行的,是从COREL DRAW 页面上导出DXF格式的小程序,存在的问题是圆弧有时导出后反了。我估计是圆的开始点和结束点如何判断的问题搞不懂,为此请教。祥见代码,如果方便请帮助修改,先感谢了。
Private Sub CommandButton3_Click()
ActiveDocument.Unit = cdrMillimeter
'On Error Resume Next
If ActivePage.Shapes.Count = 0 Then Exit Sub
Application.Optimization = True
Dim sT As Shape
Dim sr As New ShapeRange
Dim z As Long
Dim i As Long
ActivePage.Shapes.All.CreateSelection
ActivePage.Shapes.All.Copy
For Each sT In ActivePage.Shapes '取消全部群组
If sT.Type = cdrGroupShape Then sT.UngroupAll
Next
For Each sT In ActivePage.Shapes
If sT.Type = cdrPolygonShape Then sT.ConvertToCurves
If sT.Type = cdrRectangleShape Then sT.ConvertToCurves
If sT.Type = cdrEllipseShape Then
If Round(sT.Ellipse.HRadius, 2) <> Round(sT.Ellipse.VRadius, 2) Then sT.ConvertToCurves
End If
Next
For Each sT In ActivePage.FindShapes(, cdrCurveShape)
sT.Curve.Closed = False
z = sT.Curve.Nodes.Count
For i = z To 1 Step -1
sT.Curve.Nodes(i).BreakApart
Next i
sT.BreakApart
Next
For Each sT In ActivePage.FindShapes(, cdrCurveShape)
If sT.Curve.SubPaths(1).Segments(1).Type = 1 Then
For i = 1 To 4 ''''''''''''''''
sT.Curve.SubPaths(1).AddNodeAt (i / 5), cdrRelativeSegmentOffset ''''''''''''''''''''''
Next
sT.Curve.Closed = False
z = sT.Curve.Nodes.Count
For i = z To 1 Step -1
sT.Curve.Nodes(i).BreakApart
Next i
sT.BreakApart
End If
Next
WriteLineToFile
ActivePage.Shapes.All.Delete
ActiveLayer.Paste
Application.Optimization = False
Application.ActiveWindow.Refresh
End Sub
Private Function WriteLineToFile() As String
Const ForReading = 1, ForWriting = 2
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile("c:\testfile.dxf", ForWriting, True)
'-------------------------------------------
Call WriteHeader(ActivePage.Shapes.All)
Call writeTable
Call WriteBeginEntities
Call WriteLineText '''''''''''''''''''''''''''''
Call WriteEndSEC
Call WriteEof
f.Close
Set f = Nothing
'-------------------------------------------
Set f = fso.OpenTextFile("c:\testfile.dxf", ForReading)
WriteLineToFile = f.ReadAll
f.Close
Set f = Nothing
Set fso = Nothing
End Function
Private Sub WriteHeader(sr As ShapeRange)
'写DXF文件头
WriteBeginSEC
WriteLine " 2"
WriteLine "HEADER"
ActiveDocument.ReferencePoint = cdrBottomLeft
WriteLine " 9"
WriteLine "$EXTMIN"
With sr
WriteLine " 10"
WriteLine .PositionX
WriteLine " 20"
WriteLine .PositionY
End With
ActiveDocument.ReferencePoint = cdrTopRight
WriteLine " 9"
WriteLine "$EXTMAX"
With sr
WriteLine " 10"
WriteLine .PositionX
WriteLine " 20"
WriteLine .PositionY
End With
WriteEndSEC
End Sub
Private Sub writeTable()
'此部份为DXF文件第二部份
WriteBeginSEC
WriteLine " 2"
WriteLine "TABLES"
WriteLine " 0"
WriteLine "TABLE"
WriteLine " 2"
WriteLine "LAYER"
WriteLine " 70"
WriteLine " 1"
WriteLine " 0"
WriteLine "LAYER"
WriteLine " 2"
WriteLine "Design"
WriteLine " 70"
WriteLine "64"
WriteLine " 62"
WriteLine "7"
WriteLine " 6"
WriteLine "CONTINUOUS"
WriteLine " 0"
WriteLine "ENDTAB"
WriteEndSEC
End Sub
Private Sub WriteBeginBlocks()
WriteBeginSEC
WriteLine " 2"
WriteLine "BLOCKS"
WriteEndSEC
End Sub
Private Sub WriteBeginEntities()
WriteBeginSEC
WriteLine " 2"
WriteLine "ENTITIES"
End Sub
Private Sub WriteLineText()
Dim x2 As Double, y2 As Double
For Each s In ActivePage.Shapes
Select Case s.Type
Case 3 'cdrCurveShape
Select Case s.Curve.SubPaths(1).Segments(1).Type
Case 0 'cdrLineSegment
Call WriteCdrLine(CMYKColorToIndexColor(s.Outline.Color.Name), _
s.Curve.SubPaths(1).Segments(1).StartNode.PositionX, _
s.Curve.SubPaths(1).Segments(1).StartNode.PositionY, _
s.Curve.SubPaths(1).Segments(1).EndNode.PositionX, _
s.Curve.SubPaths(1).Segments(1).EndNode.PositionY) '直线
Case 1 'cdrCurveSegment
s.Curve.SubPaths(1).Segments(1).GetPointPositionAt x2, y2
Call WriteCdrCArc(CMYKColorToIndexColor(s.Outline.Color.Name), _
s.Curve.SubPaths(1).Segments(1).StartNode.PositionX, _
s.Curve.SubPaths(1).Segments(1).StartNode.PositionY, _
x2, _
y2, _
s.Curve.SubPaths(1).Segments(1).EndNode.PositionX, _
s.Curve.SubPaths(1).Segments(1).EndNode.PositionY) '曲线弧
Case 2
MsgBox "复合线出现!"
End Select
Case 2 'cdrEllipseShape
If Round(s.Ellipse.HRadius, 2) = Round(s.Ellipse.VRadius, 2) Then
Call WriteCdrEArc(CMYKColorToIndexColor(s.Outline.Color.Name), _
s.Ellipse.CenterX, _
s.Ellipse.CenterY, _
s.Ellipse.HRadius, _
s.Ellipse.StartAngle + s.RotationAngle + 0.01, _
s.Ellipse.EndAngle + s.RotationAngle)
End If
End Select
Next
End Sub
Sub WriteCdrCArc(indexColor As Integer, x1 As Double, y1 As Double, x2 As Double, y2 As Double, x3 As Double, y3 As Double)
Dim x0 As Double
Dim y0 As Double
Dim r As Double
Dim StartAngle As Double
Dim EndAngle As Double
x0 = ((y3 - y1) * (y2 * y2 - y1 * y1 + x2 * x2 - x1 * x1) + (y2 - y1) * (y1 * y1 - y3 * y3 + x1 * x1 - x3 * x3)) / (2 * (x2 - x1) * (y3 - y1) - 2 * (x3 - x1) * (y2 - y1))
y0 = ((x3 - x1) * (x2 * x2 - x1 * x1 + y2 * y2 - y1 * y1) + (x2 - x1) * (x1 * x1 - x3 * x3 + y1 * y1 - y3 * y3)) / (2 * (y2 - y1) * (x3 - x1) - 2 * (y3 - y1) * (x2 - x1))
r = Sqr((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0))
EndAngle = MyAngle(x1 - x0, y1 - y0, x1, y1, x0, y0)
StartAngle = MyAngle(x3 - x0, y3 - y0, x3, y3, x0, y0)
WriteLine " 0"
WriteLine "ARC"
WriteLine " 8"
WriteLine "Design"
WriteLine " 6"
WriteLine "CONTINUOUS"
WriteLine " 62"
WriteLine CStr(indexColor)
WriteLine " 10"
WriteLine CStr(x0)
WriteLine " 20"
WriteLine CStr(y0)
WriteLine " 40"
WriteLine CStr(r)
WriteLine " 50"
WriteLine CStr(StartAngle)
WriteLine " 51"
WriteLine CStr(EndAngle)
End Sub
Private Sub WriteCdrLine(indexColor As Integer, StartNodeX As Double, StartNodeY As Double, EndNodeX As Double, EndNodeY As Double) '直线
WriteLine " 0"
WriteLine "LINE"
WriteLine " 8" '层名
WriteLine "Design"
WriteLine " 6"
WriteLine "CONTINUOUS"
WriteLine " 62" '颜色
WriteLine CStr(indexColor)
WriteLine " 10"
WriteLine CStr(StartNodeX)
WriteLine " 20"
WriteLine CStr(StartNodeY)
WriteLine " 11"
WriteLine CStr(EndNodeX)
WriteLine " 21"
WriteLine CStr(EndNodeY)
End Sub
Private Sub WriteCdrEArc(indexColor As Integer, S_CenterX As Double, S_CenterY As Double, S_HRadius As Double, StartAngelM As Double, EndAngelM As Double) '正圆和弧
WriteLine " 0"
WriteLine "ARC"
WriteLine " 8"
WriteLine "Design"
WriteLine " 6"
WriteLine "CONTINUOUS"
WriteLine " 62"
WriteLine CStr(indexColor)
WriteLine " 10"
WriteLine CStr(S_CenterX)
WriteLine " 20"
WriteLine CStr(S_CenterY)
WriteLine " 40"
WriteLine CStr(S_HRadius)
WriteLine " 51"
WriteLine CStr(StartAngelM)
WriteLine " 50"
WriteLine CStr(EndAngelM)
End Sub
Private Sub WriteLine(sOneRow As String)
'向DXF文件流中写入一行信息
On Error GoTo ErrorHandler
f.WriteLine sOneRow
Exit Sub
ErrorHandler:
MsgBox Err.Description
End Sub
Private Sub WriteBeginSEC()
f.WriteLine " 0"
f.WriteLine "SECTION"
End Sub
Private Sub WriteEndSEC()
WriteLine " 0"
WriteLine "ENDSEC"
End Sub
Private Sub WriteEof()
f.WriteLine " 0"
f.WriteLine "EOF"
End Sub
Private Function MyAngle(w As Double, h As Double, xx As Double, yy As Double, x0 As Double, y0 As Double) As Double
Dim HW As Double
HW = h / w
MyAngle = Abs(Atn(HW) * 180 / 3.14159265358979)
Select Case xx - x0
Case Is >= 0
Select Case yy - y0
Case Is >= 0 '++++++ 1
MyAngle = MyAngle
Case Is < 0 '++++++ 4
MyAngle = (90 - MyAngle) + 270
End Select
Case Is < 0
Select Case yy - y0
Case Is >= 0 '++++++ 2
MyAngle = (90 - MyAngle) + 90
Case Is < 0 '++++++ 3
MyAngle = MyAngle + 180
End Select
End Select
End Function
Private Function CMYKColorToIndexColor(CMYK As String) As Integer
Select Case CMYK
Case "黑"
CMYKColorToIndexColor = 7
Case "青"
CMYKColorToIndexColor = 4
Case "蓝"
CMYKColorToIndexColor = 5
Case "红"
CMYKColorToIndexColor = 1
Case "紫"
CMYKColorToIndexColor = 202
Case "洋红"
CMYKColorToIndexColor = 6
Case "绿"
CMYKColorToIndexColor = 3
Case "黄"
CMYKColorToIndexColor = 2
Case Else
CMYKColorToIndexColor = 9
End Select
End Function