Рабочие наборы связанного файла

Автор Тема: Рабочие наборы связанного файла  (Прочитано 6236 раз)

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

Оффлайн Андрей ФазлеевАвтор темы

  • ADN Club
  • Сообщений: 24
  • Карма: 8
    • Andrey Stroitel
Добрый день!

Скажите, пожалуйста, как можно получить список рабочих наборов связанного файла?

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Рабочие наборы связанного файла
« Ответ #1 : 20-03-2015, 15:57:11 »
kha,
Получить список рабочих наборов текущего файла можно с помощью класса FilteredWorksetCollector
Код - C# [Выбрать]
  1.                         var doc = ActiveUIDocument.Document;
  2.                        
  3.                         FilteredWorksetCollector worksetCollector =
  4.                                 new FilteredWorksetCollector(doc);
  5.                        
  6.                         worksetCollector.OfKind(WorksetKind.UserWorkset);
  7.                         foreach (var ws in worksetCollector) {
  8.                                 Debug.Print("{0} {1}", ws.Kind, ws.Name);
  9.                         }              

В конструкторе класс принимает в качесстве аргумента Document. Логично предположить, что нужно туда передать связанный файл, чтобы получить его рабочие наборы. Чуть позже подскажу как их получить.

Отмечено как Решение Андрей Фазлеев 20-03-2015, 20:14:28

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Рабочие наборы связанного файла
« Ответ #2 : 20-03-2015, 16:48:06 »
Как и обещал, вот код.
Методы для получения списка связанных документов:
Код - C# [Выбрать]
  1.         private IEnumerable<RevitLinkType> GetLinkedFiles(Document doc)
  2.         {
  3.             ElementFilter categoryFilter = new ElementCategoryFilter(BuiltInCategory.OST_RvtLinks);
  4.             ElementFilter typeFilter = new ElementClassFilter(typeof(Instance));
  5.             ElementFilter logicalFilter = new LogicalAndFilter(categoryFilter, typeFilter);
  6.  
  7.             FilteredElementCollector collector = new FilteredElementCollector(doc);
  8.             var linkedElements = collector
  9.                 .OfClass(typeof(RevitLinkType))
  10.                 .OfType<RevitLinkType>();
  11.  
  12.             return linkedElements;
  13.         }
  14.  
  15.         /// <summary>
  16.         /// Get revit documents linked with the document
  17.         /// </summary>
  18.         /// <returns></returns>
  19.         public List<Document> GetLinkedDocuments(Document doc)
  20.         {
  21.             var linkedFiles =
  22.                 GetLinkedFiles(doc);
  23.  
  24.             var linkedFileNames = linkedFiles.Select(x => x.Name)
  25.                     .ToList();
  26.  
  27.             var linkedDocuments = doc.Application.Documents
  28.                                        .Cast<Document>()
  29.                                        .Where(d => linkedFileNames
  30.                                                .Any(fileName => d.PathName.Contains(fileName)))
  31.                                         .ToList();
  32.  
  33.             return linkedDocuments;
  34.         }

Дальше все просто. Используем FilteredWorksetCollector со связанными документами.
Вот пример:
Код - C# [Выбрать]
  1.                 public void GetWorkSetsFromLinkedDocuments()
  2.                 {
  3.                         var doc = ActiveUIDocument.Document;
  4.                        
  5.                         var linkedDocs = GetLinkedDocuments(doc);
  6.                        
  7.                         foreach (var ld in linkedDocs) {
  8.                                 GetWorkSets(ld);
  9.                         }
  10.                 }
  11.                
  12.                 public void GetWorkSets(Document doc)
  13.                 {                      
  14.                
  15.                         FilteredWorksetCollector worksetCollector =
  16.                                 new FilteredWorksetCollector(doc);
  17.                        
  18.                         worksetCollector.OfKind(WorksetKind.UserWorkset);
  19.                         foreach (var ws in worksetCollector) {
  20.                                 Debug.Print("{0} {1}", ws.Kind, ws.Name);
  21.                         }      
  22.                        
  23.                 }

Проверил. Все работает.

Оффлайн Андрей ФазлеевАвтор темы

  • ADN Club
  • Сообщений: 24
  • Карма: 8
    • Andrey Stroitel
Re: Рабочие наборы связанного файла
« Ответ #3 : 20-03-2015, 20:14:19 »
Спасибо!
Была мысль получить связанный файл как документ, но не разобрался как это сделать.

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Re: Рабочие наборы связанного файла
« Ответ #4 : 23-03-2015, 07:16:25 »
Виктор, день добрый!

Хотел бы вставить свои 5 копеек. Во-первых, в методе GetLinkedFiles создаваемый логический фильтр нигде не используется, во-вторых, метод возвращает список RevitLinkType, а для некоторых задач, все-таки, требуется RevitLinkInstance, т.к. один загруженный файл может использоваться в проекте несколько раз.

Код для такой цели:
Код - C# [Выбрать]
  1. public IEnumerable<Document> GetLinkedDocuments(Document doc)
  2. {
  3.         var categoryFilter = new ElementCategoryFilter(BuiltInCategory.OST_RvtLinks);
  4.         var typeFilter = new ElementClassFilter(typeof(Instance));
  5.         var logicalFilter = new LogicalAndFilter(categoryFilter, typeFilter);
  6.  
  7.         var collector = new FilteredElementCollector(doc);
  8.  
  9.         var linkInstances = collector
  10.                 .WherePasses(logicalFilter)
  11.                 .OfType<RevitLinkInstance>();
  12.  
  13.         return linkInstances
  14.                 .Where(x => RevitLinkType.IsLoaded(doc, x.GetTypeId())) // Это проверка того, что связанный документ не выгружен
  15.                 .Select(x => x.Document);
  16. }

Еще раз повторюсь, что этот код может вернуть один документ несколько раз, если загруженный файл используется в проекте несколько раз

Кроме того, мне не очень нравится фильтр .Where(d => linkedFileNames.Any(fileName => d.PathName.Contains(fileName))), в каком-то, пусть минимально возможном проценте случаев этот код - источник потенциальных проблем. Проще и надежнее сделать Distinct для результатов вышеприведенного метода