İnsert BlockJig Different Dwg Error

İnsert BlockJig Different Dwg Error

bedyr
Advocate Advocate
1,408 Views
10 Replies
Message 1 of 11

İnsert BlockJig Different Dwg Error

bedyr
Advocate
Advocate

I want insert a name of block but it is error all times. Can anybody help me?

 

 

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Internal;

namespace insertBlock
{
    class BlockJig : EntityJig
    {
        Point3d mCenterPt, mActualPoint;
        public BlockJig(BlockReference br) : base(br)
        {
            mCenterPt = br.Position;
        }
        protected override SamplerStatus Sampler(JigPrompts prompts)
        {
            JigPromptPointOptions jigOpts = new JigPromptPointOptions();
            jigOpts.UserInputControls = (UserInputControls.Accept3dCoordinates | UserInputControls.NoZeroResponseAccepted | UserInputControls.NoNegativeResponseAccepted);
            jigOpts.Message = "\nEnter insert point: ";
            PromptPointResult dres = prompts.AcquirePoint(jigOpts);
            if (mActualPoint == dres.Value)
            {
                return SamplerStatus.NoChange;
            }
            else
            {
                mActualPoint = dres.Value;
            }
            return SamplerStatus.OK;
        }
        protected override bool Update()
        {
            mCenterPt = mActualPoint;
            try
            {
                ((BlockReference)Entity).Position = mCenterPt;
            }
            catch (System.Exception)
            {
                return false;
            }
            return true;
        }
        public Entity GetEntity()
        {
            return Entity;
        }
    }
    public class Commands
    {
        [CommandMethod("BJIG")]
        public void CreateBlockWithJig()
        {          
            string fileName = "C:\\Users\\bedyr\\Desktop\\sembol\\sembol.dwg";
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            // First let's get the name of the block
            PromptStringOptions opts = new PromptStringOptions("\nEnter block name: ");
            PromptResult pr = ed.GetString(opts);
            if (pr.Status == PromptStatus.OK)
            {
                using (Transaction tr = doc.TransactionManager.StartTransaction())
                {
                    BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                    if (!bt.Has(pr.StringResult))
                    {
                        Database tmpDb = new Database(false, true);
                        tmpDb.ReadDwgFile(fileName, System.IO.FileShare.Read, true, "");
                        // add the block to the ActiveDrawing blockTable
                        db.Insert("pr.StringResult", tmpDb, true);

                        ObjectId blockId = bt[pr.StringResult];
                        // We loop until the jig is cancelled
                        while (pr.Status == PromptStatus.OK)
                        {
                            // Create the block reference and
                            // add it to the jig
                            Point3d pt = new Point3d(0, 0, 0);
                            BlockReference br = new BlockReference(pt, blockId);

                            // Start annot-scale support code
                            BlockTableRecord bd = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
                            // Using will dispose of the block definition
                            // when no longer needed
                            using (bd)
                            {
                                if (bd.Annotative == AnnotativeStates.True)
                                {
                                    ObjectContextManager ocm = db.ObjectContextManager;
                                    ObjectContextCollection occ = ocm.GetContextCollection("ACDB_ANNOTATIONSCALES");
                                    ObjectContexts.AddContext(br, occ.CurrentContext);
                                }
                            }
                            // End annot-scale support code
                            BlockJig entJig = new BlockJig(br);
                            // Perform the jig operation
                            pr = ed.Drag(entJig);
                            if (pr.Status == PromptStatus.OK)
                            {
                                // If all is OK, let's go and add the
                                // entity to the modelspace
                                BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                                ms.AppendEntity(entJig.GetEntity());
                                tr.AddNewlyCreatedDBObject(entJig.GetEntity(), true);
                                // Start attribute support code
                                bd = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
                                // Add the attributes
                                foreach (ObjectId attId in bd)
                                {
                                    Entity ent = (Entity)tr.GetObject(attId, OpenMode.ForRead);
                                    if (ent is AttributeDefinition)
                                    {
                                        AttributeDefinition ad = (AttributeDefinition)ent;
                                        AttributeReference ar = new AttributeReference();
                                        ar.SetAttributeFromBlock(ad, br.BlockTransform);
                                        br.AttributeCollection.AppendAttribute(ar);
                                        tr.AddNewlyCreatedDBObject(ar, true);
                                    }
                                }
                                // End attribute support code
                                // Call a function to make the graphics display
                                // (otherwise it will only do so when we Commit)
                                doc.TransactionManager.QueueForGraphicsFlush();
                            }
                        }
                        
                    }
                    tr.Commit();
                }                
            }
        }       
    }    
}
0 Likes
Accepted solutions (1)
1,409 Views
10 Replies
Replies (10)
Message 2 of 11

norman.yuan
Mentor
Mentor

Firstly, it is really more appropriate that you describe what error you got, what debugging effort you did, with which you would easily know what is wrong in most cases, which also indicate you do know the code is intended to do. Posting a big chunck of code and let other guess what/where is wrong would discourage people's interest.

 

Here is my answer to your "online" test:

 

in this snippet of code

 

                        Database tmpDb = new Database(false, true);
                        tmpDb.ReadDwgFile(fileName, System.IO.FileShare.Read, true, "");
                        // add the block to the ActiveDrawing blockTable
                        db.Insert("pr.StringResult", tmpDb, true);

                        ObjectId blockId = bt[pr.StringResult];

 

either the db.Insert(...) causes the error, because the inserted block definition is given an invalid block name (with invalid character '.' in it). However, if my memory serves me correct, when a invalid character is used in block name in Database.Insert() method, AutoCAD does not raise exception, rather it goes a head to create the block definition and give the blcok definition a blank name, effectively make this block definition not usable (this could be AutoCAD API bug, IMO).

 

So, even the db.Insert(...) does not staop the execution, the next line would definitely raise error, becuase the block name entered by user, which is stored in pr.StringResult, is unlikely be "pr.StringResult".

 

Hopefully, I would score on this test.

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 3 of 11

_gile
Consultant
Consultant

Hi

 

pr.StringResult shouldn't be quoted an you should not ask the user for a block name if you load a specific DWG (hard coded filename).

 

EDIT: @norman.yuan was faster and gave a better reply.


bedyr a écrit :

I want insert a name of block but it is error all times. Can anybody help me?

 

 

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Internal;

namespace insertBlock
{
    class BlockJig : EntityJig
    {
        Point3d mCenterPt, mActualPoint;
        public BlockJig(BlockReference br) : base(br)
        {
            mCenterPt = br.Position;
        }
        protected override SamplerStatus Sampler(JigPrompts prompts)
        {
            JigPromptPointOptions jigOpts = new JigPromptPointOptions();
            jigOpts.UserInputControls = (UserInputControls.Accept3dCoordinates | UserInputControls.NoZeroResponseAccepted | UserInputControls.NoNegativeResponseAccepted);
            jigOpts.Message = "\nEnter insert point: ";
            PromptPointResult dres = prompts.AcquirePoint(jigOpts);
            if (mActualPoint == dres.Value)
            {
                return SamplerStatus.NoChange;
            }
            else
            {
                mActualPoint = dres.Value;
            }
            return SamplerStatus.OK;
        }
        protected override bool Update()
        {
            mCenterPt = mActualPoint;
            try
            {
                ((BlockReference)Entity).Position = mCenterPt;
            }
            catch (System.Exception)
            {
                return false;
            }
            return true;
        }
        public Entity GetEntity()
        {
            return Entity;
        }
    }
    public class Commands
    {
        [CommandMethod("BJIG")]
        public void CreateBlockWithJig()
        {          
            string fileName = "C:\\Users\\bedyr\\Desktop\\sembol\\sembol.dwg";
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            // First let's get the name of the block
            PromptStringOptions opts = new PromptStringOptions("\nEnter block name: ");
            PromptResult pr = ed.GetString(opts);
            if (pr.Status == PromptStatus.OK)
            {
                using (Transaction tr = doc.TransactionManager.StartTransaction())
                {
                    BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                    if (!bt.Has(pr.StringResult))
                    {
                        Database tmpDb = new Database(false, true);
                        tmpDb.ReadDwgFile(fileName, System.IO.FileShare.Read, true, "");
                        // add the block to the ActiveDrawing blockTable
                        db.Insert("pr.StringResult", tmpDb, true);

                        ObjectId blockId = bt[pr.StringResult];
                        // We loop until the jig is cancelled
                        while (pr.Status == PromptStatus.OK)
                        {
                            // Create the block reference and
                            // add it to the jig
                            Point3d pt = new Point3d(0, 0, 0);
                            BlockReference br = new BlockReference(pt, blockId);

                            // Start annot-scale support code
                            BlockTableRecord bd = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
                            // Using will dispose of the block definition
                            // when no longer needed
                            using (bd)
                            {
                                if (bd.Annotative == AnnotativeStates.True)
                                {
                                    ObjectContextManager ocm = db.ObjectContextManager;
                                    ObjectContextCollection occ = ocm.GetContextCollection("ACDB_ANNOTATIONSCALES");
                                    ObjectContexts.AddContext(br, occ.CurrentContext);
                                }
                            }
                            // End annot-scale support code
                            BlockJig entJig = new BlockJig(br);
                            // Perform the jig operation
                            pr = ed.Drag(entJig);
                            if (pr.Status == PromptStatus.OK)
                            {
                                // If all is OK, let's go and add the
                                // entity to the modelspace
                                BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                                ms.AppendEntity(entJig.GetEntity());
                                tr.AddNewlyCreatedDBObject(entJig.GetEntity(), true);
                                // Start attribute support code
                                bd = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
                                // Add the attributes
                                foreach (ObjectId attId in bd)
                                {
                                    Entity ent = (Entity)tr.GetObject(attId, OpenMode.ForRead);
                                    if (ent is AttributeDefinition)
                                    {
                                        AttributeDefinition ad = (AttributeDefinition)ent;
                                        AttributeReference ar = new AttributeReference();
                                        ar.SetAttributeFromBlock(ad, br.BlockTransform);
                                        br.AttributeCollection.AppendAttribute(ar);
                                        tr.AddNewlyCreatedDBObject(ar, true);
                                    }
                                }
                                // End attribute support code
                                // Call a function to make the graphics display
                                // (otherwise it will only do so when we Commit)
                                doc.TransactionManager.QueueForGraphicsFlush();
                            }
                        }
                        
                    }
                    tr.Commit();
                }                
            }
        }       
    }    
}

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 4 of 11

bedyr
Advocate
Advocate

Actually, I created a windows form and using select blockname on listbox and insert block but it is error on (pr.StringResult).

0 Likes
Message 5 of 11

_gile
Consultant
Consultant

bedyr a écrit :

Actually, I created a windows form and using select blockname on listbox and insert block but it is error on (pr.StringResult).


So, the code you provided is not the the one throwing the error?

Sorry, but I cannot keep on trying to help you if you do not clearly describe the circumstances the error occur.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 6 of 11

ActivistInvestor
Mentor
Mentor

@bedyr wrote:

Actually, I created a windows form and using select blockname on listbox and insert block but it is error on (pr.StringResult).


It seems that rather than spending the time learning to use the tools, you are trying to adapt code you found somewhere, without really understanding it, or how it works. That usually doesn't work. You posted an image of a Windows Form, but you don't show the code behind it, but are expecting others here to tell you what's wrong with that code.

 

I'd suggest spending more time on smaller, less-complicated tasks until you've learned to use the tools, or at least post the code that you are having problems with.

0 Likes
Message 7 of 11

bedyr
Advocate
Advocate

I never think of asking a question from now on. Because when I asked a question I did not get a straight answer. I asked a question yesterday. why did you write the whole code so that you can not do it with the codes you find from right to left. But nobody answered the charge. I wrote the whole code, because I wrote it so that you could copy the code and try it yourself and see the error with your own eyes. I have added a picture of the windows form. He was said that you did not write the codes at this time. Do you know how many videos I watched and how much research did I do to find out that you judge me? I'm learning both C # and AutoCAD programming, but you're cooling me off doing it. The whole forum is yours. I do not write again. Thank you for your answers. have a nice day.

0 Likes
Message 8 of 11

fieldguy
Advisor
Advisor
Accepted solution

bedyr - you got the straight answer twice at least. the code your not showing is the form definition. how do you get from your form to the jig? from the form pic that you provided, it looks like you would select "listBox1" and click "Insert".  Find these lines in the code you posted:

 

// add the block to the ActiveDrawing blockTable
db.Insert("pr.StringResult", tmpDb, true);

The response from your form would have to be "pr.stringresult" for this to work.  according to the form pic the response can only be "listBox1", but that will still fail - you have to check if you have a block in your dwg called listbox1.

 

i'm guessing that "sembol.dwg" contains blocks that you want to access from your form and insert into the current dwg. that has been discussed in the public domain 100's of times.

https://forums.autodesk.com/t5/net/insert-block-from-another-file/m-p/3527080#M29767

https://forums.autodesk.com/t5/net/insert-block-from-block-container-file/m-p/2933384#M22721

http://through-the-interface.typepad.com/through_the_interface/2009/03/jigging-an-autocad-block-with...

 

This is a public forum and the people who replied before provide excellent answers. the code your looking for is in the forum already - or searchable using google. if it is apparent from your code, questions & replies that you have not learned the basics, or done the research, that is your problem - not the participants here. developing applications for autocad using the managed apis is not a trivial task.

Message 9 of 11

bedyr
Advocate
Advocate
Thank you fieldguy. I got answer. Yes my dwg has any blocks any. I am adding that blocks code
listbox.item.add(blocktablerecord.name);
And I want to get pr.stringresult. I can do I think.
0 Likes
Message 10 of 11

ActivistInvestor
Mentor
Mentor

@bedyr wrote:

I never think of asking a question from now on. Because when I asked a question I did not get a straight answer. I asked a question yesterday. why did you write the whole code so that you can not do it with the codes you find from right to left. But nobody answered the charge. I wrote the whole code, because I wrote it so that you could copy the code and try it yourself and see the error with your own eyes. I have added a picture of the windows form. He was said that you did not write the codes at this time. Do you know how many videos I watched and how much research did I do to find out that you judge me? I'm learning both C # and AutoCAD programming, but you're cooling me off doing it. The whole forum is yours. I do not write again. Thank you for your answers. have a nice day.


You didn't write the whole code yourself. That is obvious from the comments that you left in the code, which makes it clear that you didn't write it. It is an example that you found somewhere on the internet (my guess - throughtheinterface), and you are trying to use it without knowing very much about how it works. The error in the code is so basic that it could only be made by someone with almost no programming experience at all. Being inexperienced is not a crime, but expecting others here to copy and paste your code and compile and run it, is expecting too much.  Besides that, no one has to do that to point out the error. Even after you were shown what was wrong with the code and how to fix it, you still couldnt' get it working, because the other problem is not in the code you posted, it is in the code behind your form, which you only provided a screenshot of, but not the code behind it.

 

If you don't ask a straight question, and don't include the information needed to give you an answer, you will not get a straight answer, from me or anyone else, because we are not mind-readers and we do not care to spend our time guessing about what is wrong with the code you didn't bother to show.

 

 

 

Message 11 of 11

_gile
Consultant
Consultant

Hi,

 

I agree with @ActivistInvestor, you should first focus on some basics features and logic of your algorithm.

The error pointed by @norman.yuan and I occurs in the most basic tasks of your code (nothing to do with annotative scale, inserting attribute references, jigging during insertion or getting data from with a form).

 

// here, filename is hard coded (i.e.: it has nothing to do with user inputs)
string fileName = "C:\\Users\\bedyr\\Desktop\\sembol\\sembol.dwg";
Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor;
// here, you prompt the user for a block name PromptStringOptions opts = new PromptStringOptions("\nEnter block name: ");
PromptResult pr = ed.GetString(opts); if (pr.Status == PromptStatus.OK) { using (Transaction tr = doc.TransactionManager.StartTransaction()) { BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); if (!bt.Has(pr.StringResult)) { Database tmpDb = new Database(false, true); tmpDb.ReadDwgFile(fileName, System.IO.FileShare.Read, true, "");
// here, you add a new block to the block table which is literally named "pr.StringResult" and // contains sembol.dwg model space entities (see @norman.yuan reply about invalid symbol names). db.Insert("pr.StringResult", tmpDb, true);
// here, you affect to blockId variable, the ObjectId of the block definition // named as pr.StringResult value which does not exist in the block table ObjectId blockId = bt[pr.StringResult]; // blockId == ObjectId.Null
// ... }
// ... } // here, there's no code, that's to say you do nothing if the block table
// already contains a block named as pr.StringResult value }


 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes