前回の、
BricsCAD VBAを使ってみよう[10] Excelとの連携②-3
からの続篇です。
【2021.09.21改定】
連番用のVBAを元に使用頻度の高い図形で、四角形の連続作図を検討しました。
同サイズでは、連続して作図できます。
サイズを変更する場合は、一旦ESCキーで終了して、HとWの値を入力します。
動作中に、【Spaceキー→テンキーで直接選択】もしくは【右クリックにより基点1~9→1~をスクロール】で作図基点を変えることができます。(自動的にPASTECLIPする図形の基点を変更します)
1,連番のVBAコードからの変更点の概要
1,Excelのbookを開いた時の自動実行
基本は前回の連番と同様に、先にBricsCADを開いておきます。
次に、WorkBookを開いた時、BricsCADに作図用の画層を自動作成します。
作成する画層は、「PASTECLIP」用の画層のみです。
現在の画層一覧を取得しcomboboxに格納します。
「PASTECLIP」用の画層はリストに含まないようにしています。
RECTANG作図用の画層をcomboboxから選択します。
自動実行のコード
前回の連番の時と同様に、Workbook_Open()のsubプロシージャ内に記述します。
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
''======【PASTECLIP判定用画層の確認と作成】=====
Dim PastLyr As String, LayCol As Integer
''PASTECLIP用画層名
PastLyr = Cells(6, 2).Value
''画層色を指定
LayCol = 4
Dim LayObj As AcadLayer
Dim NwLayObj As AcadLayer
Dim CkLyr As Boolean
CkLyr = False
''同じ画層名が有るかチェック
For Each LayObj In BcadDoc.Layers
If LayObj.Name = PastLyr Then
CkLyr = True
Exit For
End If
Next
If CkLyr = False Then
''画層がない場合は作成する
Set NwLayObj = BcadDoc.Layers.Add(PastLyr)
NwLayObj.Color = LayCol
End If
''=====【画層一覧の取得】=====
''ComboBoxのオブジェクト変数を宣言
Dim ComboBox As MSForms.ComboBox
Set ComboBox = ActiveSheet.ComboBox1
''全画層名をComboBox1に格納
Dim layerNames As String
For Each LayObj In BcadDoc.Layers
''PASTECLIP用画層名以外の全画層名を取得
If LayObj.Name <> PastLyr Then
layerNames = layerNames + LayObj.Name + vbCrLf
ComboBox.AddItem LayObj.Name
End If
Next
''現在の画層名をコンボボックスに標示
ComboBox.Value = BcadDoc.ActiveLayer.Name
Set NwLayObj = Nothing
Set ComboBox = Nothing
Set BcadDoc = Nothing
Set BcadApp = Nothing
End Sub
2,WorkSheetの構成
RECTANGの四隅を、1・3・7・9とし、更にテンキーのNoと同様の位置を基点に追加しています。
ActiveXコントロールのOptionButton★を、テンキーと同様に★1~9で並べ、10を単位の㎜、★11をmにしています。
実行ボタンは、フォームコントロールのボタンです。
作図実行時の基点は、OptionButtonを選択しておきます。
作図繰り返し動作中は、Spaceキーを先に押して(押し続けません)、
次にテンキーで変更する基点を選択して、PASTECLIP用のPOLYLINE図形を変更するか、
右クリックで現在の基点Noからカウントアップして、PASTECLIP用のPOLYLINE図形を変更します。(連続して右クリックで変更できます)
3,RECTANG作図用のプロシージャ
標準モジュールを作成し、その中にVBAコードを記述します。
今回は、他でも使えそうなので、キー操作での選択を追加しました。
【2021.09.21改定】
Option Explicit
''Win32API宣言(64bit)Sleep関数
Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Declare PtrSafe Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long
Sub Draw_Rectang()
''=========================================
''四角形連続作図 (BricsCAD V21 Excel2019)
''2021.08.22初稿
''2021.09.18改定:再作図時の座標値を訂正
''2021.09.21改定:作図時のズーム範囲を訂正
''=========================================
''BricsCADのオブジェクト変数を宣言
Dim BcadApp As BricscadApp.AcadApplication
Dim BcadDoc As BricscadApp.AcadDocument
''現在開いているBricsCADを取得する
Set BcadApp = GetObject(, "BricscadApp.AcadApplication")
BcadApp.Visible = True
Set BcadDoc = BcadApp.ActiveDocument
''現在の画層名を取得
Dim CurLyr As String
CurLyr = BcadDoc.ActiveLayer.Name
''作図用画層名を取得
Dim SelLyr As String
SelLyr = ActiveSheet.ComboBox1.Value
''PASTECLIP用画層名
Dim PastLyr As String
PastLyr = Cells(6, 2).Value
''↓↓必要に応じて設定してください。
''図形スナップモードの変数を宣言
'Dim OSM As Integer
''図形スナップモードをOFF
'BcadDoc.SetVariable "OSMODE", 0
''図形スナップモードを元に戻す
'BcadDoc.SetVariable "OSMODE", OSM
''右クリックメニューの変数を宣言
Dim RkMenu As Integer
''右クリックメニューの取得
RkMenu = BcadDoc.GetVariable("SHORTCUTMENU")
''右クリックメニューOFF
BcadDoc.SetVariable "SHORTCUTMENU", 0
''BricsCADのキャプションを取得
Dim BcadCaption As String
BcadCaption = BcadDoc.Application.Caption
'' Excelのキャプションを取得
Dim xlApp As String
xlApp = Excel.Application.Caption
''図形サイズの変数を宣言(タテ・ヨコ)
Dim Objhi, ObjWd As Double
''タテヨコ寸法
Objhi = Cells(3, 2).Value: ObjWd = Cells(4, 2).Value
''入力単位がmの場合の換算
If ActiveSheet.OptionButton11.Value = True Then
Objhi = Objhi * 1000: ObjWd = ObjWd * 1000
End If
If Objhi = 0 Or ObjWd = 0 Then MsgBox "値が入力されていません": Exit Sub
''作図開始時判定フラグ
Dim STFlg As Boolean
STFlg = True
''ESCキー時判定フラグ
Dim EscFlg As Boolean
EscFlg = False
''PASTECLIP時判定フラグ
Dim PastFlg As Boolean
PastFlg = False
''===========================================
''===========================================
'' BricsCADの画面をアクティブ
AppActivate BcadCaption
'' MODEMACRO表示
BcadDoc.SendCommand "MODEMACRO" & vbCr & "終了【ESC】/基点変更【右クリック】or【Space→テンキー】" & vbCr
'' 作図繰り返し
ReturnLine:
''画層を"PASTECLIP"に変更する
BcadDoc.SetVariable "CLAYER", PastLyr
''===========================================
''===========================================
Dim Getpt() As Double
''開始時は画面中央座標を取得する
If STFlg = True Then
Getpt = BcadDoc.GetVariable("VIEWCTR")
End If
''Polylineで四角形を描画
Dim objPoly As AcadPolyline
Call DrawPolyline(PastFlg, Getpt, Objhi, ObjWd, BcadDoc, objPoly)
''開始時の画面表示サイズ調整
''作図位置にズーム
Sleep 30
Dim Zp1(0 To 2) As Double, Zp2(0 To 2) As Double
Dim ZA As Double
If ObjWd >= Objhi Then
ZA = Objhi
Else
ZA = ObjWd
End If
Zp1(0) = Getpt(0) - ObjWd: Zp1(1) = Getpt(1) - Objhi: Zp1(2) = Getpt(2)
Zp2(0) = Getpt(0) + ObjWd: Zp2(1) = Getpt(1) + Objhi: Zp2(2) = Getpt(2)
ZoomWindow Zp1, Zp2
STFlg = False
''Polyline図形を選択
BcadDoc.SendCommand "SELECT" & vbCr & "L" & vbCr & vbCr
''【COPYBASE】
BcadDoc.SendCommand "COPYBASE" & vbCr & Getpt(0) & "," & Getpt(1) & vbCr
BcadDoc.SendCommand "ERASE" & vbCr
''===========================================
'' 【PASTECLIP】
''===========================================
''PASTECLIP判定用SelectionSets
On Error Resume Next
Dim RectObj As AcadSelectionSet
''同じ選択セットが有れば削除
BcadDoc.SelectionSets("Rectang").Delete
Set RectObj = BcadDoc.SelectionSets.Add("Rectang")
'エラートラップ
If Err Then
Set RectObj = BcadDoc.SelectionSets.Item("Rectang")
Err.Clear
RectObj.Clear
End If
Dim FilterType(0 To 1) As Integer
Dim FilterData(0 To 1) As Variant
''PASTECLIPした図形(POLYLINE)の選択条件を設定
FilterType(0) = 0
FilterData(0) = "POLYLINE"
FilterType(1) = 8
FilterData(1) = "PASTECLIP"
BcadDoc.SendCommand "_PASTECLIP" & vbCr
Dim SelCnt As Integer
Do
Sleep 30
''ESCキーでループを抜けて終了する
If GetAsyncKeyState(vbKeyEscape) Then
EscFlg = True: Exit Do
''Spaceキーで、基点をテンキー選択で再作図
ElseIf GetAsyncKeyState(vbKeySpace) Then
''図形を選択セットに格納(フィルタ:画面全体、画層、ラインタイプ)
RectObj.Select acSelectionSetAll, , , FilterType, FilterData
''選択セット内のオブジェクト数を取得
'Dim SelCnt As Integer
SelCnt = RectObj.Count
''PASTECLIPされた場合
If SelCnt <> 0 Then
Sleep 100
RectObj.Erase
End If
Do
Sleep 30
If GetAsyncKeyState(vbKeyNumpad1) Then
ActiveSheet.OptionButton1.Value = True: Exit Do
ElseIf GetAsyncKeyState(vbKeyNumpad2) Then
ActiveSheet.OptionButton2.Value = True: Exit Do
ElseIf GetAsyncKeyState(vbKeyNumpad3) Then
ActiveSheet.OptionButton3.Value = True: Exit Do
ElseIf GetAsyncKeyState(vbKeyNumpad4) Then
ActiveSheet.OptionButton4.Value = True: Exit Do
ElseIf GetAsyncKeyState(vbKeyNumpad5) Then
ActiveSheet.OptionButton5.Value = True: Exit Do
ElseIf GetAsyncKeyState(vbKeyNumpad6) Then
ActiveSheet.OptionButton6.Value = True: Exit Do
ElseIf GetAsyncKeyState(vbKeyNumpad7) Then
ActiveSheet.OptionButton7.Value = True: Exit Do
ElseIf GetAsyncKeyState(vbKeyNumpad8) Then
ActiveSheet.OptionButton8.Value = True: Exit Do
ElseIf GetAsyncKeyState(vbKeyNumpad9) Then
ActiveSheet.OptionButton9.Value = True: Exit Do
End If
Loop
EscFlg = False: GoTo ReturnLine
''【右クリックで基点を1~9スクロールで変更し再作図】
ElseIf GetAsyncKeyState(vbKeyRButton) <> 0 Then
Sleep 300
''図形を選択セットに格納(フィルタ:画面全体、画層、ラインタイプ)
RectObj.Select acSelectionSetAll, , , FilterType, FilterData
''選択セット内のオブジェクト数を取得
'Dim SelCnt As Integer
SelCnt = RectObj.Count
''PASTECLIPされた場合
If SelCnt <> 0 Then
Sleep 100
RectObj.Erase
End If
''挿入基準点変更に伴う四角形4隅の移動量
If ActiveSheet.OptionButton1.Value = True Then
ActiveSheet.OptionButton2.Value = True
ElseIf ActiveSheet.OptionButton2.Value = True Then
ActiveSheet.OptionButton3.Value = True
ElseIf ActiveSheet.OptionButton3.Value = True Then
ActiveSheet.OptionButton4.Value = True
ElseIf ActiveSheet.OptionButton4.Value = True Then
ActiveSheet.OptionButton5.Value = True
ElseIf ActiveSheet.OptionButton5.Value = True Then
ActiveSheet.OptionButton6.Value = True
ElseIf ActiveSheet.OptionButton6.Value = True Then
ActiveSheet.OptionButton7.Value = True
ElseIf ActiveSheet.OptionButton7.Value = True Then
ActiveSheet.OptionButton8.Value = True
ElseIf ActiveSheet.OptionButton8.Value = True Then
ActiveSheet.OptionButton9.Value = True
ElseIf ActiveSheet.OptionButton9.Value = True Then
ActiveSheet.OptionButton1.Value = True
End If
EscFlg = False: GoTo ReturnLine
Else
''POLYLINE図形を選択セットに格納
RectObj.Select acSelectionSetAll, , , FilterType, FilterData
''選択セット内のオブジェクト数を取得
SelCnt = RectObj.Count
''PASTECLIPされた場合
If SelCnt <> 0 Then
PastFlg = True
Dim PastObj As AcadEntity
Set PastObj = RectObj.Item(0)
''PASTECLIPした囲い図形にREGIONを作成
Dim RegObj As Variant
RegObj = BcadDoc.ModelSpace.AddRegion(PastObj)
''PASTECLIPした囲い図形を削除
RectObj.Item(0).Erase
''REGIONの選択条件を設定
FilterType(0) = 0
FilterData(0) = "REGION"
FilterType(1) = 8
FilterData(1) = "PASTECLIP"
''REGIONを選択セットに格納
RectObj.Select acSelectionSetAll, , , FilterType, FilterData
''REGIONの中心座標を取得
Dim Centpt() As Double
Centpt = RectObj.Item(1).Centroid
''作図座標に格納
Getpt(0) = Centpt(0): Getpt(1) = Centpt(1): Getpt(2) = Centpt(2)
''REGIONを削除
RectObj.Item(1).Erase
''画層を"作図画層"に変更する
BcadDoc.SetVariable "CLAYER", SelLyr
''PASTECLIPした座標にPolyline図形を再作図
Call DrawPolyline(PastFlg, Getpt, Objhi, ObjWd, BcadDoc, objPoly)
PastFlg = False
''次回作図時に、図形のCOPYBASEを前回作図位置で行うための基点変更
If ActiveSheet.OptionButton1.Value = True Then
Getpt(0) = Centpt(0) - ObjWd / 2: Getpt(1) = Centpt(1) - Objhi / 2: Getpt(2) = Centpt(2)
ElseIf ActiveSheet.OptionButton2.Value = True Then
Getpt(0) = Centpt(0): Getpt(1) = Centpt(1) - Objhi / 2: Getpt(2) = Centpt(2)
ElseIf ActiveSheet.OptionButton3.Value = True Then
Getpt(0) = Centpt(0) + ObjWd / 2: Getpt(1) = Centpt(1) - Objhi / 2: Getpt(2) = Centpt(2)
ElseIf ActiveSheet.OptionButton4.Value = True Then
Getpt(0) = Centpt(0) - ObjWd / 2:: Getpt(1) = Centpt(1): Getpt(2) = Centpt(2)
ElseIf ActiveSheet.OptionButton5.Value = True Then
Getpt(0) = Centpt(0): Getpt(1) = Centpt(1): Getpt(2) = Centpt(2)
ElseIf ActiveSheet.OptionButton6.Value = True Then
Getpt(0) = Centpt(0): Getpt(1) = Centpt(1) + Objhi / 2: Getpt(2) = Centpt(2)
ElseIf ActiveSheet.OptionButton7.Value = True Then
Getpt(0) = Centpt(0) - ObjWd / 2: Getpt(1) = Centpt(1) + Objhi / 2:: Getpt(2) = Centpt(2)
ElseIf ActiveSheet.OptionButton8.Value = True Then
Getpt(0) = Centpt(0): Getpt(1) = Centpt(1) + Objhi / 2:: Getpt(2) = Centpt(2)
ElseIf ActiveSheet.OptionButton9.Value = True Then
Getpt(0) = Centpt(0) + ObjWd / 2: Getpt(1) = Centpt(1) + Objhi / 2: Getpt(2) = Centpt(2)
End If
Sleep 30
Exit Do
End If
End If
Loop
''図面を更新
BcadDoc.Application.Update
''Esc終了時はエラー処理後終了する
If EscFlg = True Then GoTo ErrLine
''作図繰り返し
GoTo ReturnLine
ErrLine:
'' MODEMACROをなしにする
BcadDoc.SendCommand "MODEMACRO" & vbCr & "." & vbCr
''画層を元に戻す
BcadDoc.SetVariable "CLAYER", CurLyr
''図形スナップモードを元に戻す
'BcadDoc.SetVariable "OSMODE", OSM
''ミ右クリックメニュy-を元に戻す
BcadDoc.SetVariable "SHORTCUTMENU", RkMenu
'' Excelの画面をアクティブ
AppActivate xlApp
Set RectObj = Nothing
Set objPoly = Nothing
Set BcadDoc = Nothing
Set BcadApp = Nothing
End Sub
Private Sub ComboBox1_Change()
SelLyr = ActiveSheet.ComboBox1.Value
BcadDoc.SetVariable "CLAYER", SelLyr
End Sub
Private Sub DrawPolyline(ByVal PastFlg As Boolean, ByVal Getpt As Variant, ByVal Objhi As Double, ByVal ObjWd As Double, BcadDoc As BricscadApp.AcadDocument, objPoly As AcadPolyline)
''挿入基準点変更に伴う作図用座標値の移動
Dim Mx, My As Double
If PastFlg = False Then
If ActiveSheet.OptionButton1.Value = True Then
Mx = 0: My = 0
ElseIf ActiveSheet.OptionButton2.Value = True Then
Mx = -ObjWd / 2: My = 0
ElseIf ActiveSheet.OptionButton3.Value = True Then
Mx = -ObjWd: My = 0
ElseIf ActiveSheet.OptionButton4.Value = True Then
Mx = 0: My = -Objhi / 2
ElseIf ActiveSheet.OptionButton5.Value = True Then
Mx = -ObjWd / 2: My = -Objhi / 2
ElseIf ActiveSheet.OptionButton6.Value = True Then
Mx = -ObjWd: My = -Objhi / 2
ElseIf ActiveSheet.OptionButton7.Value = True Then
Mx = 0: My = -Objhi
ElseIf ActiveSheet.OptionButton8.Value = True Then
Mx = -ObjWd / 2: My = -Objhi
ElseIf ActiveSheet.OptionButton9.Value = True Then
Mx = -ObjWd: My = -Objhi
End If
Else
Mx = -ObjWd / 2: My = -Objhi / 2
End If
''RECTANGをPolylineで描画
Dim Pv(0 To 14) As Double
''左下の座標
Pv(0) = Getpt(0) + Mx: Pv(1) = Getpt(1) + My: Pv(2) = Getpt(2)
''右下の座標
Pv(3) = Getpt(0) + Mx: Pv(4) = Getpt(1) + My + Objhi: Pv(5) = Getpt(2)
''右上の座標
Pv(6) = Getpt(0) + Mx + ObjWd: Pv(7) = Getpt(1) + My + Objhi: Pv(8) = Getpt(2)
''左上の座標
Pv(9) = Getpt(0) + Mx + ObjWd: Pv(10) = Getpt(1) + My: Pv(11) = Getpt(2)
''左上の座標
Pv(12) = Getpt(0) + Mx: Pv(13) = Getpt(1) + My: Pv(14) = Getpt(2)
''3Dポリライン作図
Set objPoly = BcadDoc.ModelSpace.AddPolyline(Pv)
''ポリラインを閉じる
objPoly.Closed = False
End Sub
Do~Loop内のコードをSleepでコントロールしていますので、PCの処理速度の影響があるかもわかりません。そのあたりは以下のcoffe breakを参照ください。
以下続く・・・・
今回はEsc終了以外に、作図基点を作図中に変更することを検討しました。
Do~Loopで選択を行っていますが、使用しているSleepの30と300を逆にすると、エラーになります。Escキー、右クリック、テンキーのキーアクションをとらえれない状態で、コードのすり抜けが発生し、連続的に原点でPASTECLIPする場合があります。この場合Escキーを連打で終了します。
SendCommandも、コマンドの組み合わせによっては、影響が生じる場合が有ります。
CadもExcelもいったん閉じて再度実行で治っていますので、その他まだ気づいていない要因が有るのかも分かりません。
この辺りは、コマンドラインウインドウで、動作状態を確認しながら調整することも重要ですね。
2021.09.21 一部改定しました。
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
以下検討中です。
◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
「この特集記事の内容につきましては、
こちらの環境のみの検討結果です。
動作保証は出来かねますため、ご参考
資料としてお扱いください。
Windows10(64bit)
BricsCAD pro V21(64bit)
Office2019(64bit)
◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇




