Excel VBA 在工程測量上的應用
Excel 是大家很熟悉的辦公軟件,相信大家在工作中經(jīng)常使用吧。在測量工作中,你是否感覺到有很不方便的時候?比如,計算一個角度的三角函數(shù)值,而角度的單位是 60 進制的,此時,你一定感到很無奈,因為, Excel 本身無法直接計算 60 進制的角度的三角函數(shù)!還有,如果你的工作表中有了點坐標值(二維或者三維),要在 CAD 中展繪出來,怎樣才能又快又直接?不然,就只有拐彎摸角了,很痛苦啊!其實,只要對 Excel 進行一些挖掘,就可以發(fā)現(xiàn) Excel 的功能我們還沒有好好的利用呢。 Excel 本身提供了強大的二次開發(fā)功能,只要我們仔細的研究,沒有什么能難倒我們的。下面,好好筆者將帶你走近 Excel ,認識它的強大的二次開發(fā)環(huán)境 VBAIDE ,用它來解決上面所提到的問題,就非常容易了。
初識 VBAIDE ,首先,你必須懂得一些簡單的 VB 編程常識。如果不懂就只有通過其他的途徑去學習了。但用不著深入的研究,只要靜下心來,幾個小時就可以了。
打開 Excel ,按 Alt+F11 即進入 VBAIDE ,學過 VB 的人一看就知道那就是熟悉的 VB 界面。下面看看如何定義一個函數(shù),然后利用它來解決 60 進制的???㈠?0角度的三角函數(shù)計算問題。在菜單上依次點擊 [ 插入 ]----->[ 模塊 ] ,然后輸入如下代碼
Public Const pi = 3.14159265359
Public Function DEG(n As Double)
Dim A As Double, B As Double, C As Double, D As Double, E As Double, F As Double, G As Double, KA As Double
D = Abs(n) + 0.000000000000001
F = Sgn(n)
A = Int(D)
B = Int((D - A) * 100)
C = D - A - B / 100
DEG = F * (A + B / 60 + C / 0.36) * pi / 180
End Function
這樣,就定義了一個名字叫 DEG 的函數(shù),它的作用就是轉換 60 進制的角度為 Excel 認識的弧度。編輯完后按 Alt+Q 即返回 Excel ,再在某一單元格輸入 =sin(deg(A1))(A1 既可以是單元格的值 , 也可以是輸入的角度值 ), 回車,哈哈,怎么樣?結果出來了吧?你可以用計算器檢驗一下是否正確。如果出現(xiàn) #NA???㈠?0ME ?那就要設置一下安全設置。依次點 [ 工具 ]->[ 宏 ]->[ 安全性 ] ,在安全級選項卡上選擇“中”或者“低”,然后關閉后重新打開就可以了,以后只要是 60 進制的角度,就用它轉換,非常方便哦。
工程測量中,經(jīng)常碰到導線的計算,如果手頭沒有平差計算程序就只有手工計算了,這時候你曾經(jīng)想過編個小程序來計算?其實,這很簡單,筆者在宛坪(上海至武威)高速公路上做測量監(jiān)理,因為有大量的導線需要復核,故編寫了一個附合導線計算程序,代碼很簡單,但很實用。下面是該程序的代碼:
Sub 附合導線計算 ()
Dim m As Integer, n As Integer, ms As Double, gg As Double, sht As Object, xx As Double, yy As Double, S As Double
Set sht = ThisWorkbook.ActiveSheet
Do While sht.Cells(m + 3, 4) <> ""
m = m + 1
Loop
For n = 3 To m + 2
ms = DEG(ms) + DEG(sht.Cells(n, 4))
ms = RAD(ms)
S = S + sht.Cells(n, 3)
Next
ms = DEG(ms)
gg = RAD(DEG(sht.Cells(3, 5)) + ms - DEG(sht.Cells(3 + m, 5)) - pi * m)
xx = 0: yy = 0
For n = 4 To m + 2
' 方位角
sht.Cells(n, 5) = RAD(DEG(sht.Cells(n - 1, 5)) + DEG(sht.Cells(n - 1, 4)) - pi - DEG(gg) / m)
' 坐標增量
sht.Cells(n, 6) = Format(sht.Cells(n - 1, 3) * Cos(DEG(sht.Cells(n, 5))), "#####.####")
sht.Cells(n, 7) = Format(sht.Cells(n - 1, 3) * Sin(DEG(sht.Cells(n, 5))), "#####.####")
' 坐標增量和
xx = xx + sht.Cells(n, 6)
yy = yy + sht.Cells(n, 7)
Next
xx = xx + sht.Cells(3, 10) - sht.Cells(m + 2, 10)
yy = yy + sht.Cells(3, 11) - sht.Cells(m + 2, 11)
sht.Cells(m + 4, 5) = " △α =" & Format(gg, "###.######")
sht.Cells(m + 4, 6) = " △ X=" & Format(xx, "###.###")
sht.Cells(m + 4, 7) = " △ Y=" & Format(yy, "###.###")
sht.Cells(m + 4, 3) = " ∑ S=" & Format(S, "###.###")
sht.Cells(m + 4, 9) = " △ S=" & Format(Sqr(xx * xx + yy * yy), "###.###")
sht.Cells(m + 4, 10) = " 相對精度 1/" & Format(S / Sqr(xx * xx + yy * yy), "######")
For n = 4 To m + 2
sht.Cells(n, 8) = Format(xx / S * sht.Cells(n - 1, 3), "###.####")
sht.Cells(n, 9) = Format(yy / S * sht.Cells(n - 1, 3), "###.####")
Next
For n = 4 To m + 1
sht.Cells(n, 10) = sht.Cells(n - 1, 10) + sht.Cells(n, 6) - sht.Cells(n, 8)
sht.Cells(n, 11) = sht.Cells(n - 1, 11) + sht.Cells(n, 7???㈠?0) - sht.Cells(n, 9)
Next
Columns("F:K").Select
Selection.NumberFormatLocal = "0.000_ "
End Sub
Public Function RAD(Nu As Double) As Double
Dim A As Double, B As Double, C As Double, D As Double, E As Double, F As Double, G As Double, p As Double
D = Abs(Nu)
F = Sgn(Nu)
p = 180# / pi
G = p * 60#
A = Int(D * p)
B = Int((D - A / p) * G)
W = B
C = (D - A / p - B / G) * 20.62648062
RAD = (C + A + B / 100) * F
End Function
值得注意的是,前面提到的 DEG 函數(shù)別忘記加進去。
如果自己定義一個名字叫“計算”的按鈕,指定此工具的宏為“單一附合導線計算”,那么,只要按下面的格式輸入原始數(shù)據(jù)(斜體是輸入的),點“計算”就可以得到計算結果了。所有的過程都是自動的,無須再手工填寫,是不是很方便?
下面我們就來解決上面提到的與 CAD 的連接和通訊問題。
進入 VBAIDE ,按 [ 工具 ]->[ 引用 ], 找到可使用的引用,在“ AutoCAD2000 類型庫”的左邊打鉤,點確定就行了。在模塊中輸入以下代碼:
Global Sheet As Object, acadmtext As acadmtext, fontHight As Double
Global xlBook As Excel.Workbook
Global p0(2) As Double, p1(2) As Double, p2(2) As Double
Global acadApp As AcadApplication
Global acadDoc As AcadDocument
Global acadPoint As acadPoint
Global number As Integer
Public Type pt
n As Integer
pt(2) As Double
Global pt() As pt
Global text1 As AcadText
???㈠?0 Global CAD As Object
Global p(2) As Double, i As Integer, j As Integer
Global h As Integer, l As Integer
Public Function Get_ACAD(Dwt As String) As Boolean
Dim YER As Integer
On Error Resume Next
Set acadApp = GetObject(, "AutoCAD.Application")
If Err Then
Err.Clear
Set acadApp = CreateObject("AutoCAD.Application")
If Err Then
MsgBox Err.Description
On Error GoTo 0
Get_ACAD = False
Exit Function
End If
End If
On Error GoTo 0
Set acadDoc = acadApp.ActiveDocument
acadApp.Visible = True
Get_ACAD = True
Dim typeFace As String
Dim Bold As Boolean
Dim Italic As Boolean
Dim charSet As Long
Dim PitchandFamily As Long
acadDoc.ActiveTextStyle.GetFont typeFace, Bold, Italic, charSet, PitchandFamily
acadDoc.ActiveTextStyle.SetFont " 宋體 ", Bold, Italic, charSet, PitchandFamily
End Function
Sub 顯示對話框 ()
Form1.Show (0)
End Sub
Public Function Draw_Point(Point() As Double) As acadPoint
Set Draw_Point = acadDoc.ModelSpace.AddPoint(Point)
Draw_Point.Update
End Function
Public Sub Set_layer(s As String)
Dim layerObj As AcadLayer
Set layerObj = acadDoc.Layers.Add(s)
acadDoc.ActiveLayer = layerObj
End Sub
再按以下模式做個對話框:窗體的名字就叫“ Form1 ”
雙擊“展點”按鈕,輸入以下代碼:
Dim p0(2) As Double, p1(2) As Double, p2(2) As Double
Dim T1 As Double, T2 As Double, T3 As Double, T4 As Double
Public ne As Integer, sp As Single, cz As Single
Call Get_ACAD("")
Dim txt As AcadText
Dim la As AcadLayer
For Each Layer In acadDoc.ModelSpace
Next
Call Set_layer("zdh")
Set Sheet = ThisWorkbook.ActiveSheet
Dim i As Integer
Do While Sheet.Cells(i + 1, 3) <> "" Or Sheet.Cells(i + 1, 1) <> ""
If Sheet.Cells(i + 1, 3) = "" Or Sheet.Cells(i + 1, 4) = "" Then GoTo II
With Sheet
p1(0) = .Cells(i + 1, 3).Value
p1(1) = .Cells(i + 1, 4).Value
p1(2) = .Cells(i + 1, 5).Value
End With
p(0) = p1(0)
p(1) = p1(1)
Call Set_layer("ZDH")
Call Draw_Point(p1)
fontHight = TextBox5.Value
If Cells(i + 1, 2) = "" Then GoTo oo
Set txt = acadDoc.ModelSpace.AddText(Cells(i + 1, 2), p, fontHight)
txt.Color = acMagenta
oo:
If Cells(i + 1, 5) = "" Then GoTo II
Set_layer ("GCD")
p(1) = p1(1) - fontHight
Set txt = acadDoc.ModelSpace.AddText(Format(Cells(i + 1, 5), "00.0"), p, fontHight)
txt.Color = acMagenta
II:
i = i + 1
Loop
End Sub
當然,你在 Excel 上同樣可以再加個工具按鈕,比如叫“展點”,指定宏為“顯示對話框”,只要你的 Excel 有了 X,Y 或者 X,Y , Z (格式如下表),點擊“展點” 就可以自動啟動 A utoCAD 展點啦!當然 , 如果 A utoCAD 已經(jīng)啟動 , 就直接在已經(jīng)打開的 A utoCAD 文檔中展點,展點完畢后,會顯示一個對話框,提示“展點完畢“,再切換到 A utoCAD 看看,你所要展的點是否已經(jīng)出現(xiàn)了?如果沒有輸入錯誤,應該可以得到滿意的結果。如果有點號 , 還可以顯示點號,并且可以輸入字體的高度。
下面是坐標格式,其中第一列為點名,第二列為編碼(可以為空),第三列為 X ,第四列為 Y ,第五列為高程。注意, X , Y 是 A utoCAD 的橫坐標和縱坐標,與測量坐標系不同。
Excel 的功能是非常強大的,如果有興趣,你還可以在 AutoCAD 中直接與 Excel 通訊,比如一條三維多段線的所有結點的三維坐標直接導入到 Excel ,比在 AutoCAD 中用列表的方法要方便的多,限于篇幅,無法在此詳細敘述了。如果讀者有興趣,可以深入的學習和探討。