Hi:
i have a dwg "A". and in the dwg "A", there are some blocks like blk1,blk2.
and in my blockview form, i newed a databse db1.
and i want to insert the blk1 into the db1 modelspace.
but when i append the blockreference to the db1 modelspace, acad show the error "ewrongdatabase",i found the databse is exist and the space is also exist, the only thing is it is not saved to a dwg file.
did anyone do this? or could anybody give me a simple demo for this?
regards
swaywood
Solved! Go to Solution.
Solved by phliberato. Go to Solution.
Without seeing your code, all is a guessing game. Let me guess:
You have a drawing "A" opening, with a few block DEFINITION defined. You want to create one block reference based on one of the block definition in another drawing database. So, you creates an instance of a block reference, and try to append it into the modelspace of another drawomg (the side database).
If this is what you do, it is so obvious: the block reference created is a REFERENCE to one fo the block definitions in drawing "A", which cannot live in other database, thus the error.
You need to recreate/copy the block definition into the other drawing/database, and then create block referense THERE.
Norman Yuan
hi yuan:
here is the test code, please help me.
private void Test(string dwgName = "d:\\A.DWG", string blockName = "blk1") { //load the A DWG Database dbTemp = new Database(false, true); dbTemp.ReadDwgFile(dwgName, FileShare.Read, true, null); dbTemp.CloseInput(true); //i want to insert a block from A DWG into the new dwg i newed using (Database desDB = new Database(false, true)) using (Transaction trans = desDB.TransactionManager.StartTransaction()) { ObjectId spaceId = desDB.GetModelSpaceId(); ObjectId btrId = desDB.Insert(blockName, dbTemp, false); trans.Commit(); } }
public static class BlockUtils { public static void TestInsertBlock() { ////Use this code to copy block from another database and create and insert one blockreference in the current drawing Database db = HostApplicationServices.WorkingDatabase; //Put your file path here string dwgFileBlocks = "c:\\........"; //Name of block string blockName = "blockName"; //Point to insert block Point3d blockReferencePoint = new Point3d(0, 0, 0); string erro; ObjectId blocoId = GetBlockIdWithCopyBlockTableRecord(db, dwgFileBlocks, blockName, out erro); if (!blocoId.IsNull) { BlockReference blockReference = new BlockReference(blockReferencePoint, blocoId); InsertBlockReference(db, blockReference); } else { Editor ed = acadApp.DocumentManager.MdiActiveDocument.Editor; ed.WriteMessage(Environment.NewLine + erro); } } public static ObjectId GetBlockIdWithCopyBlockTableRecord(Database pToDatabase, string pDwgFileBlocks, string pBlockName, out String pErro) { pErro = null; using (Transaction trans = pToDatabase.TransactionManager.StartTransaction()) { BlockTable bt = (BlockTable)trans.GetObject(pToDatabase.BlockTableId, OpenMode.ForWrite, false); if (!bt.Has(pBlockName)) { if (!CopyBlockTableRecord(bt, pDwgFileBlocks, pBlockName, out pErro)) return ObjectId.Null; } ObjectId objectId = bt[pBlockName]; trans.Commit(); return objectId; } } private static bool CopyBlockTableRecord(BlockTable pBlockTable, string pDwgFileBlocks, string pBlockName, out String pErro) { pErro = null; if (!File.Exists(pDwgFileBlocks)) { pErro = string.Format("File '{0}' not found", pDwgFileBlocks); return false; } Database dbSource = new Database(false, true); try { dbSource.ReadDwgFile(pDwgFileBlocks, FileOpenMode.OpenForReadAndReadShare, true, ""); } catch { pErro = String.Format("Can't read file '{0}'", pDwgFileBlocks); return false; } using (Transaction transSource = dbSource.TransactionManager.StartTransaction()) { BlockTable btSource = (BlockTable)transSource.GetObject(dbSource.BlockTableId, OpenMode.ForRead); if (!btSource.Has(pBlockName)) { pErro = string.Format("Block '{0}' not found", pBlockName); transSource.Commit(); return false; } ObjectIdCollection listIds = new ObjectIdCollection(); listIds.Add(btSource[pBlockName]); IdMapping mapping = new IdMapping(); dbSource.WblockCloneObjects(listIds, pBlockTable.ObjectId, mapping, DuplicateRecordCloning.Ignore, false); transSource.Commit(); return true; } } public static void InsertBlockReference(Database pToDatabase, BlockReference pBlockReference) { using (Transaction trans = pToDatabase.TransactionManager.StartTransaction()) { BlockTable bt = (BlockTable)trans.GetObject(pToDatabase.BlockTableId, OpenMode.ForWrite, false); BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite, false); btr.AppendEntity(pBlockReference); trans.AddNewlyCreatedDBObject(pBlockReference, true); BlockTableRecord blockTableRecordCopy = (BlockTableRecord)trans.GetObject(pBlockReference.BlockTableRecord, OpenMode.ForRead); IEnumerable<ObjectId> listAttributes = blockTableRecordCopy.GetAttributes(); foreach (ObjectId id in listAttributes) { AttributeDefinition attributeDefinition = (AttributeDefinition)trans.GetObject(id, OpenMode.ForRead); AttributeReference attributeReference = new AttributeReference(); attributeReference.SetAttributeFromBlock(attributeDefinition, pBlockReference.BlockTransform); pBlockReference.AttributeCollection.AppendAttribute(attributeReference); trans.AddNewlyCreatedDBObject(attributeReference, true); } trans.Commit(); } }
Hi,
thank you for your reply,
but i am not to want to import a blockdef and insert a blockref to 'current database'.
i want to new a database DB by code.
and import a blockdef and insert a blockref to 'DB'.
What about changing this line in the 'DB' you want:
Database db = HostApplicationServices.WorkingDatabase;new Database(false, true);
...
ObjectId blocoId = GetBlockIdWithCopyBlockTableRecord(db, dwgFileBlocks, blockName, out erro);
...
db.SaveAs(...)
Try this code:
public static void TestInsertBlockNewDatabase() { ////Use this code to copy block from another database and create and insert one blockreference in the current drawing Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; using (doc.LockDocument()) { using (Database db = new Database(true, false)) { //Put your file path here string dwgFileBlocks = "c:\\........"; string dwgToSave = "c:\\........"; //Name of block string blockName = "blockName"; //Point to insert block Point3d blockReferencePoint = new Point3d(0, 0, 0); string error; ObjectId blocoId = GetBlockIdWithCopyBlockTableRecord(db, dwgFileBlocks, blockName, out error); if (!blocoId.IsNull) { BlockReference blockReference = new BlockReference(blockReferencePoint, blocoId); InsertBlockReference(db, blockReference); db.SaveAs(dwgToSave, true, DwgVersion.AC1024, null); } else { Editor ed = acadApp.DocumentManager.MdiActiveDocument.Editor; ed.WriteMessage(Environment.NewLine + error); } } } }
Hi phliberato,
thanks so much, it's really works. i found the key method is as following
Database dbSource = new Database(false, true)
Database db = new Database(true, false)
i do not know the difference between the two lines.
regards
swaywood
The first parameter (buildDefaultDWG) is True when you are creating a new Database. If you are using ReadDwgFile you need to pass False.
The second parameter (noDocumento) is intended to indicate that the Database DWG file has no associated Document window.
Regards
swaywood wrote:
Database dbSource = new Database(false, true)
Database db = new Database(true, false)
i do not know the difference between the two lines.
From the ObjectARX SDK
From arxmgd.chm
From arxref.chm
// Called Kerry in my other life.
Everything will work just as you expect it to, unless your expectations are incorrect.
class keyThumper<T> : Lazy<T>; another Swamper
This answer was heaven sent because I just made a screen dump of the ObjectARX managed class reference guide to ask that very question - and Kerry Brown seems to have also done that!
Notice the second parameter - could anybody please clarify what is meant by it:
With all the help in the world, i still do not understand what is meant by the second parameter - any clarifications would be extremely appreciated.
rgds
BK
I can't recall seeing a definitive description of the full technical meaning of the noDocument parameter.
These may help in a small way.
http://adndevblog.typepad.com/autocad/2012/07/enoinputfiler-exception-when-using-readdwgfile.html
// Called Kerry in my other life.
Everything will work just as you expect it to, unless your expectations are incorrect.
class keyThumper<T> : Lazy<T>; another Swamper
and this gives couple more breadcrumbs.
Document-Independent Databases
// Called Kerry in my other life.
Everything will work just as you expect it to, unless your expectations are incorrect.
class keyThumper<T> : Lazy<T>; another Swamper