Программная очистка файла в NC 23-23.1
Столкнулся со странной работой стандартного PurgeAll в файлах с внешними ссылками. Если во внешней ссылке есть линии с пользовательскими типами линий, можно словить очень странный баг.
Выполняю достаточно несложный код (одно "но" - все это приходится делать внутри отдельной транзакции, поскольку помимо очистки делается еще масса телодвижений)
1 2 3 4 5 | nanoCAD.Document comDoc = doc.AcadDocument as nanoCAD.Document; for (int i = 0; i < 3; i++) { comDoc.PurgeAll(); } |
И вроде бы все хорошо. Пока не будет выполнена регенерация. После нее все линии во внешних ссылках могут преобразоваться (визуально) в Continuous. Спасает только ручная перезагрузка ссылки. Но пользователям-то это не объяснишь!
Пришлось обращаться на форум разработчиков, где Андрей Лысенко и показал решение. Процитирую его:
Одашники (DwgDirect) полтора года назад поправили в своих потрохах поправили purge(OdDbObjectIdArray)
<...>
У нас это вошло в версию 24.0
С его любезного разрешения привожу слегка переделанный вариант его решения, хотя проблема в версиях 24 и более поздних, похоже, решена.
Прежде всего два служебных метода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | private static void PurgeAddDictRecords(DBDictionary dict, ObjectIdCollection ids) { foreach (DBDictionaryEntry entry in dict) { ObjectId objId = entry.Value; if (objId.Database == dict.Database) ids.Add(objId); } } private static void PurgeAddTableRecords(SymbolTable symbolTable, ObjectIdCollection ids) { foreach (ObjectId objId in symbolTable) { if (objId.Database == symbolTable.Database) ids.Add(objId); } } |
В принципе, все достаточно прозрачно: очистка словарей (типа словаря табличных стилей, мультилиний и т.п.), и очистка символьных таблиц.
Ну и основная команда:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | [CommandMethod("purge-sample")] public static void PurgeAlCommand() { Document doc = Application.DocumentManager.MdiActiveDocument; if (doc == null) { return; } Database dbase = doc.Database; using (Transaction trans = dbase.TransactionManager.StartTransaction()) { for (int i = 0; i < 3; i++) { ObjectIdCollection idCollection = new ObjectIdCollection(); PurgeAddDictRecords((DBDictionary) dbase.TableStyleDictionaryId.GetObject(OpenMode.ForRead), idCollection); PurgeAddDictRecords((DBDictionary) dbase.MLStyleDictionaryId.GetObject(OpenMode.ForRead), idCollection); PurgeAddDictRecords((DBDictionary) dbase.MLeaderStyleDictionaryId.GetObject(OpenMode.ForRead), idCollection); PurgeAddTableRecords((SymbolTable)dbase.BlockTableId.GetObject(OpenMode.ForRead), idCollection); PurgeAddTableRecords((SymbolTable)dbase.DimStyleTableId.GetObject(OpenMode.ForRead), idCollection); PurgeAddTableRecords((SymbolTable)dbase.LayerTableId.GetObject(OpenMode.ForRead), idCollection); PurgeAddTableRecords((SymbolTable)dbase.LinetypeTableId.GetObject(OpenMode.ForRead), idCollection); PurgeAddTableRecords((SymbolTable)dbase.TextStyleTableId.GetObject(OpenMode.ForRead), idCollection); dbase.Purge(idCollection); foreach (ObjectId objectId in idCollection) { DBObject dbObj = objectId.GetObject(OpenMode.ForWrite); dbObj.Erase(); } } trans.Commit(); } } |
Да, для версии 24 и более поздних (повторюсь!) скорее всего, это уже не понадобится. Но сайт-то шпаргалка!