Database.Purge(all_ids)

Автор Тема: Database.Purge(all_ids)  (Прочитано 8319 раз)

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

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Database.Purge(all_ids)
« : 13-11-2014, 17:27:01 »
Как известно, Database.Purge(ids) оставляет в составе полученной коллекции ObjectIdCollection лишь те идентификаторы, объекты которых можно удалить. Стало интересно, что будет, если передать идентификаторы всех объектов базы данных? Например, имеется линия или окружность к которой нет привязки посредством поля (Field). Исчезнет ли она? Как поведёт себя AutoCAD, если присутствуют идентификаторы возможно неожиданных для него объектов (например BlockTable и т.п.)? Написал простой тестовый код:
Код - C# [Выбрать]
  1. // © Andrey Bushman, 2014
  2. // Test code...
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6.  
  7. #if AUTOCAD
  8. using cad = Autodesk.AutoCAD.ApplicationServices.Application;
  9. using Rt = Autodesk.AutoCAD.Runtime;
  10. using Db = Autodesk.AutoCAD.DatabaseServices;
  11. using Ed = Autodesk.AutoCAD.EditorInput;
  12. using Ap = Autodesk.AutoCAD.ApplicationServices;
  13. #endif
  14.  
  15. namespace AcadTest {
  16.     public class Class1 {
  17.         [Rt.CommandMethod("test")]
  18.         public void Test() {
  19.  
  20.             Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  21.             Ed.Editor ed = doc.Editor;
  22.             Db.Database db = doc.Database;
  23.             PurgeAll(db);
  24.             ed.WriteMessage("Database purged.\n");
  25.         }
  26.  
  27.         public static void PurgeAll(Db.Database db) {
  28.             if (null == db)
  29.                 throw new ArgumentNullException("db");
  30.             if (db.IsDisposed)
  31.                 throw new ArgumentException("Database is disposed.");
  32.  
  33.             Int32 prewCount = 0;
  34.             Int32 loop = 1;
  35.             Ed.Editor ed = cad.DocumentManager.MdiActiveDocument.Editor;
  36.             Dictionary<Rt.RXClass, List<Db.ObjectId>> dict =
  37.                 GetObjectIdsGroupedByRXClass(db);
  38.  
  39.             Rt.RXClass entRX = Rt.RXClass.GetClass(typeof(Db.Entity));
  40.  
  41.             while (true) {
  42.                 ed.WriteMessage("\n### Loop {0}...\n\n", loop);
  43.  
  44.                 IEnumerable<Db.ObjectId> dyn_ids = dict.Values.SelectMany(n => n)
  45.                     .Where(n => !n.IsErased);
  46.  
  47.                 using (Db.ObjectIdCollection ids = new Db.ObjectIdCollection(
  48.                         dyn_ids.ToArray())) {
  49.                     db.Purge(ids);
  50.                     using (Db.Transaction tr = db.TransactionManager.
  51.                     StartTransaction()) {
  52.                         foreach (Db.ObjectId id in ids) {
  53.                             if (!id.IsErased && !id.ObjectClass.IsDerivedFrom(entRX)) {
  54.                                 Db.DBObject obj = tr.GetObject(id, Db.OpenMode.
  55.                                     ForWrite, false);
  56.                                 try {
  57.                                     obj.Erase();
  58.                                 }
  59.                                 catch (Exception ex) {
  60.                                     ed.WriteMessage("{0}\n", ex.Message);
  61.                                     ed.WriteMessage("Object Type: {0}, ObjectId = {1}, " +
  62.                                         "IsErased = {2}, IsDisposed = {3}\n\n", obj.GetType()
  63.                                         .ToString(), obj.ObjectId.ToString(), obj.IsErased,
  64.                                         obj.IsDisposed);
  65.                                 }
  66.                             }
  67.                         }
  68.                         tr.Commit();
  69.                         dict = GetObjectIdsGroupedByRXClass(db);
  70.                         Int32 count = dict.Values.SelectMany(n => n).Where(
  71.                             n => !n.IsErased).Count();
  72.                         if (prewCount == count)
  73.                             break;
  74.                         prewCount = count;
  75.                     }
  76.                 }
  77.                 ++loop;
  78.             }
  79.         }
  80.  
  81.         public static Dictionary<Rt.RXClass, List<Db.ObjectId>>
  82.             GetObjectIdsGroupedByRXClass(Db.Database db) {
  83.  
  84.             if (null == db)
  85.                 throw new ArgumentNullException("db");
  86.             if (db.IsDisposed)
  87.                 throw new ArgumentException("Database is disposed.");
  88.  
  89.             Dictionary<Rt.RXClass, List<Db.ObjectId>> dict = new Dictionary<
  90.                 Rt.RXClass, List<Db.ObjectId>>();
  91.  
  92.             Int32 approxNum = db.ApproxNumObjects;
  93.  
  94.             for (Int64 i = db.BlockTableId.Handle.Value; i < db.Handseed.Value
  95.                 && approxNum > 0; i++, approxNum--) {
  96.  
  97.                 Db.ObjectId id = Db.ObjectId.Null;
  98.                 Db.Handle h = new Db.Handle(i);
  99.  
  100.                 db.TryGetObjectId(h, out id);
  101.  
  102.                 if (id.IsValid && !id.IsErased) {
  103.                     Rt.RXClass key = id.ObjectClass;
  104.  
  105.                     if (!dict.ContainsKey(key)) {
  106.                         dict.Add(key, new List<Db.ObjectId>());
  107.                     }
  108.                     dict[key].Add(id);
  109.                 }
  110.             }
  111.             return dict;
  112.         }
  113.     }
  114. }

Создал новый DWG на основании некоторого DWT, добавил в него линию, окружность и определение блока (см. файл во вложении). Запускаю в нём свой код и получаю некоторый набор ошибок, текст которых отправляется в консоль:

Цитировать
Command: netload
Command: test
eCannotBeErasedByCaller
Object Type: Autodesk.AutoCAD.DatabaseServices.Material, ObjectId =
(8796087794064), IsErased = False, IsDisposed = False

Unknown error 20072
Object Type: Autodesk.AutoCAD.DatabaseServices.DBVisualStyle, ObjectId =
(8796087794336), IsErased = False, IsDisposed = False

Unknown error 20072
Object Type: Autodesk.AutoCAD.DatabaseServices.DBVisualStyle, ObjectId =
(8796087794352), IsErased = False, IsDisposed = False

Unknown error 20072
Object Type: Autodesk.AutoCAD.DatabaseServices.DBVisualStyle, ObjectId =
(8796087794368), IsErased = False, IsDisposed = False

Unknown error 20072
Object Type: Autodesk.AutoCAD.DatabaseServices.DBVisualStyle, ObjectId =
(8796087794384), IsErased = False, IsDisposed = False

Unknown error 20072
Object Type: Autodesk.AutoCAD.DatabaseServices.DBVisualStyle, ObjectId =
(8796087794400), IsErased = False, IsDisposed = False

Unknown error 20072
Object Type: Autodesk.AutoCAD.DatabaseServices.DBVisualStyle, ObjectId =
(8796087794448), IsErased = False, IsDisposed = False

Unknown error 20072
Object Type: Autodesk.AutoCAD.DatabaseServices.DBVisualStyle, ObjectId =
(8796087794464), IsErased = False, IsDisposed = False

Unknown error 20072
Object Type: Autodesk.AutoCAD.DatabaseServices.DBVisualStyle, ObjectId =
(8796087794496), IsErased = False, IsDisposed = False

Unknown error 20072
Object Type: Autodesk.AutoCAD.DatabaseServices.DBVisualStyle, ObjectId =
(8796087794512), IsErased = False, IsDisposed = False

Unknown error 20072
Object Type: Autodesk.AutoCAD.DatabaseServices.DBVisualStyle, ObjectId =
(8796087794528), IsErased = False, IsDisposed = False

Unknown error 20072
Object Type: Autodesk.AutoCAD.DatabaseServices.DBVisualStyle, ObjectId =
(8796087794544), IsErased = False, IsDisposed = False

Unknown error 20072
Object Type: Autodesk.AutoCAD.DatabaseServices.DBVisualStyle, ObjectId =
(8796087794560), IsErased = False, IsDisposed = False

Unknown error 20072
Object Type: Autodesk.AutoCAD.DatabaseServices.DBVisualStyle, ObjectId =
(8796087794576), IsErased = False, IsDisposed = False

Меня интересуют ошибки, подсвеченные красным.
« Последнее редактирование: 13-11-2014, 18:57:06 от Андрей Бушман »

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

  • Administrator
  • *****
  • Сообщений: 13832
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Database.Purge(all_ids)
« Ответ #1 : 14-11-2014, 11:41:40 »
Unknown error 20072

Цитировать
eVSNotFound=20065
eVSTrue=20066
eVSFalse=20067
eVSAlreadyExists=20068
eVSOneOffCreated=20069
eVSAPIOnlyValues=20070
eVSIsInUse=20071
eVSIsAcadDefault=20072

Судя по всему это ошибка связана с тем, что эти визуальные стили встроенные и не могут быть удалены.
Коды ошибок я нашел проанализировав файл inc\acadstrc.h из ObjectARX SDK.

eCannotBeErasedByCaller
Ошибка говорит о том, что не может быть удалено. Видимо причина в том, что этот Материал единственный и его удалять нельзя.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Database.Purge(all_ids)
« Ответ #2 : 24-12-2014, 17:34:18 »
Поднимаю тему.

Вспомогательные методы, которые используются в коде команды:
Код - C# [Выбрать]
  1. /* © Andrey Bushman, 2014
  2. * ExtensionMethods.cs
  3.  */
  4.  
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Text;
  9.  
  10. #if AUTOCAD
  11. using cad = Autodesk.AutoCAD.ApplicationServices.Application;
  12. using Ap = Autodesk.AutoCAD.ApplicationServices;
  13. using Db = Autodesk.AutoCAD.DatabaseServices;
  14. using Ed = Autodesk.AutoCAD.EditorInput;
  15. using Rt = Autodesk.AutoCAD.Runtime;
  16. using Gm = Autodesk.AutoCAD.Geometry;
  17. #endif
  18.  
  19. namespace Bushman.CAD {
  20.  
  21.     public delegate void WriteMessage(String format, params Object[] args);
  22.  
  23.     public static class ExtensionMethods {
  24.  
  25.         public static Db.ObjectId[] GetDBObjectIds(this Db.Database db) {
  26.             Db.ObjectId[] ids = GetDBObjectIds(db, (n => true));
  27.             return ids;
  28.         }
  29.  
  30.         public static Db.ObjectId[] GetDBObjectIds(this Db.Database db,
  31.             Func<Db.ObjectId, Boolean> filter) {
  32.  
  33.             // Check arguments
  34.             if (null == db)
  35.                 throw new ArgumentNullException("null == db");
  36.             if (null == filter)
  37.                 throw new ArgumentNullException("null == filter");
  38.             if (db.IsDisposed)
  39.                 throw new ArgumentException("true == db.IsDisposed");
  40.  
  41.             // -------------------
  42.             Int32 approxNum = db.ApproxNumObjects;
  43.             List<Db.ObjectId> ids = new List<Db.ObjectId>();
  44.  
  45.             for (Int64 i = db.BlockTableId.Handle.Value; i < db.Handseed.Value
  46.                 && approxNum > 0; ++i) {
  47.  
  48.                 Db.Handle h = new Db.Handle(i);
  49.                 Db.ObjectId id = Db.ObjectId.Null;
  50.  
  51.                 Boolean parseResult = db.TryGetObjectId(h, out id);
  52.  
  53.                 if (parseResult) {
  54.                     --approxNum;
  55.                     if (filter(id)) {
  56.                         ids.Add(id);
  57.                     }
  58.                 }
  59.             }
  60.             return ids.ToArray();
  61.         }
  62.  
  63.         public static Int64 PurgeAll(this Db.Database db, out Db.ObjectId[]
  64.             notRemovedIds, out String errMsg) {
  65.             // check args
  66.             if (null == db)
  67.                 throw new ArgumentNullException("null == db");
  68.             if (db.IsDisposed)
  69.                 throw new ArgumentException("db.IsDisposed");
  70.             //--------------              
  71.  
  72.             Db.ObjectId[] ids = null;
  73.             Db.ObjectIdCollection _ids = null;
  74.             Int64 rmObjCount = 0;
  75.             List<Db.ObjectId> errIds = new List<Db.ObjectId>();
  76.             StringBuilder sb = new StringBuilder();
  77.  
  78.             do {
  79.                 ids = db.GetDBObjectIds(n => !n.IsErased &&
  80.                     !n.IsEffectivelyErased && !errIds.Contains(n));
  81.                 _ids = new Db.ObjectIdCollection(ids);
  82.  
  83.                 db.Purge(_ids);
  84.  
  85.                 using (Db.Transaction tr = db.TransactionManager
  86.                     .StartOpenCloseTransaction()) {
  87.                     foreach (Db.ObjectId id in _ids) {
  88.                         if (!id.IsErased && !id.IsEffectivelyErased) {
  89.                             Db.DBObject obj = tr.GetObject(id, Db.OpenMode
  90.                                 .ForWrite, false, true);
  91.                             try {
  92.                                 obj.Erase();
  93.                                 ++rmObjCount;
  94.                             }
  95.                             catch (Exception ex) {
  96.                                 errIds.Add(id);
  97.                                 sb.AppendFormat("ObjectId: {0}. ClassName = " +
  98.                                     "\"{1}\". Error message: \"{2}\".\n", id,
  99.                                     id.ObjectClass.Name, ex.Message);
  100.                             }
  101.                         }
  102.                     }
  103.                     tr.Commit();
  104.                 }
  105.             } while (0 != _ids.Count);
  106.  
  107.             notRemovedIds = errIds.ToArray();
  108.             errMsg = sb.ToString();
  109.             return rmObjCount;
  110.         }
  111.     }
  112. }

Далее код команды:
Код - C# [Выбрать]
  1. /* Commands.cs
  2.  * © Andrey Bushman, 2014
  3.  */
  4.  
  5.  
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Diagnostics;
  10. using System.IO;
  11.  
  12. #if AUTOCAD
  13. using cad = Autodesk.AutoCAD.ApplicationServices.Application;
  14. using Ap = Autodesk.AutoCAD.ApplicationServices;
  15. using Db = Autodesk.AutoCAD.DatabaseServices;
  16. using Ed = Autodesk.AutoCAD.EditorInput;
  17. using Rt = Autodesk.AutoCAD.Runtime;
  18. using Gm = Autodesk.AutoCAD.Geometry;
  19. #endif
  20.  
  21. [assembly: Rt.ExtensionApplication(typeof(Bushman.CAD.ProxyCommands))]
  22. [assembly: Rt.CommandClass(typeof(Bushman.CAD.ProxyCommands))]
  23.  
  24. namespace Bushman.CAD {
  25.     public sealed class ProxyCommands : Rt.IExtensionApplication {
  26.  
  27.         public void Initialize() {
  28.             Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  29.             if (null == doc)
  30.                 return;
  31.  
  32.             Ed.Editor ed = doc.Editor;
  33.             ed.WriteMessage("\n{0}\n", Path.GetFileName(this.GetType().Assembly
  34.                 .Location));
  35.             ed.WriteMessage("{0}\n\n", "© Andrey Bushman, 2014");
  36.             ed.WriteMessage("{0}:\n", "Commands");
  37.             ed.WriteMessage("{0}\n\n", "purgeAll - purge all in the current" +
  38.                 "Database.");
  39.         }
  40.  
  41.         public void Terminate() { }
  42.  
  43.         [Rt.CommandMethod("purgeAll", Rt.CommandFlags.Modal)]
  44.         public void Command_PurgeAll() {
  45.  
  46.             Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  47.             if (null == doc)
  48.                 return;
  49.  
  50.             Ed.Editor ed = doc.Editor;
  51.             Db.Database db = doc.Database;
  52.  
  53.             using (doc.LockDocument()) {
  54.                 Db.ObjectId[] notRemovedIds = null;
  55.                 String errMsg = null;
  56.                 Int64 count = db.PurgeAll(out notRemovedIds, out errMsg);
  57.                 ed.WriteMessage("Removed objects count: {0}\n", count);
  58. #if DEBUG
  59.                 ed.WriteMessage(errMsg);
  60.                 ed.WriteMessage("Not removed objects count: {0}\n",
  61.                     notRemovedIds.Length);
  62. #endif
  63.             }
  64.         }
  65.     }
  66. }
Результат (в режиме Debug):
Цитировать
Command: netload
Tools.dll
© Andrey Bushman, 2014

Commands:
purgeAll - purge all in the current Database.

Command: purgeall
Removed objects count: 147
ObjectId: (8796087794064). ClassName = "AcDbMaterial". Error message:
"eCannotBeErasedByCaller".
ObjectId: (8796087794336). ClassName = "AcDbVisualStyle". Error message:
"Unknown error 20072".
ObjectId: (8796087794352). ClassName = "AcDbVisualStyle". Error message:
"Unknown error 20072".
ObjectId: (8796087794368). ClassName = "AcDbVisualStyle". Error message:
"Unknown error 20072".
ObjectId: (8796087794384). ClassName = "AcDbVisualStyle". Error message:
"Unknown error 20072".
ObjectId: (8796087794400). ClassName = "AcDbVisualStyle". Error message:
"Unknown error 20072".
ObjectId: (8796087794448). ClassName = "AcDbVisualStyle". Error message:
"Unknown error 20072".
ObjectId: (8796087794464). ClassName = "AcDbVisualStyle". Error message:
"Unknown error 20072".
ObjectId: (8796087794496). ClassName = "AcDbVisualStyle". Error message:
"Unknown error 20072".
ObjectId: (8796087794512). ClassName = "AcDbVisualStyle". Error message:
"Unknown error 20072".
ObjectId: (8796087794528). ClassName = "AcDbVisualStyle". Error message:
"Unknown error 20072".
ObjectId: (8796087794544). ClassName = "AcDbVisualStyle". Error message:
"Unknown error 20072".
ObjectId: (8796087794560). ClassName = "AcDbVisualStyle". Error message:
"Unknown error 20072".
ObjectId: (8796087794576). ClassName = "AcDbVisualStyle". Error message:
"Unknown error 20072".
ObjectId: (8796087893568). ClassName = "AcDbFontTable". Error message:
"eCannotBeErasedByCaller".
Not removed objects count: 15


При попытке после этого запуска Audit получаю окошко с сообщением (см. вложенный файл). В чём может быть проблема?

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

  • Administrator
  • *****
  • Сообщений: 13832
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Database.Purge(all_ids)
« Ответ #3 : 24-12-2014, 17:57:46 »
Похоже на то, что Database.Purge работает некорректно и оставляет в массиве ObjectId тех элементов, которые в действительности удалять нельзя. Ну и результат ты видишь. Интересно бы понять что это за объекты. Очевидно, что нельзя удалять BlockTable, LayerTable и т.д.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Database.Purge(all_ids)
« Ответ #4 : 24-12-2014, 21:59:46 »
Очевидно, что нельзя удалять BlockTable, LayerTable и т.д.
Логично предположить, что Purge должен был бы убирать их из выборки. Потревожите ADN?

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

  • Administrator
  • *****
  • Сообщений: 13832
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Database.Purge(all_ids)
« Ответ #5 : 24-12-2014, 22:02:01 »
Потревожите ADN?
Ага. Хотя не факт, что они побегут блокировать возможность удаления.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Database.Purge(all_ids)
« Ответ #6 : 24-12-2014, 22:04:55 »
Ага. Хотя не факт, что они побегут блокировать возможность удаления.
Но может они посоветуют, какие именно изменения мне стоит внести в код, чтобы он работал как следует (т.е. подскажут, как обойти этот баг меньшей кровью).

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Database.Purge(all_ids)
« Ответ #7 : 26-12-2014, 12:13:43 »
Пока что, дабы не ждать у моря погоды, накидал упрощённую, менее гибкую альтернативу.

Вспомогательный метод:

Код - C# [Выбрать]
  1. public static Dictionary<Rt.RXClass, List<Db.ObjectId>>
  2.         GetGroupedDBObjectIds(this Db.Database db, Func<Db.ObjectId,
  3.         Boolean> filter) {
  4.  
  5.         // Check arguments
  6.         if (null == db)
  7.                 throw new ArgumentNullException("null == db");
  8.         if (null == filter)
  9.                 throw new ArgumentNullException("null == filter");
  10.         if (db.IsDisposed)
  11.                 throw new ArgumentException("true == db.IsDisposed");
  12.  
  13.         // -------------------
  14.         Int32 approxNum = db.ApproxNumObjects;
  15.         Dictionary<Rt.RXClass, List<Db.ObjectId>> dict = new Dictionary<
  16.                 Rt.RXClass, List<Db.ObjectId>>();
  17.  
  18.         for (Int64 i = db.BlockTableId.Handle.Value; i < db.Handseed.Value
  19.                 && approxNum > 0; ++i) {
  20.  
  21.                 Db.Handle h = new Db.Handle(i);
  22.                 Db.ObjectId id = Db.ObjectId.Null;
  23.  
  24.                 Boolean parseResult = db.TryGetObjectId(h, out id);
  25.  
  26.                 if (parseResult) {
  27.                         --approxNum;
  28.                         if (filter(id)) {
  29.                                 if (!dict.ContainsKey(id.ObjectClass)) {
  30.                                         dict.Add(id.ObjectClass, new List<Db.ObjectId>());
  31.                                 }
  32.                                 dict[id.ObjectClass].Add(id);
  33.                         }
  34.                 }
  35.         }
  36.         return dict;
  37. }

Далее метод, выполняющий очистку:

Код - C# [Выбрать]
  1.                 public static Int64 PurgeAll2(this Db.Database db, out Db.ObjectId[]
  2.                         notRemovedIds, out String errMsg) {
  3.                         // check args
  4.                         if (null == db)
  5.                                 throw new ArgumentNullException("null == db");
  6.                         if (db.IsDisposed)
  7.                                 throw new ArgumentException("db.IsDisposed");
  8.                         //--------------              
  9.  
  10.                         Dictionary<Rt.RXClass, List<Db.ObjectId>> dict = null;
  11.                         Db.ObjectIdCollection _ids = null;
  12.                         Int64 rmObjCount = 0;
  13.                         List<Db.ObjectId> errIds = new List<Db.ObjectId>();
  14.                         StringBuilder sb = new StringBuilder();
  15.  
  16.                         Rt.RXClass[] expectedRx = new Rt.RXClass[] {
  17.                                 Rt.RXClass.GetClass(typeof(Db.BlockTableRecord)),
  18.                                 Rt.RXClass.GetClass(typeof(Db.TextStyleTableRecord)),
  19.                                 Rt.RXClass.GetClass(typeof(Db.DimStyleTableRecord)), // TODO: Problem is here!
  20.                                 Rt.RXClass.GetClass(typeof(Db.MLeaderStyle)),
  21.                                 Rt.RXClass.GetClass(typeof(Db.MlineStyle)),
  22.                                 Rt.RXClass.GetClass(typeof(Db.TableStyle)),
  23.                                 Rt.RXClass.GetClass(typeof(Db.LinetypeTableRecord)),
  24.                                 Rt.RXClass.GetClass(typeof(Db.LayerTableRecord)),
  25.                                 Rt.RXClass.GetClass(typeof(Db.Shape)),
  26.                                 Rt.RXClass.GetClass(typeof(Db.Material)),
  27.                                 Rt.RXClass.GetClass(typeof(Db.DBVisualStyle)),
  28.                                 Rt.RXClass.GetClass(typeof(Db.Group))
  29.                         };
  30.  
  31.                         Func<Db.ObjectId, Boolean> filter = n =>
  32.                                 !n.IsErased &&
  33.                                 !n.IsEffectivelyErased &&
  34.                                 !errIds.Contains(n) &&
  35.                                 expectedRx.Any(m => n.ObjectClass.IsDerivedFrom(m));
  36.  
  37.                         do {
  38.                                 dict = db.GetGroupedDBObjectIds(filter);
  39.                                 _ids = new Db.ObjectIdCollection(dict.Values.SelectMany(n => n)
  40.                                         .ToArray());
  41.  
  42.                                 db.Purge(_ids);
  43.  
  44.                                 using (Db.Transaction tr = db.TransactionManager
  45.                                         .StartOpenCloseTransaction()) {
  46.                                         foreach (Db.ObjectId id in _ids) {
  47.                                                 if (!id.IsErased && !id.IsEffectivelyErased) {
  48.                                                         Db.DBObject obj = tr.GetObject(id, Db.OpenMode
  49.                                                                 .ForWrite, false, true);
  50.                                                         try {
  51.                                                                 obj.Erase();
  52.                                                                 ++rmObjCount;
  53.                                                         }
  54.                                                         catch (Exception ex) {
  55.                                                                 errIds.Add(id);
  56.                                                                 sb.AppendFormat("ObjectId: {0}. ClassName = " +
  57.                                                                         "\"{1}\". Error message: \"{2}\".\n", id,
  58.                                                                         id.ObjectClass.Name, ex.Message);
  59.                                                         }
  60.                                                 }
  61.                                         }
  62.                                         tr.Commit();
  63.                                 }
  64.                         } while (0 != _ids.Count);
  65.  
  66.                         notRemovedIds = errIds.ToArray();
  67.                         errMsg = sb.ToString();
  68.                         return rmObjCount;
  69.                 }

Код команды тот же, что показывал ранее, только вместо PurgeAll вызываю PurgeAll2.

В строке 19 проблемное место. Если я в чертеже вызываю команду purgeAll, то очистка происходит, audit ошибок не находит. Однако если я сохраню чертёж и проверю его при помощи RECOVERY, то вижу, что найдена одна ошибка, которую не видел AUDIT:
Цитировать
Pass 2 1700    objects auditedAcDbDimStyleTableRecord: "Copy(2) of Основной без допусков"
                                  Not in Table          Added
То, что акад не делает пробела (лепит вместе  "audited" и "AcDbDimStyleTableRecord") - это пережить можно. Но, насколько я вижу, это сообщение не корректно, т.к. обозначенный размерный стиль на самом деле присутствует. Однако до выполнения RECOVERY кроме него не было других стилей, даже standard (они все были удалены командой purgeAll). после исправления, выполненного RECOVERY, появляется стиль standard. Если удалить стиль standard, то  RECOVERY снова покажет тот же текст ошибки и заново создаст стиль standard.

Если в размерных стилях обязательно нужен standard (судя по поведению RECOVERY), даже если он нигде не используется, то логично было бы запретить его удаление. Однако по факту это не запрещено - удалить можно как программно, так и вручную. Я могу, конечно, добавить проверку имени размерного стиля, прежде чем его удалить, но это напоминает латание старой одежды новыми заплатками...

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1097
  • Карма: 172
Re: Database.Purge(all_ids)
« Ответ #8 : 09-01-2015, 14:13:50 »
Standard должны быть текстовый, табличный и стиль мультилинии. К размерным стилям подобных требований нет, насколько я помню ;)
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Database.Purge(all_ids)
« Ответ #9 : 09-01-2015, 16:42:24 »
Однако recovery похоже так не думает, в чём и конфликтует с Database.Purge.

P.S. И тебя так же с прошедшими.