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

ADN Club => AutoCAD .NET API => Тема начата: Борис_С от 01-12-2020, 17:58:00

Название: Как удалить поле из однострочного текста
Отправлено: Борис_С от 01-12-2020, 17:58:00
Добрый день!
Подскажите, п-ста, как удалить поле из однострочного текста.
Спасибо.
Название: Re: Как удалить поле из однострочного текста
Отправлено: Александр Ривилис от 01-12-2020, 18:13:32
DBObject.RemoveField() ?
Или DBText.ConvertFieldToText, которая превращает в обычный текст и удаляет поле.
Название: Re: Как удалить поле из однострочного текста
Отправлено: Борис_С от 01-12-2020, 18:21:10
Как я понимаю, DBText.ConvertFieldToText удаляет все поля и превращает их в текст.
А если нужно удалить одно поле и превратить его в текст?
Название: Re: Как удалить поле из однострочного текста
Отправлено: Александр Ривилис от 01-12-2020, 18:26:32
А если нужно удалить одно поле и превратить его в текст?
Тогда наверное DBObject.RemoveField(ObjectId idField). Попробуй.
Есть еще Field.FindField которое позволяет найти позицию поля внутри текста. Если его вырезать, а вместо его вставить Field.Value, то наверное будет то, что тебе нужно.
Название: Re: Как удалить поле из однострочного текста
Отправлено: Борис_С от 01-12-2020, 19:33:47
Написал такой код:
Код - C# [Выбрать]
  1.                     using (DBText text = acTrans.GetObject(acObjId, OpenMode.ForWrite) as DBText)
  2.                     {
  3.                         if (text.HasFields)
  4.                         {
  5.                             ObjectId FieldId = text.GetField();
  6.                             field = acTrans.GetObject(FieldId, OpenMode.ForRead) as Field;
  7.                             ObjectId[] objectIds = field.GetChildrenIds();
  8.                             for (int i = 0; i < objectIds.Length; i++)
  9.                             {
  10.                                 field = acTrans.GetObject(objectIds[i], OpenMode.ForRead) as Field;
  11.                                 if (field != null && field.HyperLink != null)
  12.                                 {
  13.                                     DBObject dBObject = ((DBObject)text);
  14.                                     dBObject.RemoveField(objectIds[i]);
  15.                                     break;
  16.                                 }
  17.                             }
  18.                         }
  19.                     }
  20.  
На операторе dBObject.RemoveField(objectIds); происходит исключение eKeyNotFound
Где я не прав?
Название: Re: Как удалить поле из однострочного текста
Отправлено: Александр Ривилис от 02-12-2020, 01:59:35
Борис_С,
Увы, но способа удалять поля по одному я не нашел и очень похоже, что их и нет.
Название: Re: Как удалить поле из однострочного текста
Отправлено: Борис_С от 02-12-2020, 12:02:56
Если я не вру, то это означает, что в API ошибка. Так?
Название: Re: Как удалить поле из однострочного текста
Отправлено: Борис_С от 02-12-2020, 12:07:31
Для создания поля я использовал оператор
text.TextString = "Винт B.М5-6g*20.36.016 ГОСТ 1491-80  %<\\AcVar \\href \"https://www.mail.ru##ГОСТ 1491-81#0\">%."
Почему поле не удаляется оператором
text.TextString = "Винт B.М5-6g*20.36.016 ГОСТ 1491-80  ГОСТ 1491-81."
Название: Re: Как удалить поле из однострочного текста
Отправлено: Александр Ривилис от 02-12-2020, 12:22:43
Если я не вру, то это означает, что в API ошибка. Так?
Думаю что это не ошибка, а так задумано. Впрочем, задам как я этот вопрос в ADN DevHelp. На просторах интернета ничего подобного я не нашел.
Название: Re: Как удалить поле из однострочного текста
Отправлено: Александр Ривилис от 02-12-2020, 12:44:57
Для создания поля я использовал оператор
text.TextString = "Винт B.М5-6g*20.36.016 ГОСТ 1491-80  %<\\AcVar \\href \"https://www.mail.ru##ГОСТ 1491-81#0\">%."
Почему поле не удаляется оператором
text.TextString = "Винт B.М5-6g*20.36.016 ГОСТ 1491-80  ГОСТ 1491-81."
Потому что в первый раз AutoCAD интерпретировал это строку и создал на её основе поле. Дальнейшие изменения этой строки поле не удаляют. Но в данном случае всё проще. Удалить всё поле можно так:

Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.EditorInput;
  4. using Autodesk.AutoCAD.Runtime;
  5.  
  6. [assembly: CommandClass(typeof(FieldRemove.MyCommands))]
  7.  
  8. namespace FieldRemove
  9. {
  10.   public class MyCommands
  11.   {
  12.     [CommandMethod("RemoveFieldsWithHyperlink")]
  13.     public void MyCommand()
  14.     {
  15.       // Put your command code here
  16.       Document doc = Application.DocumentManager.MdiActiveDocument;
  17.       if (doc == null) return;
  18.       Editor ed = doc.Editor;
  19.       PromptEntityOptions opts =
  20.         new PromptEntityOptions("\nВыберите DBText: ");
  21.       opts.SetRejectMessage("\nЭто не DBText!");
  22.       opts.AddAllowedClass(typeof(DBText), true);
  23.       PromptEntityResult res = ed.GetEntity(opts);
  24.       if (res.Status != PromptStatus.OK)
  25.         return;
  26.       using (Transaction tr = doc.TransactionManager.StartTransaction())
  27.       {
  28.         DBText text = tr.GetObject(res.ObjectId, OpenMode.ForWrite) as DBText;
  29.         if (text != null && text.HasFields)
  30.         {
  31.           ObjectId idField = text.GetField();
  32.           Field field = tr.GetObject(idField, OpenMode.ForWrite) as Field;
  33.           field.Erase();
  34.           text.RecordGraphicsModified(true);
  35.         }
  36.         tr.Commit();
  37.       }
  38.     }
  39.   }
  40. }
Название: Re: Как удалить поле из однострочного текста
Отправлено: Борис_С от 02-12-2020, 19:29:13
Этот код удаляет все поля в моем чертеже. Я его немножко подкорректировал:
Код - C# [Выбрать]
  1.         public static void MyCommand()
  2.         {
  3.             // Put your command code here
  4.             Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  5.             if (doc == null) return;
  6.             Editor ed = doc.Editor;
  7.             PromptEntityOptions opts =
  8.               new PromptEntityOptions("\nВыберите DBText: ");
  9.             opts.SetRejectMessage("\nЭто не DBText!");
  10.             opts.AddAllowedClass(typeof(DBText), true);
  11.             PromptEntityResult res = ed.GetEntity(opts);
  12.             if (res.Status != PromptStatus.OK)
  13.                 return;
  14.             using (Transaction tr = doc.TransactionManager.StartTransaction())
  15.             {
  16.                 DBText text = tr.GetObject(res.ObjectId, OpenMode.ForWrite) as DBText;
  17.                 if (text != null && text.HasFields)
  18.                 {
  19.                     ObjectId idField = text.GetField();
  20.                     Field field = tr.GetObject(idField, OpenMode.ForWrite) as Field;
  21.                     ObjectId[] objectIds = field.GetChildrenIds();
  22.                     field = tr.GetObject(objectIds[0], OpenMode.ForWrite) as Field;
  23.                     field.Erase();
  24.                     text.RecordGraphicsModified(true);
  25.                 }
  26.                 tr.Commit();
  27.             }
  28.         }
  29.  
Но и в этом случае 1-ое поле не удаляется.
Название: Re: Как удалить поле из однострочного текста
Отправлено: Александр Ривилис от 02-12-2020, 20:36:44
Борис_С,
В таком виде я тоже пробовал, перед тем как писать предыдущий пример. И так как он не работает, то и не стал его предлагать. Запрос в ADN DevHelp я написал. Как только будет ответ - сообщу.
Название: Re: Как удалить поле из однострочного текста
Отправлено: Борис_С от 04-12-2020, 15:34:23
А если нужно удалить одно поле и превратить его в текст?
Тогда наверное DBObject.RemoveField(ObjectId idField). Попробуй.
Есть еще Field.FindField которое позволяет найти позицию поля внутри текста. Если его вырезать, а вместо его вставить Field.Value, то наверное будет то, что тебе нужно.
Хочу разобраться с методом
Код - C# [Выбрать]
  1. public static bool FindField(
  2.     string text,
  3.     int iSearchFrom,
  4.     ref int nStartPos,
  5.     ref int nEndPos
  6. );
Не очень понимаю, что должно сидеть в text и в iSearchFrom.
Название: Re: Как удалить поле из однострочного текста
Отправлено: Александр Ривилис от 04-12-2020, 16:06:50
Не очень понимаю, что должно сидеть в text и в iSearchFrom.
В text - содержимое DBText (в данном случае). В iSearchFrom - начальная позиция в text для поиска поля.
Название: Re: Как удалить поле из однострочного текста
Отправлено: Борис_С от 04-12-2020, 16:21:48
Я посадил в text DBText.TextString, в iSearchFrom 1
Метод вернул false.
Название: Re: Как удалить поле из однострочного текста
Отправлено: Александр Ривилис от 04-12-2020, 16:24:19
Нумерация идет с нуля.
Название: Re: Как удалить поле из однострочного текста
Отправлено: Борис_С от 04-12-2020, 16:35:19
Поменял на 0. Все равно возвращает false.
Название: Re: Как удалить поле из однострочного текста
Отправлено: Александр Ривилис от 04-12-2020, 16:44:53
Поменял на 0. Все равно возвращает false.
Логично. В самом тексте полей нет.
Название: Re: Как удалить поле из однострочного текста
Отправлено: Борис_С от 04-12-2020, 17:49:16
И как же решить эту проблему?
Название: Re: Как удалить поле из однострочного текста
Отправлено: Александр Ривилис от 04-12-2020, 18:00:50
Никак. В очередной раз повторяю - ждем ответ из ADN DevHelp.
Название: Re: Как удалить поле из однострочного текста
Отправлено: Александр Ривилис от 09-12-2020, 11:49:27
Получил ответ из ADN DevHelp. Если в двух словах, то и они не нашли способа удалить единичное поле из DBText при помощи API. Передали вопрос в Engineering team, но подозреваю что и это не поможет. Похоже, что на уровне API этого нет - только встроенный интерактивный механизм замены поля на текст.