public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { Document doc = commandData.Application.ActiveUIDocument.Document; if (!doc.IsWorkshared) { message = "Файл не является файлом совместной работы"; return(Result.Failed);; } //считываю список рабочих наборов string dllPath = System.Reflection.Assembly.GetExecutingAssembly().Location; string folder = System.IO.Path.GetDirectoryName(dllPath); System.Windows.Forms.OpenFileDialog dialog = new System.Windows.Forms.OpenFileDialog(); dialog.InitialDirectory = folder; dialog.Multiselect = false; dialog.Filter = "xml files (*.xml)|*.xml|All files (*.*)|*.*"; if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) { return(Result.Cancelled); } string xmlFilePath = dialog.FileName; InfosStorage storage = new InfosStorage(); System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(InfosStorage)); using (StreamReader r = new StreamReader(xmlFilePath)) { storage = (InfosStorage)serializer.Deserialize(r); } if (storage.LinkedFilesPrefix == null) { storage.LinkedFilesPrefix = "#"; } using (Transaction t = new Transaction(doc)) { t.Start("Создание рабочих наборов"); //назначаю рабочие наборы в случае, если указана категория foreach (WorksetByCategory wb in storage.worksetsByCategory) { Workset wset = wb.GetWorkset(doc); List <BuiltInCategory> cats = wb.revitCategories; if (cats == null) { continue; } if (cats.Count == 0) { continue; } foreach (BuiltInCategory bic in cats) { List <Element> elems = new FilteredElementCollector(doc) .OfCategory(bic) .WhereElementIsNotElementType() .ToElements() .ToList(); foreach (Element elem in elems) { WorksetBy.SetWorkset(elem, wset); } } } //назначаю рабочие наборы по именам семейств List <FamilyInstance> famIns = new FilteredElementCollector(doc) .WhereElementIsNotElementType() .OfClass(typeof(FamilyInstance)) .Cast <FamilyInstance>() .ToList(); foreach (WorksetByFamily wb in storage.worksetsByFamily) { Workset wset = wb.GetWorkset(doc); List <string> families = wb.FamilyNames; if (families == null) { continue; } if (families.Count == 0) { continue; } foreach (string familyName in families) { List <FamilyInstance> curFamIns = famIns .Where(f => f.Symbol.FamilyName.StartsWith(familyName)) .ToList(); foreach (FamilyInstance fi in curFamIns) { WorksetBy.SetWorkset(fi, wset); } } } //назначаю рабочие наборы по именам типов List <Element> allElems = new FilteredElementCollector(doc) .WhereElementIsNotElementType() .Cast <Element>() .ToList(); foreach (WorksetByType wb in storage.worksetsByType) { Workset wset = wb.GetWorkset(doc); List <string> typeNames = wb.TypeNames; if (typeNames == null) { continue; } if (typeNames.Count == 0) { continue; } foreach (string typeName in typeNames) { foreach (Element elem in allElems) { ElementId typeId = elem.GetTypeId(); if (typeId == null || typeId == ElementId.InvalidElementId) { continue; } ElementType elemType = doc.GetElement(typeId) as ElementType; if (elemType == null) { continue; } if (elemType.Name.StartsWith(typeName)) { WorksetBy.SetWorkset(elem, wset); } } } } //назначаю рабочие наборы по значению параметров foreach (WorksetByParameter wb in storage.worksetsByParameter) { Workset wset = wb.GetWorkset(doc); string paramName = wb.ParameterName; string paramValue = wb.ParameterValue; List <Element> elemsFilterByParam = allElems .Where(e => e.LookupParameter(paramName).AsString().Equals(paramValue)).ToList(); foreach (Element elem in elemsFilterByParam) { WorksetBy.SetWorkset(elem, wset); } } //назначаю рабочие наборы для связанных файлов List <RevitLinkInstance> links = new FilteredElementCollector(doc) .OfClass(typeof(RevitLinkInstance)) .Cast <RevitLinkInstance>() .ToList(); foreach (RevitLinkInstance rli in links) { RevitLinkType linkFileType = doc.GetElement(rli.GetTypeId()) as RevitLinkType; if (linkFileType == null) { continue; } if (linkFileType.IsNestedLink) { continue; } string linkWorksetName1 = rli.Name.Split(':')[0]; string linkWorksetName2 = linkWorksetName1.Substring(0, linkWorksetName1.Length - 5); string linkWorksetName = storage.LinkedFilesPrefix + linkWorksetName2; bool checkExists = WorksetTable.IsWorksetNameUnique(doc, linkWorksetName); if (!checkExists) { continue; } Workset.Create(doc, linkWorksetName); Workset linkWorkset = new FilteredWorksetCollector(doc) .OfKind(WorksetKind.UserWorkset) .ToWorksets() .Where(w => w.Name == linkWorksetName) .First(); WorksetBy.SetWorkset(rli, linkWorkset); WorksetBy.SetWorkset(linkFileType, linkWorkset); } t.Commit(); } List <string> emptyWorksetsNames = WorksetTool.GetEmptyWorksets(doc); if (emptyWorksetsNames.Count > 0) { string msg = "Обнаружены пустые рабочие наборы! Их можно удалить вручную:\n"; foreach (string s in emptyWorksetsNames) { msg += s + "\n"; } TaskDialog.Show("Отчёт", msg); } return(Result.Succeeded); }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { Debug.Listeners.Clear(); Debug.Listeners.Add(new RbsLogger.Logger("Worksets")); Document doc = commandData.Application.ActiveUIDocument.Document; if (!doc.IsWorkshared) { message = "Файл не является файлом совместной работы"; Debug.WriteLine("File os not workshared document"); return(Result.Failed);; } //считываю список рабочих наборов string dllPath = System.Reflection.Assembly.GetExecutingAssembly().Location; string dllFolder = System.IO.Path.GetDirectoryName(dllPath); string folder = System.IO.Path.Combine(dllPath, "RevitWorksets_data"); Debug.WriteLine("Default folder for xmls: " + folder); System.Windows.Forms.OpenFileDialog dialog = new System.Windows.Forms.OpenFileDialog(); dialog.InitialDirectory = folder; dialog.Multiselect = false; dialog.Filter = "xml files (*.xml)|*.xml|All files (*.*)|*.*"; if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) { return(Result.Cancelled); } string xmlFilePath = dialog.FileName; Debug.WriteLine("Xml path: " + xmlFilePath); InfosStorage storage = new InfosStorage(); System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(InfosStorage)); using (StreamReader r = new StreamReader(xmlFilePath)) { storage = (InfosStorage)serializer.Deserialize(r); } if (storage == null) { string errormsg = "Unable to deserialize: " + xmlFilePath.Replace("\\", " \\"); Debug.WriteLine(errormsg); throw new Exception(errormsg); } Debug.WriteLine("Deserialize success"); using (Transaction t = new Transaction(doc)) { t.Start("Создание рабочих наборов"); Debug.WriteLine("Start worksets by category"); foreach (WorksetByCategory wb in storage.worksetsByCategory) { Debug.WriteLine("Current workset: " + wb.WorksetName); Workset wset = wb.GetWorkset(doc); List <BuiltInCategory> cats = wb.revitCategories; if (cats == null) { continue; } if (cats.Count == 0) { continue; } foreach (BuiltInCategory bic in cats) { List <Element> elems = new FilteredElementCollector(doc) .OfCategory(bic) .WhereElementIsNotElementType() .ToElements() .ToList(); foreach (Element elem in elems) { WorksetBy.SetWorkset(elem, wset); } } } Debug.WriteLine("Start worksets by family names"); List <FamilyInstance> famIns = new FilteredElementCollector(doc) .WhereElementIsNotElementType() .OfClass(typeof(FamilyInstance)) .Cast <FamilyInstance>() .ToList(); Debug.WriteLine("Family instances found: " + famIns.Count); foreach (WorksetByFamily wb in storage.worksetsByFamily) { Debug.WriteLine("Current workset:" + wb.WorksetName); Workset wset = wb.GetWorkset(doc); List <string> families = wb.FamilyNames; if (families == null) { continue; } if (families.Count == 0) { continue; } foreach (string familyName in families) { List <FamilyInstance> curFamIns = famIns .Where(f => f.Symbol.FamilyName.StartsWith(familyName)) .ToList(); foreach (FamilyInstance fi in curFamIns) { WorksetBy.SetWorkset(fi, wset); } } } Debug.WriteLine("Start worksets by type names"); List <Element> allElems = new FilteredElementCollector(doc) .WhereElementIsNotElementType() .Cast <Element>() .ToList(); Debug.WriteLine("Elements found: " + allElems.Count); foreach (WorksetByType wb in storage.worksetsByType) { Debug.WriteLine("Current workset:" + wb.WorksetName); Workset wset = wb.GetWorkset(doc); List <string> typeNames = wb.TypeNames; if (typeNames == null) { continue; } if (typeNames.Count == 0) { continue; } foreach (string typeName in typeNames) { foreach (Element elem in allElems) { ElementId typeId = elem.GetTypeId(); if (typeId == null || typeId == ElementId.InvalidElementId) { continue; } ElementType elemType = doc.GetElement(typeId) as ElementType; if (elemType == null) { continue; } Debug.WriteLine("Element id: " + elem.Id.IntegerValue + ", TypeName: " + elemType.Name); if (elemType.Name.StartsWith(typeName)) { WorksetBy.SetWorkset(elem, wset); } } } } if (storage.worksetByParameter != null) { Debug.WriteLine("Start worksets by parameters"); string paramName = storage.worksetByParameter.ParameterName; foreach (Element elem in allElems) { Parameter p = elem.LookupParameter(paramName); if (p == null) { continue; } if (!p.HasValue) { continue; } if (p.StorageType != StorageType.String) { string errmsg = "Parameter is not string: " + paramName; Debug.WriteLine(errmsg); throw new Exception(errmsg); } string wsetParamValue = p.AsString(); Workset wsetByparamval = WorksetBy.GetOrCreateWorkset(doc, wsetParamValue); WorksetBy.SetWorkset(elem, wsetByparamval); } } if (storage.worksetByLink != null) { WorksetByLink wsetbylink = storage.worksetByLink; Debug.WriteLine("Worksets for link files"); List <RevitLinkInstance> links = new FilteredElementCollector(doc) .OfClass(typeof(RevitLinkInstance)) .Cast <RevitLinkInstance>() .ToList(); Debug.WriteLine("Links found: " + links.Count); foreach (RevitLinkInstance rli in links) { Debug.WriteLine("Current link: " + rli.Name); RevitLinkType linkFileType = doc.GetElement(rli.GetTypeId()) as RevitLinkType; if (linkFileType == null) { Debug.WriteLine("LinkType is invalid"); continue; } if (linkFileType.IsNestedLink) { Debug.WriteLine("It is nested link"); continue; } char separator = wsetbylink.separator[0]; string linkWorksetName1 = linkFileType.Name.Split(separator)[wsetbylink.partNumberAfterSeparator]; string linkWorksetName2 = linkWorksetName1 .Substring(wsetbylink.ignoreFirstCharsAfterSeparation, linkWorksetName1.Length - wsetbylink.ignoreLastCharsAfterSeparation); string linkWorksetName = wsetbylink.prefixForLinkWorksets + linkWorksetName2; Debug.WriteLine("Workset name: " + linkWorksetName); Workset linkWorkset = WorksetBy.GetOrCreateWorkset(doc, linkWorksetName); WorksetBy.SetWorkset(rli, linkWorkset); WorksetBy.SetWorkset(linkFileType, linkWorkset); } } t.Commit(); } List <string> emptyWorksetsNames = WorksetTool.GetEmptyWorksets(doc); if (emptyWorksetsNames.Count > 0) { string msg = "Обнаружены пустые рабочие наборы! Их можно удалить вручную:\n"; foreach (string s in emptyWorksetsNames) { msg += s + "\n"; } Debug.WriteLine("Empty worksets found: " + msg); TaskDialog.Show("Отчёт", msg); } Debug.WriteLine("Finished"); return(Result.Succeeded); }