Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: simson43 от 02-09-2018, 09:48:45

Название: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: simson43 от 02-09-2018, 09:48:45
Код - C# [Выбрать]
  1. BlockTableRecord lyy;
  2.  
  3.                     foreach (DBDictionaryEntry ly in dbl)
  4.                     {
  5.                         lyy = ly.Value.GetObject(OpenMode.ForWrite) as BlockTableRecord;
  6.                         lyy.AppendEntity(ci);
  7.                         tr.AddNewlyCreatedDBObject(ci, true);
  8.                     }
ругается! на строчку где добавляю объект ci. якобы ссылаюсь на lyy и он пустой.
подозреваю что здесь - lyy = ly.Value.GetObject(OpenMode.ForWrite) as BlockTableRecord; - что то не так сделал.
в чем проблема?
спасибо
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: Владимир Шу от 02-09-2018, 10:24:34
По тому огрызку кода, который Вы показали, вообще не понятно что такое ci, как оно было создано и с какой стати должно добавляться.
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: simson43 от 02-09-2018, 10:28:24
По тому огрызку кода, который Вы показали, вообще не понятно что такое ci, как оно было создано и с какой стати должно добавляться.

Код - C# [Выбрать]
  1. Circle ci = new Circle();
  2.             ci.Center = new Point3d(0, 0, 0);
  3.             ci.Radius = 5;
проблема не в нем. пробовал просто выводить имя листа на каждом листе. ошибка та же. будто lyy пустой
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: Владимир Шу от 02-09-2018, 10:46:35
Я намекал, что надо бы весь смысловой кусок кода показывать... гадать по кусочкам бесполезно.
что такое dbl, почему Вы открываете объект не через транзакцию ( а она у Вас вроде как есть.. tr), да тут много чего не понятно...

Вы бы код вложили и пояснили чего хотите добиться.
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: simson43 от 02-09-2018, 10:52:41
Код - C# [Выбрать]
  1.  private void buttonFind_Click(object sender, EventArgs e)
  2.         {
  3.             Document doc = App.DocumentManager.MdiActiveDocument;
  4.             Database db = doc.Database;
  5.  
  6.             Circle ci = new Circle();
  7.             ci.Center = new Point3d(0, 0, 0);
  8.             ci.Radius = 5;
  9.  
  10.             using (DocumentLock dl = doc.LockDocument())
  11.             {
  12.                 using (Transaction tr = doc.TransactionManager.StartTransaction())
  13.                 {
  14.                     BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
  15.                    
  16.                     DBDictionary dbl = tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
  17.  
  18.                     BlockTableRecord lyy;
  19.                     foreach (DBDictionaryEntry ly in dbl)
  20.                     {
  21.                         lyy = ly.Value.GetObject(OpenMode.ForWrite) as BlockTableRecord;
  22.                         lyy.AppendEntity(ci);
  23.                         tr.AddNewlyCreatedDBObject(ci, true);
  24.                     }
  25.                     tr.Commit();
  26.                 }
  27.             }
  28.         }

хочу добраться до пространства каждого листа
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: Владимир Шу от 02-09-2018, 11:17:53
активнее пользуйтесь отладчиком и если не знаете какого типа объект Вам вернет система, используйте DBObject с последующем приведением к нужному типу.
Код - C# [Выбрать]
  1.         private static void buttonFind_Click()
  2.         {
  3.             App.Document doc = App.Application.DocumentManager.MdiActiveDocument;
  4.             Db.Database db = doc.Database;
  5.  
  6.             //Db.Circle ci = new Db.Circle();
  7.             //ci.Center = new Gem.Point3d(0, 0, 0);
  8.             //ci.Radius = 5;
  9.  
  10.             using (App.DocumentLock dl = doc.LockDocument())
  11.             {
  12.                 using (Db.Transaction tr = doc.TransactionManager.StartTransaction())
  13.                 {
  14.                     //Db.BlockTable bt = tr.GetObject(db.BlockTableId,Db. OpenMode.ForRead) as Db.BlockTable;
  15.                     Db.DBDictionary dbl = tr.GetObject(db.LayoutDictionaryId, Db.OpenMode.ForRead) as Db.DBDictionary;
  16.  
  17.                     foreach (Db.DBDictionaryEntry ly in dbl)
  18.                     {
  19.                         //lyy = ly.Value.GetObject(Db.OpenMode.ForWrite) as Db.BlockTableRecord;
  20.                         //lyy.AppendEntity(ci);
  21.                         //tr.AddNewlyCreatedDBObject(ci, true);
  22.  
  23.                         Db.Layout lout = tr.GetObject(ly.Value, Db.OpenMode.ForRead) as Db.Layout;
  24.                         Db.BlockTableRecord lyy = tr.GetObject(lout.BlockTableRecordId, Db.OpenMode.ForWrite) as Db.BlockTableRecord;
  25.  
  26.                         Db.Circle ci = new Db.Circle();
  27.                         ci.Center = new Gem.Point3d(0, 0, 0);
  28.                         ci.Radius = 5;
  29.  
  30.                         lyy.AppendEntity(ci);
  31.                         tr.AddNewlyCreatedDBObject(ci, true);
  32.                     }
  33.                     tr.Commit();
  34.                 }
  35.             }
  36.         }
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: simson43 от 02-09-2018, 12:00:37
я просто поместил создание окружности в цикл и все заработало. почему?
зачем ее объявлять в каждой итерации? разве нельзя один раз а потом просто вставлять везде?
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: Владимир Шу от 02-09-2018, 12:21:44
я просто поместил создание окружности в цикл и все заработало. почему?
Вот и мне интересно, почему. В строчке:
lyy = ly.Value.GetObject(OpenMode.ForWrite) as BlockTableRecord;
Вы объект типа Layout приводите к типу BlockTableRecord и закономерно получаете null и как перенос только создания окружности помог Вам сделать код рабочим.... загадка.

зачем ее объявлять в каждой итерации? разве нельзя один раз а потом просто вставлять везде?
Нельзя. Вам ведь нужен не один объект, а по объекту на каждом листе, т.е. много объектов, вот и создавайте эти объекты.
Если очень грубо: Когда Вы создали объект, под него был выделен некий диапазон в памяти, когда Вы добавили этот объект в базу чертежа, автокад пометил, что объект из этой области(с этим адресом) уже добавлен в базу чертежа и второй раз его не добавит, т.к. он уже есть.
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: simson43 от 02-09-2018, 12:30:19
все разобрался! спасибо большое!
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: simson43 от 02-09-2018, 12:33:29
Вы объект типа Layout приводите к типу BlockTableRecord и закономерно получаете null и как перенос только создания окружности помог Вам сделать код рабочим.... загадка.
да это я в другом методе вставил. там через перебор в blocktable добрался до каждого листа и вставил окружности. но этому методу все мое нутро сопротивлялось ибо приходится перебирать все блоки в чертеже, а на больших чертежах это впустую потраченные ресурсы я считаю и драгоценное время.
вот искал другой способ.
нашел! спасибо)
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: simson43 от 02-09-2018, 12:40:20
а вот еще вопрос.
а можно ли их перебирать не foreach a for?
от 0 до количества листов?
для этого нужно подобие item
есть здесь такое?
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: Владимир Шу от 02-09-2018, 13:08:34
Можно конечно, но вот смысла в это маловато. =о)
Код - C# [Выбрать]
  1.                     Db.DBDictionary dbl = tr.GetObject(db.LayoutDictionaryId, Db.OpenMode.ForRead) as Db.DBDictionary;
  2.  
  3.                     List<Db.ObjectId> listLoutsId = new List<Db.ObjectId>();
  4.                     foreach(Db.DBDictionaryEntry ly in dbl)
  5.                         listLoutsId.Add(ly.Value);
  6.  
  7.                     for (int i = 0; i < dbl.Count; i++)
  8.                     {
  9.                         Db.Layout lout = tr.GetObject(listLoutsId[i], Db.OpenMode.ForRead) as Db.Layout;
  10.                         Db.BlockTableRecord lyy = tr.GetObject(lout.BlockTableRecordId, Db.OpenMode.ForWrite) as Db.BlockTableRecord;
  11.  
  12.                         Db.Circle ci = new Db.Circle();
  13.                         ci.Center = new Gem.Point3d(0, 0, 0);
  14.                         ci.Radius = 5;
  15.  
  16.                         lyy.AppendEntity(ci);
  17.                         tr.AddNewlyCreatedDBObject(ci, true);
  18.  
  19.                     }
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: simson43 от 02-09-2018, 13:25:02
Смысл в этом есть. Просто нужно в зависимомти от ввода пользователя залазить в конкретные листы. Спасибо
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: Владимир Шу от 02-09-2018, 13:31:16
в зависимомти от ввода пользователя залазить в конкретные листы
Код - C# [Выбрать]
  1. Db.Layout lout = tr.GetObject(dbl.GetAt("LayoutName"), Db.OpenMode.ForRead) as Db.Layout;
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: simson43 от 02-09-2018, 13:43:31
Названия листов неивестны. Или все листы или только модель или все все все. Номерами самое оптимальное ро моему.
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: Александр Ривилис от 02-09-2018, 15:17:37
simson43,
Внимательно прочитайте у меня в подписи как следует форматировать код для форума и неуклонно соблюдайте это правило!
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: Александр Ривилис от 02-09-2018, 15:18:31
Номерами самое оптимальное ро моему.
Нет. Пользователь может их перетасовать.
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: simson43 от 02-09-2018, 15:54:39
Главное что 0 всегда модель. Отальное не интересует
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: Александр Ривилис от 02-09-2018, 16:05:39
Главное что 0 всегда модель. Отальное не интересует
Теоретически и это может быть не так. Во всяком случае я знаю как сделать модель не 0-ой. Но если тебе так нравится, то можешь считать, что модель 0-ая.
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: Владимир Шу от 02-09-2018, 16:06:06
Так если Вам нужна была ссылка на модель, то все гораздо проще:
Код - C# [Выбрать]
  1. ObjectId ModelSpaceId =SymbolUtilityServices.GetBlockModelSpaceId(db);
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: simson43 от 02-09-2018, 16:10:35
А также на все листы.
Как сделать модель не 0?
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: Александр Ривилис от 02-09-2018, 16:11:28
Как сделать модель не 0?
Зачем это тебе?
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: simson43 от 02-09-2018, 16:12:17
Интересно. В каких случаях мой код будет ошибаться
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: Александр Ривилис от 02-09-2018, 16:13:57
Интересно. В каких случаях мой код будет ошибаться
Прочитай про DBObject.SwapIdWith
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: simson43 от 02-09-2018, 16:15:19
Хорошо. Спасибо.
Ну а допустим я отдельно доберусь до модели.
А как я отдельно доберусь до всех листов но не до модели? Если она вдруг не 0
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: Александр Ривилис от 02-09-2018, 16:17:58
А как я отдельно доберусь до всех листов но не до модели? Если она вдруг не 0
Если ты объяснишь толком что тебе нужно, то ответ найдётся обязательно. А так понять какие у тебя исходные данные и что нужно получить - невозможно...
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: simson43 от 02-09-2018, 22:44:38
Прочитай про DBObject.SwapIdWith
не думаю что кому то приходит в голову поменять id модели на другой..
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: simson43 от 02-09-2018, 23:06:22
List<Db.ObjectId> listLoutsId = new List<Db.ObjectId>();
                    foreach(Db.DBDictionaryEntry ly in dbl)
                        listLoutsId.Add(ly.Value);
решение хорошее) спасибо)
но по моему тут было что то вроде elementAt изначально.. куда делся этот вариант? я вообще не могу подобного метода найти
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: Александр Ривилис от 03-09-2018, 00:12:16
Прочитай про DBObject.SwapIdWith
не думаю что кому то приходит в голову поменять id модели на другой..
То что ты так не думаешь не означает, что это не произойдет.
Название: Re: C# ссылка на объект не указывает на экземпляр объекта
Отправлено: Владимир Шу от 03-09-2018, 06:11:51
что то вроде elementAt изначально
LINQ. там по сути то же самое было, но теперешний вариант лучше.