c# - Block insert loop error !dbobji.cpp@8638: eNotOpenForWrite -
c# - Block insert loop error !dbobji.cpp@8638: eNotOpenForWrite -
good day,
i'm creating programme few calculations , insert block @ point user clicks on, repeats calc , insert @ other point user clicks on until user cancels (see programme below).
the programme correctly @ first point user clicks on. yet sec time through while loop, after user clicks on point, programme causes fatal error , crashes autocad without inserting block, crash error message: “ internal error: !dbobji.cpp@8638: enotopenforwrite”.
would please go through , explain me problem is?
thank you,
using system; using autodesk.autocad.runtime; using autodesk.autocad.applicationservices; using autodesk.autocad.databaseservices; using autodesk.autocad.geometry; using autodesk.autocad.editorinput; using system.collections.generic; using system.linq; [assembly: commandclass(typeof(level_arrow.program))] namespace level_arrow { public class programme { [commandmethod("levelcalc")] public static void insertblock(string[] args) { document acdoc = application.documentmanager.mdiactivedocument; editor ed = acdoc.editor; database db = acdoc.database; transaction tr = db.transactionmanager.starttransaction(); promptstringoptions blkn1 = new promptstringoptions(""); blkn1.message = "\nspecify block name: "; blkn1.allowspaces = true; blkn1.defaultvalue = "level arrow"; promptresult blkn2 = ed.getstring(blkn1); string blkname = blkn2.stringresult.tostring(); blocktable bt = (blocktable)tr.getobject(db.blocktableid, openmode.forread); blocktablerecord btr = (blocktablerecord)tr.getobject(db.currentspaceid, openmode.forwrite); if (!bt.has(blkname)) { ed.writemessage("\nblock not found."); } else { blocktablerecord orgbtr = (blocktablerecord)tr.getobject(bt[blkname], openmode.forread); promptstringoptions poptsunitscale = new promptstringoptions(""); poptsunitscale.message = "\nenter drawing unit scale (m or mm): "; poptsunitscale.allowspaces = false; poptsunitscale.defaultvalue = "mm"; promptresult drgunitsres = ed.getstring(poptsunitscale); string drgunits = drgunitsres.stringresult.tolower(); promptdoubleoptions poptsdrgscale = new promptdoubleoptions(""); poptsdrgscale.message = "\nenter detail scale(1:_): "; promptdoubleresult drgscale = ed.getdouble(poptsdrgscale); double drgscalem = drgscale.value / 1000; double drgscalemm = drgscale.value; promptpointoptions ptbl = new promptpointoptions(""); ptbl.message = "\nindicate baseline: "; promptpointresult ptbaseline = ed.getpoint(ptbl); if (ptbaseline.status == promptstatus.cancel) return; double ybase = ptbaseline.value.y; promptdoubleoptions levelbl = new promptdoubleoptions(""); levelbl.message = "\nspecify baseline level: "; promptdoubleresult bllevel = ed.getdouble(levelbl); double bllevelmm = bllevel.value * 1000; double bllevelm = bllevel.value; blockreference insblkref; promptpointoptions ptins; scale3d blkscale; attributereference ar; int = 1; while (a == 1) { using (documentlock lckdoc = acdoc.lockdocument()) { using (tr) { ptins = new promptpointoptions(""); ptins.message = "\nspecify insertion point: "; promptpointresult ptinsert = ed.getpoint(ptins); if (ptinsert.status == promptstatus.cancel) return; double yinsert = ptinsert.value.y; double ptvar = yinsert - ybase; double ptlevel = 0; objectid bdid = bt[blkname]; point3d pt = ptinsert.value; insblkref = new blockreference(pt, bdid); insblkref.rotation = 0; if (drgunits == "mm") { ptlevel = (bllevelmm + ptvar) / 1000; blkscale = new scale3d(drgscalemm, drgscalemm, drgscalemm); insblkref.scalefactors = blkscale; } else if (drgunits == "m") { ptlevel = bllevelm + ptvar; blkscale = new scale3d(drgscalem, drgscalem, drgscalem); insblkref.scalefactors = blkscale; } double ptdisp = math.round(ptlevel, 3); btr.appendentity(insblkref); tr.addnewlycreateddbobject(insblkref, true); if (orgbtr.hasattributedefinitions) { foreach (objectid id in orgbtr) { dbobject obj = tr.getobject(id, openmode.forread); attributedefinition advertisement = obj attributedefinition; if (ad != null && !ad.constant) { ar = new attributereference(); ar.setattributefromblock(ad, insblkref.blocktransform); ar.position = ad.position.transformby(insblkref.blocktransform); if (ad.justify != attachmentpoint.baseleft) { ar.alignmentpoint.transformby(insblkref.blocktransform); } if (ar.ismtextattribute) { ar.updatemtextattribute(); } ar.textstring = ptdisp.tostring(); objectid arid = insblkref.attributecollection.appendattribute(ar); tr.addnewlycreateddbobject(ar, true); break; } } } tr.commit(); } //transaction end } //lock end insblkref = null; //tried "insblkref.dispose();" didn't work. } //while loop end } } } }
i think issue's line:
using (tr)
you declared tr earlier, , utilize later (on sec loop). you'd set using statement around declaration (i.e. replace transaction tr = db.transactionmanager.starttransaction();
using (transaction tr = db.transactionmanager.starttransaction())
.
the reason is, @ end of using block, variable passed in closed & disposed; meaning you're closing transaction before you're finished it.
c# .net autocad
Comments
Post a Comment