Если второй раз считать блок из файла, то он не находится?!

Автор Тема: Если второй раз считать блок из файла, то он не находится?!  (Прочитано 7543 раз)

0 Пользователей и 3 Гостей просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн BadimАвтор темы

  • ADN OPEN
  • Сообщений: 16
  • Карма: 0
Старался в заголовке отразить суть проблемы

Autocad 2015
C#

Есть два файла dwg. в 1 содержатся некие эталонные боки: "блок1", "блок2", "блок3", и т.д.
во 2 файл эти блоки копируются и помещаются в нужные места.

все было замечательно, пока небыло повторов

если надо скопировать блоки: "блок1" и "блок2", "блок3" тогда все ок

но если надо повторы: "блок1", "блок2", "блок1" тогда программа находит первый блок, копирует его, а второй раз его же не находит
будут найдены и скопированы: "блок1", "блок2".  Повторение "блок1" - будет пропущен

вот фрагмент с поиском:

Код - C# [Выбрать]
  1.  // Создаём переменную, в которой будем хранить идентификаторы нужных нам определений блоков
  2.                         ObjectIdCollection blockIds = new ObjectIdCollection();
  3.  
  4.                         using (Transaction t = sourceDb.TransactionManager.StartTransaction())
  5.                         {
  6.                                     // Открываем таблицу блоков
  7.                                     BlockTable bt = (BlockTable)t.GetObject(sourceDb.BlockTableId, OpenMode.ForRead, false);
  8.  
  9.                                 ObjectId btrIdAux;
  10.                         for (int i = 0; i< 5; i++)
  11.                         {
  12.                             if (bt.Has(myArr[i,2])) // myArr - содержит названия блоков, например myArr[0,2] - "блок1", myArr[1,2] - "блок2"
  13.                             {
  14.                                 btrIdAux = bt[myArr[i, 2]];
  15.                                 // получаем запись таблицы блоков
  16.                                 BlockTableRecord btr = (BlockTableRecord)t.GetObject(btrIdAux, OpenMode.ForWrite);
  17.                                 btr.Name = myArr[i, 1];
  18.                                 blockIds.Add(btrIdAux);
  19.                             }
  20.                         }
  21.                                     // Копируем определения блоков в нужную нам базу данных
  22.                                     IdMapping mapping = new IdMapping();
  23.                                     sourceDb.WblockCloneObjects(blockIds, targetDb.BlockTableId, mapping, behaviour, false);

массив  myArr
выглядит примерно так
 myArr[0,2] - "блок1",
myArr[1,2] - "блок2"
 myArr[2,2] - "блок3",
myArr[3,2] - "блок1"

проверка на наличие нужного блока в 12 строчке, и при указанном массиве
 myArr[0,2] - "блок1",
myArr[1,2] - "блок2"
 myArr[2,2] - "блок3", - будет скопирован,
myArr[3,2] - "блок1" - будет пропущен

никак не могу понять почему  if (bt.Has(myArr[i,2])) не видит повторы ?

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
но если надо повторы: "блок1", "блок2", "блок1" тогда программа находит первый блок, копирует его, а второй раз его же не находит
А зачем дублировать определения блоков?
Как могут быть два определения блока с одинаковыми именами в одной базе данных?
В общем, похоже, что Вы что-то недопонимаете.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
никак не могу понять почему  if (bt.Has(myArr[i,2])) не видит повторы ?
А как он может видеть повторы, если ты проверяешь наличие в чертеже-источнике (sourceDb), а не в чертеже-приёмнике (targetDb)?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн BadimАвтор темы

  • ADN OPEN
  • Сообщений: 16
  • Карма: 0
А как он может видеть повторы, если ты проверяешь наличие в чертеже-источнике (sourceDb), а не в чертеже-приёмнике (targetDb)?
ну все правильно
мне надо считать в чертеже-источнике два раза один и тот же блок и потом разместить в разные места чертежа-приемника

Оффлайн BadimАвтор темы

  • ADN OPEN
  • Сообщений: 16
  • Карма: 0
А зачем дублировать определения блоков?
Как могут быть два определения блока с одинаковыми именами в одной базе данных?
до дублирования как раз дело не доходит.

затык как раз пока считываются блоки. Программе должно же быть все равно сколько раз читали один и тот же блок.

Вот когда их будем записывать в чертеж-приемник, тогда можно и подумать дублировать или не дублировать.

Получается у чертежа-источника источника спрашивают: есть "блок1" ?, он говорит есть, а когда второй раз спрашивают говорит нет!
пока еще ничего не пишем только спрашиваем...   (   if (bt.Has(myArr[i,2]))    )

Оффлайн BadimАвтор темы

  • ADN OPEN
  • Сообщений: 16
  • Карма: 0
если не разберусь в затыке,
придется логику писать на чтение:  -  "если такой блок уже спрашивали, то тогда возьми ответ из предыдущего вопроса"

нехочется

Оффлайн RevitTormentor

  • ADN OPEN
  • ***
  • Сообщений: 162
  • Карма: 6
Предлагаю проверить не в таблице.
Считать из первой базы нужные блоки без повторов в промежуточный массив, лучше в List (если можно). А потом уже из временного выдёргивать блоки в том порядке в котором делаете запрос, в том числе и с повторами, в массив или List который и запишете в новую базу.

Отмечено как Решение Badim 26-12-2017, 13:19:53

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Badim
Видимо ты пока совершенно не понимаешь что делаешь и каковы последствия этого.
Постараюсь объяснить на пальцах. Ты проверяешь в таблице блоков есть ли там блок с именем myArr[i,2]. После этого ты этот блок переименовываешь ( btr.Name = myArr[i, 1] ). Как ты можешь рассчитывать, что потом блок со старым именем найдётся???
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн BadimАвтор темы

  • ADN OPEN
  • Сообщений: 16
  • Карма: 0
Badim
После этого ты этот блок переименовываешь ( btr.Name = myArr[i, 1] ). Как ты можешь рассчитывать, что потом блок со старым именем найдётся???

я забыл, что переименовываю блок,
мне он потом нужен под другим именем

большое спасибо, что указали на мою невнимательность

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
мне он потом нужен под другим именем
А это лучше вообще делать в другой транзакции...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн BadimАвтор темы

  • ADN OPEN
  • Сообщений: 16
  • Карма: 0
А это лучше вообще делать в другой транзакции...
никак не могу сообразить как прикрутить вторую транзацию

в первой транзакции
читаем чертеж-исходник
ищем нужные блоки
записываем все идентификаторы нужных блоков в переменную

осталось подменить название
и записать в чертеж-приемник

а как тут вторая транзакция ...

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Если опишешь подробно что тебе нужно получить - попробую объяснить алгоритм. В первом сообщении вроде бы написано что нужно, но то что написано дальше явно этому противоречит.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн BadimАвтор темы

  • ADN OPEN
  • Сообщений: 16
  • Карма: 0
заранее спасибо

Задача
есть чертеж-источник с эталонными блоками, (в нем все возможные варианты) поиск по имени блока: Деталь1, Заготовка1, Деталь2, и т.д.

есть чертеж-приемник
в нем есть динамический большой блок. В состав большого блока уже включены 5 будущих блоков с заранее заготовленными именами: Блок1, Блок2, и т.д.
Большой блок в зависимости от ситуации может менятся (динамический) и координаты вложенных блоков меняются соответственно.
Также могут менятся блоки, которые надо поместить в большой блок.
в чертеже-приемнике текстом заносятся названия нужных блоков

Решение.
1. Считать какие блоки нужны из чертежа-приемника
2. Найти их в чертеже-источнике
3. Скопировать найденное базу блоков чертежа-приемника, но поменять имена:
пример считать Деталь1 - перименовать в Блок1
считать Заготовка1 - переименовать Блок2
и т.д.
в результате в чертеже изменится начертание блоков: Блок1, Блок2, ... и Автокад обновит все вхождения данных блоков

в результате у нас будет наш Большой блок состоящий из тех же мелких блоков(Блок1, Блок2, ...), но мелкие блоки уже будут иметь нужное нам изображение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
1. Составляешь коллекцию blockIds для BlockTableRecor'ов из базы-источника, которые следует скопировать.
2. Копируешь их в базу-приемник при помощи sourceDb.WblockCloneObjects
3. В mapping у тебя уже есть ObjectId для скопированных блоков (BlockTableRecord). Вот их в новой транзакции ты можешь открыть и переименовать если в этом есть смысл.
4. Проходишься по вставкам своих старых блоков в базе-приемнике и меняешь в них свойство BlockTableRecord на ObjectId соответствующей скопированной BlockTableRecord. Это тоже лучше делать в отдельной транзакции.
Это всё если я правильно понял постановку задачи, которая лично мне кажется очень странной.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение