After the recent discussions about the OmniClass and UniFormat parameters, I’ve been thinking about more generic tools optimized for modifying multiple parameters for multiple families.
One option would be to build a big grid-like UI as part of a Revit API app where the parameters could be edited.
Easier would be to export everything to Excel, let you make changes there, and then modify the parameters by reading back in the Excel file. The first half of this process (Export to Excel) could look like this:
In its current state, this isn’t usable for parameters that store element IDs (like Material). But if you could read this data into Revit to set text and numeric parameter values, would it be helpful?
public void FamilyParametersToExcel()
{
Autodesk.Revit.ApplicationServices.Application application = this.Application;
string directory = @"C:\ProgramData\Autodesk\RAC 2013\Libraries\US Imperial\Columns";
string s = "";
// loop through all files in the directory
foreach (string filename in Directory.GetFiles(directory))
{
s += "Family Name,Family Type,";
Document doc = application.OpenDocumentFile(filename);
if (!doc.IsFamilyDocument)
return; // skip any files that are not families
FamilyManager familyManager = doc.FamilyManager;
// sort the family parameters alphabetically
List<string> paramSorted = new List<string>();
foreach (FamilyParameter fp in familyManager.Parameters)
{
paramSorted.Add(fp.Definition.Name);
}
paramSorted.Sort();
// create a header row listing the parameter names for this family
foreach (string paramName in paramSorted)
{
FamilyParameter familyParameter = familyManager.get_Parameter(paramName);
s += familyParameter.Definition.Name + ",";
}
s += "\n";
// create a row for each family type
foreach (FamilyType familyType in familyManager.Types)
{
if (familyType.Name == " ") // skip the 'default' family type with no name
continue;
s += doc.PathName + "," + familyType.Name + ",";
foreach (string paramName in paramSorted)
{
FamilyParameter familyParameter = familyManager.get_Parameter(paramName);
s += ParameterValueForType(familyType, familyParameter) + ",";
}
s += "\n";
}
s += "\n";
doc.Close(false);
}
// write the CSV file to disk
string outfile = directory.Replace(@"\","-").Replace("C:","") + "-Parameters.";
outfile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), outfile);
using (StreamWriter streamWriter = new StreamWriter(outfile))
{
streamWriter.Write(s);
}
// open the CSV file
Process.Start(outfile);
}
private string ParameterValueForType(FamilyType type, FamilyParameter p)
{
// return a string with the value of the parameter for this type
string paramValue = "";
switch (p.StorageType)
{
case StorageType.Double:
paramValue = type.AsDouble(p).ToString();
break;
case StorageType.ElementId:
paramValue = type.AsElementId(p).IntegerValue.ToString();
break;
case StorageType.Integer:
paramValue = type.AsInteger(p).ToString();
break;
case StorageType.String:
paramValue = type.AsString(p);
break;
}
if (paramValue == null)
paramValue = "";
return paramValue;
}
Great Sir!
If it imports and edits the correct parameters, we would be interested. Would it work from the Project as well? Or by directory? Or have to be in the Family? Devil in the details. 🙂