今回は、図形の回転及び移動やコピ―を同時に行うことを検討しました。
特に、角度を他のラインから参照して回転コピーする場合は手間を簡素化できます。
Excelsheetからコントロールするようにしています。
基本設定
1-1,ExcelVBEでの設定
新たなWorkBookで作成する場合は、BricsCADのタイプライブラリを使えるように、ExcelのVBE画面で参照設定を行います。
初期設定は、BricsCAD VBAを使ってみよう[7] Excelとの連携② をご参照ください。
1-2,Excelの設定
①ComboBox1(ActivXコントロール)
②③④ボタン(フォームコントロール)
⑤OptionButton1
⑥OptionButton2
⑦OptionButton3
ComboBox1へ画層一覧をセットする
Excelのbookを開いた時に、自動実行させるコードの記述個所は、
ThisWorkbookを選択し、GeneralをWorkbookに変えます。
すると、自動的にWorkbook_Open()のsubプロシージャが作成されますので、その中にbookを開いた時に、自動実行させるコードを記述します。
Option Explicit
Private Sub Workbook_Open()
''BricsCADのオブジェクト変数を宣言
Dim BcadApp As BricscadApp.AcadApplication
Dim BcadDoc As BricscadApp.AcadDocument
''現在開いているBricsCADを取得
On Error Resume Next
Set BcadApp = GetObject(, "BricscadApp.AcadApplication")
''現在開いているBricsCADを取得
If Err.Number <> 0 Then
MsgBox "BricsCADが開かれていません" & vbCr & vbCr & "Excelを終了します"
Application.Quit
Err.Clear
On Error GoTo 0
Exit Sub
End If
BcadApp.Visible = True
Set BcadDoc = BcadApp.ActiveDocument
On Error Resume Next
''=====【画層一覧の取得】=====
Dim ComboBox1 As MSForms.ComboBox
Set ComboBox1 = ActiveSheet.ComboBox1
ComboBox1.Clear
''全画層名をComboBoxLayに格納
Dim layerNames As String
Dim LayObj As AcadLayer
For Each LayObj In BcadDoc.Layers
ComboBox1.AddItem LayObj.Name
Next
''現在の画層名をコンボボックスに標示
ComboBox1.Value = BcadDoc.ActiveLayer.Name
''=====【ブロック一覧の取得】=====
Dim ComboBox2 As MSForms.ComboBox
Set ComboBox2 = ActiveSheet.ComboBox2
ComboBox2.Clear
Dim Blkobj As AcadBlock
For Each Blkobj In BcadDoc.Blocks
If InStr(Blkobj.Name, "*") < 1 Then
ComboBox2.AddItem Blkobj.Name
End If
Next
Set BcadDoc = Nothing
Set BcadApp = Nothing
End Subこ
コード中に、【ブロック一覧の取得】でComboBox2にセットする箇所が選りますが、これは同一ブックにブロック挿入のシートも作成している為で、ここでは関係ありませんので削除してもらって結構です。
作図用のメインプロシージャ
作図用のVBAコードは、標準モジュールを作成しその中に記述します。
②ボタンの角度取得用のコード
Option Explicit
''Win32API宣言(64bit)Sleep関数
Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
''クラス名またはキャプションタイトルからウィンドウハンドルを取得
Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
''フォアグラウンドウィンドウのハンドルを取得。
Declare PtrSafe Function GetForegroundWindow Lib "user32" () As Long
''指定されたウィンドウのハンドルからキャプションタイトルを取得。
Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As LongPtr, ByVal lpString As String, ByVal cch As Long) As Long
''指定されたウィンドウをZオーダーのトップ位置に移動。
Declare PtrSafe Function SetForegroundWindow Lib "user32" (ByVal hwnd As LongPtr) As Long
Sub Get2PointsAngle()
''NUMLOCK用
Dim WshShell
Set WshShell = CreateObject("WScript.Shell")
''【BricsCADのオブジェクト変数を宣言】
Dim BcadApp As BricscadApp.AcadApplication
Dim BcadDoc As BricscadApp.AcadDocument
''現在開いているBricsCADを取得する
Set BcadApp = GetObject(, "BricscadApp.AcadApplication")
BcadApp.Visible = True
Set BcadDoc = BcadApp.ActiveDocument
'' BricsCADのキャプションを取得
Dim BcadCaption As String
BcadCaption = BcadDoc.Application.Caption
'' Excelのキャプションを取得
Dim xlApp As String
xlApp = Excel.Application.Caption
'' Excelのハンドルを取得
Dim XLhWnd As Long
XLhWnd = FindWindow(vbNullString, xlApp)
Dim P1() As Double, P2() As Double
On Error Resume Next
'' BricsCADの画面をアクティブ
AppActivate BcadCaption
P1 = BcadDoc.Utility.GetPoint(, "1点目をクリック : ESCで終了 ")
'キャンセルの場合
If Err Then
On Error GoTo 0
Exit Sub
End If
P2 = BcadDoc.Utility.GetPoint(, "2点目をクリック: ")
Dim Deg As Double, Ang As Double, PI As Double
''水平の場合
If P1(1) = P2(1) Then
If P1(0) < P2(0) Then
Ang = 0
ElseIf P1(0) > P2(0) Then
Ang = 180
End If
''垂直の場合
ElseIf P1(0) = P2(0) Then
If P1(1) < P2(1) Then
Ang = 90
ElseIf P1(1) > P2(1) Then
Ang = 270
End If
''垂直の場合
Else
''斜めの場合
PI = WorksheetFunction.PI()
Deg = Atn((P2(1) - P1(1)) / (P2(0) - P1(0)))
Ang = Deg * 180 / PI
If P1(0) < P2(0) Then
Ang = Ang
If P1(1) > P2(1) Then Ang = Ang + 360
ElseIf P1(0) > P2(0) Then
Ang = Ang + 180
End If
End If
''Excelへ計測角度を記入する
Cells(3, 4).Select
Cells(4, 3).Value = Ang
''Excelの画面をアクティブ
Call BcadActive(WshShell, XLhWnd, xlApp)
Set WshShell = Nothing
Set BcadDoc = Nothing
Set BcadApp = Nothing
End Sub
Sub DataClear_1()
''取得データーをクリア
Dim LastDataRow As Long
LastDataRow = Cells(Rows.Count, 1).End(xlUp).Row
ActiveSheet.Range(Rows(7), Rows(LastDataRow)).ClearContents
Cells(5, 2).Value = 1
Range("B5").Activate
End Sub
Public Function BcadActive(WshShell, XLhWnd As Long, xlApp As String) As Boolean
''フォアグランドのタイトル
Dim FGtitle As String
''現在フォアグラウンドになっているウィンドウハンドルを取得
Dim FGHwnd As Long
FGHwnd = GetForegroundWindow
''フォアグラウンドのタイトルバーテキストを格納
FGtitle = String(100, Chr(0))
GetWindowText FGHwnd, FGtitle, Len(FGtitle)
''フォアグランドタイトルがBricsCADの場合
If FGtitle <> xlApp Then
''フォアグランドタイトルをExcelにする
SetForegroundWindow (XLhWnd)
''「ALT+TAB」キーストロークを送りExcelを最前面にする
Application.SendKeys "%{tab}", True
''NUMLOCK
WshShell.SendKeys "{NUMLOCK}"
Else
AppActivate xlApp
End If
End Function
③ボタンの回転用のコード
Sub Rotation()
''NUMLOCK用
Dim WshShell
Set WshShell = CreateObject("WScript.Shell")
''【BricsCADのオブジェクト変数を宣言】
Dim BcadApp As BricscadApp.AcadApplication
Dim BcadDoc As BricscadApp.AcadDocument
''現在開いているBricsCADを取得する
Set BcadApp = GetObject(, "BricscadApp.AcadApplication")
BcadApp.Visible = True
Set BcadDoc = BcadApp.ActiveDocument
'' BricsCADのキャプションを取得
Dim BcadCaption As String
BcadCaption = BcadDoc.Application.Caption
'' Excelのキャプションを取得
Dim xlApp As String
xlApp = Excel.Application.Caption
'' Excelのハンドルを取得
Dim XLhWnd As Long
XLhWnd = FindWindow(vbNullString, xlApp)
''現在の画層名を取得
Dim CurLyr As String
CurLyr = BcadDoc.ActiveLayer.Name
''作図用画層名を取得
Dim SelLyr As String
SelLyr = ActiveSheet.ComboBox1.Value
''回転角度を取得
Dim Ang As Double
Ang = Cells(4, 2).Value
''オプションボタンを取得
Dim Btn1 As Boolean, Btn2 As Boolean, Btn3 As Boolean
Btn1 = ActiveSheet.OptionButton1.Value
Btn2 = ActiveSheet.OptionButton2.Value
Btn3 = ActiveSheet.OptionButton3.Value
''■■作図実行■■
'' BricsCADの画面をアクティブ
AppActivate BcadCaption
On Error Resume Next
'' UNDO開始
BcadDoc.SendCommand "undo" & vbCr & "BE" & vbCr
Dim Getpt() As Double
Getpt = BcadDoc.Utility.GetPoint(, "回転基点をクリック")
''キャンセルの場合
If Err.Number <> 0 Then
Err.Clear
On Error GoTo 0
GoTo Errline
End If
If Btn2 = True Or Btn3 = True Then
Dim Retpt() As Double
Dim Ret As String
If Btn2 = True Then
Ret = "移動先をクリック"
ElseIf Btn3 = True Then
Ret = "コピー先をクリック"
End If
Retpt = BcadDoc.Utility.GetPoint(, Ret)
End If
Sleep 300
Dim objSelSet As AcadSelectionSet
''同じ選択セットが有れば削除Btn1.Value = True Then
BcadDoc.SelectionSets("selobj").Delete
''選択セットを作成
Set objSelSet = BcadDoc.SelectionSets.Add("selobj")
'エラートラップ
If Err Then
Set objSelSet = BcadDoc.SelectionSets.Item("selobj")
Err.Clear
objSelSet.Clear
End If
''図形を選択セットに格納
objSelSet.SelectOnScreen
' 図形が選択されなかった時は終了
If objSelSet.Count = 0 Then
' 選択セット(selobj)を削除する。
BcadDoc.SelectionSets("selobj").Delete
GoTo Errline
Exit Sub
End If
''πの設定
Dim PI As Double
PI = WorksheetFunction.PI()
''選択セットの図形を回転する
Dim objEntity As AcadEntity
For Each objEntity In objSelSet
''コピーの場合は元の図形をコピーして残す
If Btn3 = True Then objEntity.Copy
objEntity.Rotate Getpt, 0
objEntity.Rotate Getpt, Ang * PI / 180
''移動もしくはコピーの場合
If Btn2 = True Or Btn3 = True Then
objEntity.Move Getpt, Retpt
End If
'' 画層変更
If SelLyr <> CurLyr Then
objEntity.Layer = SelLyr
objEntity.Update
End If
Next
' 図面内のオブジェクトを更新する。
BcadDoc.Application.Update
' 選択セットを削除する。
BcadDoc.SelectionSets("selobj").Delete
''図面を更新
BcadDoc.Application.Update
'' UNDO終了
BcadDoc.SendCommand "undo" & vbCr & "E" & vbCr
Sleep 300
Errline:
''Excelの画面をアクティブ
Call BcadActive(WshShell, XLhWnd, xlApp)
Set objSelSet = Nothing
Set WshShell = Nothing
Set BcadDoc = Nothing
Set BcadApp = Nothing
End Sub
④ボタンのUNDO用のコード
Sub UNDO() Dim BcadApp As BricscadApp.AcadApplication Dim BcadDoc As BricscadApp.AcadDocument Set BcadApp = GetObject(, "BricscadApp.AcadApplication") Set BcadDoc = BcadApp.ActiveDocument Dim BcadCaption As String BcadCaption = BcadDoc.Application.Caption AppActivate BcadCaption BcadDoc.SendCommand "undo" & vbCr & vbCr Set BcadDoc = Nothing Set BcadApp = Nothing End Sub
作図操作
OptionButtonの「Non」は、移動やコピーを行わない意味です。
excelシートオープン時では画層は現在の画層が表示されています。
処理後の図形の画層を変更したい場合は、コンボボックスを変更画層名に切り替えておきます。
「回転」ボタン→回転の基点をクリック→回転したい複数図形を選択
(単一図形では、その図形を直接選択できます)
ここでは、回転した図形が画層2に変更されています。
移動やコピーの場合は、移動先をクリックしてから図形選択です。
角度を参照して回転させる
角度の取得は、2点クリックで取得します。
初めに回転の中心側をクリックして、遠い側をクリックし~360°の角度を取得します。
角度は、水平レベルより左回転で得られます。
その為、水平方向の図形は、(前述の水平方向の矢印の場合の様に)得られた角度そのままで回転すればいいのですが、垂直な図形では、回転角度を逆算する必要があります。
例えば、垂直な方位マークを回転するために参照したラインの角度が52°の場合は、
回転角度は90°ー52°=38°で、右回りに38°なので、-38と入力してください。
この方位マークはブロックではなく、全て線分なので、回転動作時は細かく線ごとに順番に回転していくので見ていて面白いです。
次回は、同様の操作でブロック挿入の予定です。
BricsCAD VBAを使ってみよう INDEX
BricsCAD VBAを使ってみよう[1] VBAのインストール
BricsCAD VBAを使ってみよう[2] UserFormその1
「BricsCAD VBA 」Creating UserForm
BricsCAD VBAを使ってみよう[3] UserFormその2
「BricsCAD VBA 」SerialNumber drawing with UserForm
BricsCAD VBAを使ってみよう[4] VBAの基本コード①
BricsCAD VBAを使ってみよう[5] VBAの基本コード②
BricsCAD VBAを使ってみよう[6] Excelとの連携①
「BricsCAD VBA to Excel」Get_CoordinateValues
BricsCAD VBAを使ってみよう[7] Excelとの連携②
「Excel VBA to BricsCAD」Get_Area
BricsCAD VBAを使ってみよう[8] Excelとの連携②-2
「Excel VBA to BricsCAD」Draw_ChannelSteel
BricsCAD VBAを使ってみよう[9] TABLEの自動作成と値入力
「BricsCAD VBA 」AutomaticCreation of TABLE
BricsCAD VBAを使ってみよう[10] Excelとの連携②-3
「Excel VBA to BricsCAD」SerialNumber_Ⅱ
BricsCAD VBAを使ってみよう[11] Excelとの連携②-4
「Excel VBA to BricsCAD」Draw_Rectang
BricsCAD VBAを使ってみよう[12] Excelとの連携②-5 指定画層にOffset
「Excel VBA to BricsCAD」Continuous Offset to Specified Layer
BricsCAD VBAを使ってみよう[13] Excelとの連携②-6 指定画層にHATCH
「Excel VBA to BricsCAD」Continuous Hatch to Specified Layer
BricsCAD VBAを使ってみよう[14] Excelとの連携②-7 長さ計測
「Excel VBA to BricsCAD」Get Length
BricsCAD VBAを使ってみよう[15] Excelとの連携②-8 画層状態コントロール
「Excel VBA to BricsCAD」LayerStatusControl
BricsCAD VBAを使ってみよう[16] Excelとの連携②-9 回転&移動orコピー
「Excel VBA to BricsCAD」Rotate & move or copy
以下検討中です。
◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
「この特集記事の内容につきましては、
こちらの環境のみの検討結果です。
動作保証は出来かねますため、ご参考
資料としてお扱いください。
Windows11(64bit)
BricsCAD pro V21(64bit)
Office2019(64bit)
◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇









