先日アンケートをいただいて、その中にダイナミック ブロックのコピーがうまくいかないという質問をいただきました。
ということで、dblk.dwg という図面を作って試してみました。
dblk.dwg には、上から
test という名前のダイナミック ブロック
test2 という名前のダイナミック ブロック
円
がありますが、clone メソッドでコピーしてみると、下の2つは問題ないのですが、test に関しては、ブロック名が test ではなくて *U4 になってしまいました。
きっとダイナミック ブロックはコピーしなきゃいけない情報が他のオブジェクトよりもあるのでしょう。
そこで、いろいろググッてみました。
なかなかそれらしいのが見つからなかったのですが DeepCloneObjects っていうのでできそうってことをやっと見つけました。
何度か諦めようかと思ったのですが、やっぱりあると信じて辛抱強く探すことが大事だなと再認識です。
ということで、以下のような感じでやってみたら test という名前のダイナミック ブロックもブロック名が変わることなくコピーできました。
'---------------------------------------------------------
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
Using trans As Transaction = db.TransactionManager.StartTransaction
Try
Dim selEntID As ObjectId = Application.DocumentManager.MdiActiveDocument.Editor.GetEntity("オブジェクトを選択").ObjectId
Dim objIds As ObjectIdCollection = New ObjectIdCollection()
objIds.Add(selEntID)
Dim idMap As IdMapping = New IdMapping
db.DeepCloneObjects(objIds, db.CurrentSpaceId, idMap, False)
For Each idP As IdPair In idMap
Dim cpObj As DBObject = trans.GetObject(idP.Value, OpenMode.ForWrite)
If TypeOf cpObj Is Entity Then
Dim cpEnt As Entity = cpObj
cpEnt.ColorIndex = 1
Dim pt1 As Point3d = New Point3d(0, 0, 0)
Dim vec1 As Vector3d = pt1.GetVectorTo(New Point3d(110, 0, 0))
cpEnt.TransformBy(Matrix3d.Displacement(vec1))
End If
Next
trans.Commit()
Catch ex As Autodesk.AutoCAD.Runtime.Exception
Application.ShowAlertDialog(ex.Message)
End Try
End Using
'---------------------------------------------------------
それと、全然別件なのですが、このときたまたま CurrentSpaceId っていうのがあることに気が付きました。
今まで管理人は、現在モデル空間にるかペーパー空間にいるかの判断を以下のように CVPORT を見てやっていました。
'---------------------------------------------------------
If Application.GetSystemVariable("CVPORT") = 1 Then
btRec = trans.GetObject(bt(BlockTableRecord.PaperSpace), OpenMode.ForWrite)
Else
btRec = trans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
End If
'---------------------------------------------------------
でも、以下のように CurrentSpaceId を使った方が良さそうですね。
'---------------------------------------------------------
Dim cSpace As BlockTableRecord = trans.GetObject(db.CurrentSpaceId, OpenMode.ForRead)
If cSpace.Name = "*Model_Space" Then
btRec = trans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
Else
btRec = trans.GetObject(bt(BlockTableRecord.PaperSpace), OpenMode.ForWrite)
End If
'---------------------------------------------------------
ということで、これからは CurrentSpaceId を使おうかと思います。
質問させて頂いた者です。すばらしいです。ありがとうございます。私もあちこちググってDeepCloneあたりまでは行ったのですが、引数が意味不明でお手上げでした。
返信削除これから自分のマクロに組み込んでみます。
そうなんですよね、DeepClone でもできそうな感じなんですが、私もよく分かりませんでした。
返信削除また何かあればお尋ねくださいね。
CurrentSpaceId
返信削除わー、すごい。これこれ!!
ありがとうございます。
もぐもぐ、食べちゃったです。
おー、喜んでもらえてよかったです。
返信削除管理人も偶然見つけられて嬉しかったです。
初めまして、ダイナミックブロックがコピーできなくて困っていました。是非、使わせていただきたいです
返信削除私は、AutoCAD2009なのですが どこへコピーすれば良いのかを教えていただけないでしょうか
ど素人の質問で申し訳ございません
宜しく、お願い致します。
こんにちは。
返信削除私は AutoCAD 2009 で .NET のプログラムを作ったことがないんですよ。
でも、きっと AutoCAD 2011 と同じだと思います。
上のコードは、コマンドを実行するためのメソッドの中にコピーすれば OK です。
具体的には、私は AVDO_CPDBLK というコマンドを作ったので、以下の場所にコピーです。
_
Public Sub AVDO_CPDBLK()
'
End Sub
これって確認したかった答になってます?
もし、違ったら言ってくださいね。
おはようございます
返信削除早々に、ありがとうございます
御手数をお掛けいたしまして申し訳ございません
操作する以外に全くPCのことは分かりません
例えば C:\***\***\***といった感じで
コピーする場所を教えてください
それから、コピーするだけではなく何か指示を与える
書き込みも必要なのでしょうか?
分からなさ過ぎて申し訳ございません
どうぞ、よろしくお願い致します
おはようございます。
返信削除この内容は、プログラムでダイナミック ブロックをコピーするコマンドを作るときの方法です。
そのため、プログラムを作れる人でないと、どこかにコピーして使えるっていうものではないです。
ダイナミック ブロックをコピーするのであれば、他の図形と同じように、プログラムを作らなくても[複写(COPY)]コマンドでコピーでるはずなんですが…
[複写(COPY)]コマンドでコピーしようとすると、どうなっちゃうんでしょうか?