Read Instance Parameter Value from Revit Component

Like check this out, the same elements but a different parameter:

Would you be able to share a revit file with just couple of doors/elements to have a look at?

sure, this is not a door, but a simple generic model family. Here’s a sample file with a few family instances:

TestFile.rvt (5.6 MB)

Japhy was referring to a curtain wall door panel in his example. I suppose ‘Height’ in particular, as well as a few other system parameters would probably cause such trouble

Ok I see the issue now when the family has the instance parameter with the same name as well… only work around I see for now for you to continue work is the boolean ReadOnly we mentioned before and the inspect element indeed.

It is weird how “Element Parameter” is not showing both or the correct one.

Maybe @Japhy and @kike would be able to see if it is an issue to be resolved

1 Like

Indeed, thx!

If i recall we used to give a warning there, ‘Height’ is ambiguous, please use Query Element Parameters or something like that.

We prioritize the BuiltInParameter return first.

This might be a case of providing too much, but erroring on that side IMO is better than restricting the user.

Yeah, but I still don’t get where that BuiltInParameter is coming from, as this element for example clearly only has one Height and its the instance. The other one is also not visible through the API

1 Like

Hi @Danail,

When a text is converted to a parameter-key RiR search all BuiltInParameter that are called like this.
And then use some logic to decide in case of conflict.

This Element has the BuiltInParameter.CURTAIN_WALL_PANELS_HEIGHT (-1010300) defined.
This code returns an instance of a ARDB.Parameter and shows the assert message even the parameter is not visible on the UI.

var parameter = element.get_Parameter(BuiltInParameter.CURTAIN_WALL_PANELS_HEIGHT);
Debug.Assert(parameter == null);

I’m going to update this logic to give priority to those parameters that do have a value over those that do not.

public static Parameter GetParameter(this Element element, string name, ParameterClass set)
{
  return element.GetParameters(name, set).
    OrderByDescending(x => x.HasValue).         // Order descending by HasValue to give priority to parameters that do have a value.
    ThenByDescending(x => x.Id.IsBuiltInId()).  // Then by IsBuiltInId to give priority to built-in parameters.
    ThenBy(x => x.IsReadOnly).                  // Then by IsReadOnly to give priority non read-only parameters.
    ThenByDescending                            // Then by storage-type to give priority ElementId parameters over String ones.
    (
      x => x.Id.TryGetBuiltInParameter(out var bip) ?
      x.Element.Document.get_TypeOfStorage(bip) :
      StorageType.None
    ).
    FirstOrDefault();
}

This should be enough to return the family instance parameter in case it is defined and conflicts with a built-in one that do not have value.

1 Like

That’s great! :slight_smile: I’m not sure this will help and I haven’t tested it for a curtain wall panel family instance, but for my Generic Model family, I have tried it like that:

and it worked fine. Simply Element.Parameters, then you circle through the set. I’m not sure it will be the same for Curtain Wall panel, but it should be as the ‘non-existing’ height’s ID is the same. I will check though

I believe that’s what Element.Parameters method is for:

image

It already gets rid of the unwanted ones. It should probably simplify things. Not sure though… just a suggestion, I’ve already submitted enough spam in this topic anyway :smiley:

Element.Parameters give you a curated list of parameters, but not all the available parameters under an Element.

For instance this one is not available in Element.Parameters but is always there. There are others.

var param = element.get_Parameter(ARDB.BuiltInParameter.ID_PARAM)

The goal of ‘Query Element Parameters’ is give them all.

An other way of giving priority to those visible parameters over the more obscure ones may be check if they are contained in the Element.Parameters set, but is not the fastest property ever, because it has to iterate over all the parameters on the element and build a set. It seems too much just to test if one is contained.

For this situation Revit API provides Element.LookupParameter(string name) but the documentation reads like this.

This method will attempt to find a parameter on this Element whose name matches the input. The possible results include:

  • A single matching parameter is found: it will be returned.
  • No matching parameter is found: null is returned.
  • Multiple matching parameters exist. In this situation the first one encountered will be returned. This match is determined at random and may change in the future…

The word “random” and “may change in the future” in the description are the reasons that made me avoid calling it and do my own.

Anyway, thanks for all you research on this topic.

1 Like