Bulk Family Parameter Editing in Excel

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;
}
 

2 thoughts on “Bulk Family Parameter Editing in Excel

Leave a reply to flaxoice Cancel reply