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

ADN Club => AutoCAD .NET API => Тема начата: Захаров Максим от 27-01-2016, 18:05:07

Название: Переименование слоя
Отправлено: Захаров Максим от 27-01-2016, 18:05:07
Скажите пожалуйста, можно ли программно переименовать слой, или нужно создать новый скопировать туда все объекты и удалить старый.
Спасибо заранее.
Название: Re: Переименование слоя
Отправлено: Андрей Бушман от 27-01-2016, 18:05:49
можно
Название: Re: Переименование слоя
Отправлено: Александр Пекшев aka Modis от 27-01-2016, 18:06:43
Конечно можно!
А еще в автокаде есть функция _rename....
Название: Re: Переименование слоя
Отправлено: Александр Пекшев aka Modis от 27-01-2016, 18:12:22
http://exchange.autodesk.com/autocadmep/enu/online-help/BLDSYS/2012/ENU/pages/WS1a9193826455f5ff2566ffd511ff6f8c7ca-3f99.htm
Название: Re: Переименование слоя
Отправлено: Александр Ривилис от 27-01-2016, 19:43:45
http://exchange.autodesk.com/autocadmep/enu/online-help/BLDSYS/2012/ENU/pages/WS1a9193826455f5ff2566ffd511ff6f8c7ca-3f99.htm
Пример там IMHO неудачный. Он не показывает как можно переименовать слой, а показывает как можно сделать дубликат слоя (в том числе и слоя "0"). Пример был бы хорошим, если бы был запрос старого имени слоя, нового имени слоя и выполнялось бы переименование. Как-то так:

Код - C# [Выбрать]
  1. [CommandMethod("LayerReaname")]
  2. static public void LayerReaname()
  3. {
  4.   Document doc = Application.DocumentManager.MdiActiveDocument;
  5.   if (doc == null) return;
  6.   Database db = doc.Database;
  7.   Editor ed = doc.Editor;
  8.  
  9.   // Запрашиваем старое имя слоя
  10.   PromptStringOptions po1 = new PromptStringOptions("Укажите старое имя слоя: ");
  11.   po1.AllowSpaces = true;
  12.   PromptResult pr1 = ed.GetString(po1);
  13.   if (pr1.Status != PromptStatus.OK) return;
  14.   if (pr1.StringResult.Contains("|") || pr1.StringResult == "0") {
  15.     ed.WriteMessage("\nЭтот слой нельзя переименовать");
  16.     return;
  17.   }
  18.  
  19.   // Запрашиваем новое имя слоя
  20.   PromptStringOptions po2 = new PromptStringOptions("Укажите новое имя слоя: ");
  21.   po2.AllowSpaces = true;
  22.   PromptResult pr2 = ed.GetString(po2);
  23.   if (pr2.Status != PromptStatus.OK) return;
  24.   if (pr2.StringResult.Contains("|") || pr2.StringResult == "0") {
  25.     ed.WriteMessage("\nЭто имя недопустимо");
  26.     return;
  27.   }
  28.   try {
  29.     SymbolUtilityServices.ValidateSymbolName(pr2.StringResult, false);
  30.   }
  31.   catch {
  32.     ed.WriteMessage("\nЭто имя недопустимо");
  33.     return;
  34.   }
  35. #pragma warning disable 618
  36.   using (LayerTable lt = db.LayerTableId.Open(OpenMode.ForRead) as LayerTable) {
  37.     if (!lt.Has(pr1.StringResult)) {
  38.       ed.WriteMessage("Слоя {0} нет в чертеже!", pr1.StringResult);
  39.       return;
  40.     }
  41.     if (lt.Has(pr2.StringResult)) {
  42.       ed.WriteMessage("Слой {0} уже есть!", pr2.StringResult);
  43.       return;
  44.     }
  45.     using (LayerTableRecord ltr = lt[pr1.StringResult].Open(OpenMode.ForWrite) as LayerTableRecord) {
  46.       ltr.Name = pr2.StringResult;
  47.     }
  48.   }
  49. #pragma warning restore 618
  50.  
  51. }
Название: Re: Переименование слоя
Отправлено: Захаров Максим от 28-01-2016, 08:25:36
Спасибо всем, я так примерно и думал, что вроде сложностей нет. Если не затруднит, что у меня не правильно, слои не хотят переименовываться
Код - vb.net [Выбрать]
  1. Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
  2.                     Dim acLyrTbl As LayerTable = acCurDb.LayerTableId.Open(OpenMode.ForRead)
  3.                     For Each id As ObjectId In acLyrTbl
  4.                         Dim acLyrTblRec As LayerTableRecord = acTrans.GetObject(id, OpenMode.ForWrite)
  5.                         Dim N As String = acLyrTblRec.Name
  6.                         If Not (N Like "0" Or N Like "Defpoints") Then
  7.                             N = "f" & N
  8.                             acLyrTblRec.Name = N
  9.                         End If
  10.                     Next
  11.                     acTrans.Commit()
  12.                 End Using
Название: Re: Переименование слоя
Отправлено: Александр Ривилис от 28-01-2016, 08:44:16
Начни с того, что правильно отформатируй код. Смотри у меня в подписи.
Название: Re: Переименование слоя
Отправлено: Александр Ривилис от 28-01-2016, 09:30:23
Думаю, что проблема в том, что ты пытаешься переименовывать слои в итерации по LayerTable и таким образом нарушаешь итерацию.
Сделай иначе:
1) Создай массив ObjectId
2) В итерации по LayerTable заполни этот массив значениями ObjectId для всех LayerTableRecord
3) В цикле по элементам массива ObjectId выполни переименование
Название: Переименование слоя
Отправлено: Захаров Максим от 28-01-2016, 14:36:57
Спасибо всем, но не помогло, слои не хотят менять название, будем думать
Код - vb.net [Выбрать]
  1. Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
  2.                     Dim acLyrTbl As LayerTable = acCurDb.LayerTableId.Open(OpenMode.ForRead)
  3.                     Dim ArrayIdLayer As ObjectId() = Nothing
  4.                     Dim CountId As Integer = 0
  5.                     For Each id As ObjectId In acLyrTbl
  6.                         Dim acLyrTblRec As LayerTableRecord = acTrans.GetObject(id, OpenMode.ForWrite)
  7.                         ReDim Preserve ArrayIdLayer(CountId)
  8.                         ArrayIdLayer(CountId) = acLyrTblRec.Id
  9.                         CountId += 1
  10.                     Next
  11.                     For i As Integer = 0 To ArrayIdLayer.Length - 1
  12.                         Dim acLyrTblRec As LayerTableRecord = acTrans.GetObject(ArrayIdLayer(i), OpenMode.ForWrite)
  13.                         Dim N As String = acLyrTblRec.Name
  14.                         If Not (N Like "0" Or N Like "Defpoints") Then
  15.                             N = "f" & N
  16.                             acLyrTblRec.Name = N
  17.                         End If
  18.                     Next
  19.                     acTrans.Commit()
  20.                 End Using
Название: Re: Переименование слоя
Отправлено: Александр Ривилис от 28-01-2016, 15:36:58
Не вдаваясь в красоту и эффективность кода и учитывая, что на VB.NET я не пишу:

Код - vb.net [Выбрать]
  1.     <CommandMethod("TestRename", CommandFlags.Modal)> _
  2.     Public Sub TestRename()
  3.       Dim acCurDb As Database = HostApplicationServices.WorkingDatabase
  4.       Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
  5.         Dim acLyrTbl As LayerTable = acTrans.GetObject(acCurDb.LayerTableId, OpenMode.ForRead)
  6.         Dim ArrayIdLayer As ObjectId() = Nothing
  7.         Dim CountId As Integer = 0
  8.         For Each id As ObjectId In acLyrTbl
  9.           ReDim Preserve ArrayIdLayer(CountId)
  10.           ArrayIdLayer(CountId) = id
  11.           CountId += 1
  12.         Next
  13.         For i As Integer = 0 To ArrayIdLayer.Length - 1
  14.           Dim acLyrTblRec As LayerTableRecord = acTrans.GetObject(ArrayIdLayer(i), OpenMode.ForWrite)
  15.           Dim N As String = acLyrTblRec.Name
  16.           If Not (N Like "0" Or N Like "Defpoints") Then
  17.             N = "f" & N
  18.             acLyrTblRec.Name = N
  19.           End If
  20.         Next
  21.         acTrans.Commit()
  22.       End Using
  23.     End Sub
  24.  
Название: Re: Переименование слоя
Отправлено: Захаров Максим от 28-01-2016, 16:21:50
Спасибо Александр. Ваш код отлично сработал.