Create Project Parameter with "Values can vary by group instance" selected?

Create Project Parameter with "Values can vary by group instance" selected?

CoderBoy
Advocate Advocate
9,167 Views
19 Replies
Message 1 of 20

Create Project Parameter with "Values can vary by group instance" selected?

CoderBoy
Advocate
Advocate

Greetings.

 

We have a need to create a project parameter of type Text with the Revit API where the "Values can vary by group instance" is selected when we create the parameter, rather than the default of "Values are aligned per group type"

 

The Revit GUI lets us do that with no problem, but we need a way to do that with the API.

 

I have done quite a bit of searching, and cannot seem to find a solution to this problem.

 

How does one do this?

 

Thank you very much.

 

.

0 Likes
Accepted solutions (1)
9,168 Views
19 Replies
Replies (19)
Message 2 of 20

Anonymous
Not applicable

Hi CoderBoy,

 

Try something like this:

 

Okay, so let's say you've created a parameter called Par.

 

InternalDefinition idef = Par.Definition as InternalDefinition;
if (idef != null)

{
  idef.SetAllowVaryBetweenGroups(commandData.Application.ActiveUIDocument.Document, true);  

  Par.Set("value");

}

 

Message 3 of 20

jeremytammik
Autodesk
Autodesk

Dear Remy,

 

Thank you for the suggestion. 

On a side note, is it possible at all to programmatically create a project parameter?

 

Or do you mean that the project parameter is created manually, and your code snippet sets the 'vary between groups' property afterwards?

 

Thank you!

 

Cheers

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 4 of 20

Anonymous
Not applicable
Hi Jeremy, the latter. I assumed CoderBoy knows how to create a parameter, so I was just poiting out how to make it vary between groups. And correct me if I'm wrong, but you can create project parameters, only if they are shared parameters.
0 Likes
Message 5 of 20

jeremytammik
Autodesk
Autodesk

Hi Remy,

 

I believe you are absolutely right on all counts.

 

Except I thought 'project parameter' and 'shared parameter' were mutually exclusive.

 

Can a parameter be both project and shared?

 

I do not believe so.

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 6 of 20

Anonymous
Not applicable
A project parameter MUST be shared. At least, I didn't find a way in the API to create non-shared project parameter.
0 Likes
Message 7 of 20

jeremytammik
Autodesk
Autodesk

I thought you can only create project parameters manually.

 

Can project parameters be both shared and non-shared?

 

In that case, presumably the former can be created and manipulated programmatically, and the latter not?

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 8 of 20

CoderBoy
Advocate
Advocate

Hi guys.

 

Thanks for the thoughts!

 

You can create a project parameter that is a shared parameter with the API.  Yes, the teminology is weird to some people, so I'll describe things as they appear in the GUI.

 

If in the GUI you go to Manage Parameters for the project and create a new project-level parameter, which you will assign to one or more categories, you can select whether the new parameter is Project or Shared.  It's my understanding that it's the Shared kind which is the only kind which can be created by the API anyway.  We can do that, so no problems there.

 

We'd need to create it as an Instance parameter, so again no problems there with the API (as I recall).

 

When creating it with the GUI, it appears that for non-numeric-based parameter types, including Text parameters (which we need), you get the choice to either make it:

 

1) "Values are aligned per group type" -- meaning this Instance parameter doesn't act like an instance parameter when in multiple instances of a group.  The parameter value is forced to be the same for all family instances created automatically when more group instances are created, and stays the same if one family instance within a group has the value changed.  So in the first group instance, if on a family instance within the group (mouseover and tabbing into it), I set the text parameter value to "X" it gets changed to "X" on that same family's parameter in all other instances of that group.  

 

EXCEPT for cases like Mark and (I believe) Room Number, which I've read online are hard-coded into Revit to always act like instance parameters, even when used within groups.  Those can have different values in every group instance (imagine the group contains doors, which is our case).  But if they're any other (or your own) instance parameters (shared or not) even if they were declared as instance parameters, they're forced to have the same value whenever you change the value on any one family within the group definition.  (see first example, below)

 

So when "Values are aligned per group type" is selected, your instance parameter behaves essentially like a type parameter, with the group definition kind of being the type definition (try to wrap your head around that...).  I believe it's value can vary within each group definition, but when multiple instances of a group definition are placed, it MUST have the same value at all times for all of those instances.  

 

This is the default behavior, it appears to be the behavior required for numeric-based parameter types, and it's my understanding was the only behavior that was available before Revit 2014.

 

So in this case:

 

Group Instance 1  (of type "MyGroup")

  Family 1 within the group

     Instance Parameter 1 = "Value 1"

  

Group Instance 2  (of type "MyGroup")

  Family 1 within the group

     Instance Parameter 1 = "Value 1"

  

Group Instance 3  (of type "MyGroup")

  Family 1 within the group

     Instance Parameter 1 = "Value 1"

 

If I mouse over Family 1 in Group Instance 1, tab into it and change Instance Parameter 1 to have a new value of "Value 2" subesquently ALL 3 GROUPS automatically have "Value 2" on that same parameter within the same family within the group.  This is true even if that parameter was defined as Instance.

 

2) It's my understanding that "Values can vary by group instance" was added for Revit 2014 to resolve problems supporting COBie standards.  This makes parameters declared as Instance (at least when declared at the project-level and bound by category) actually act like instance parameters when multiple (err) instances of a group are created.  

 

So with this value set as the Instance parameter is being created at the project-level (or changed later?), I can have 3 group instances, and a family within each instance can have different values for that parameter in each group instance:

 

Group Instance 1  (of type "MyGroup")

  Family 1 within the group

     Instance Parameter 1 = "Value 1"

 

 

Group Instance 2  (of type "MyGroup")

  Family 1 within the group

     Instance Parameter 1 = "Value 2"

 

 

Group Instance 3  (of type "MyGroup")

  Family 1 within the group

     Instance Parameter 1 = "Value 3"

 

 

This is the behaviour our add-in is required to have for our own Instance parameter.  And it CAN be accomplished manually in the Revit GUI.

 

 

So here's the kicker:  it is also my understanding (and recollection from trying this in the past with project-level parameters declared as shared) that shared parameters DO NOT have an InternalDefinition, they only have an ExternalDefinition, and if you look in the API the ExternalDefinition does not have the SetAllowVaryBetweenGroups method.

 

Since it's my understanding that we can only create project-level parameters that are Shared, I think I'm stuck.

 

I knew all of this before posting, including that InternalDefinitions have the SetAllowVaryBetweenGroups method, but really should have spelled out the situation in more detail, as I have just done. My apologies for that.  It's easy to presume everyone has the same frame of reference that you do.

 

So in summary, this is my conundrum:

 

With only the API, how do I create a project-level Text parameter (shared or not, I think shared is desirable for our add-in), assigned to the Doors category, that is Instance which can have the SetAllowVaryBetweenGroups method be called, so I can get the behaviour demonstrated in the second example above to occur?

 

Or, really, any way that I can get the behaviour demonstrated in the second example above to occur.  I'll take anything at this point.

 

I really need help getting this resolved.

 

Thank you so very much for your time and expertise.

 

 

Message 9 of 20

jeremytammik
Autodesk
Autodesk

Dear CoderBoy,

 

Thank you for your clarification and explanations.

 

Yes, I believe I spend half my life's hours struggling with the fact that it is "easy to presume everyone has the same frame of reference that you do". Everybody does that. Almost. I love people who understand and adapt to the receiver's point of view when communicating. You did a really good job now 🙂

 

You did not specifically state that you tried to make use of Remy's initial suggestion, but I assume that is the case and it cannot be resolved that way.

I therefore submitted the wish list item CF-3726 [API wish: create project parameter with "Values can vary by group instance" selected] on your behalf for the functionality you suggest, as this issue requires exploration and possibly a modification to our software. Please make a note of this number for future reference.

 

I'll let you know as soon as the development team react to that.

 

If you do not hear anything more from me within a couple of days, please let me know, so I can prompt them for a reaction.

 

Thank you!

 

I hope this helps.

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 10 of 20

CoderBoy
Advocate
Advocate
Accepted solution

Hi Jeremy.

 

Thank you very much for doing that, but I think you may be able to cancel that API request, as I seem to have found a solution!!! (at least for Revit 2016, not R2).  It's not immediately intuitive, but it does seem to work.

 

When I create the shared parameter and add it to the project as a new Project Parameter, the ExternalDefinition for the new parameter can be cast to a base Definition successfully, but that Definition cannot be cast to an InternalDefinition.  That always comes back null.

 

Since the only way to change the parameter to SetAllowVaryBetweenGroups is via the InternalDefinition, you're out of luck.  That's why I was stuck.

 

However, the key to the solution is to essentially "ask again."

 

If you ask for the parameter back by iterating over the Project Parameters, the result will now have an InternalDefinition available.  I thought it would have only an ExternalDefinition (as Family document parameters do) but that doesn't seem to be the case.

 

 

Anyway, once I can get to the InternalDefinition for this shared parameter, calling the SetAllowVaryBetweenGroups works just fine.

 

There is still a previously-discussed potential issue that I (now) recall, but it may be minor in most cases.  The issue is that you can't (easily) get the ExternalDefinition back from the project parameter list to verify the GUID matches the one from the shared parameters file.  This is desirable because you *can* have many Project Parameters with the same case-sensitive name.  This can happen if one is not shared and another is shared, or if many are shared but each have different GUIDs.

 

So verifying you're calling SetAllowVaryBetweenGroups on the *correct* Project Parameter could still be an issue.

 

But at least there is a reasonable path for what we need.

 

Thanks again for your assistance.

 

.

 

 

Message 11 of 20

jeremytammik
Autodesk
Autodesk

Dear CoderBoy,

 

Thank you for your update.

 

Congratulations on solving this!

 

Would you like to share a code snippet that illustrates this rather convoluted-sounding procedure?

 

Would it be possible to encapsulate it into a stand-alone method taking the ExternalDefinition as an input parameter and returning the corresponding InternalDefinition?

 

As far as I understand the situation, that sounds as if it might be an absolutely optimal solution.

 

Thank you!

 

I also added your notes to the wish list item CF-3726 [API wish: create project parameter with "Values can vary by group instance" selected] and we will see what the development team have to say about it.

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 12 of 20

CoderBoy
Advocate
Advocate

Hi Jeremy.

 

If you're referring to the rather convoluted mess of finding the GUID for a project parameter that is Shared, the workaround code for the best solution I/we could come up with is documented in this thread:

 

https://forums.autodesk.com/t5/revit-api/reporting-on-project-parameter-definitions-need-guids/td-p/...

 

Otherwise to create a project parameter is fairly well documented (for example, here:  http://spiderinnet.typepad.com/blog/2011/05/parameter-of-revit-api-31-create-project-parameter.html) and iterating over the project parameters is fairly straightforward as well:

 

 

BindingMap map = document.ParameterBindings;
DefinitionBindingMapIterator it = map.ForwardIterator();
it.Reset();
while (it.MoveNext())
{
    Definition definition = it.Key;

    if (definition.Name == "MyNewParameterName")
    {

        // TODO:  Verify the GUID matches the one for the shared parameter we just added

        InternalDefinition internalDef = definition as InternalDefinition;

        if (internalDef != null)
        {
            internalDef.SetAllowVaryBetweenGroups(document, true);
        }

    }

}

 

 

 

Message 13 of 20

Anonymous
Not applicable

Sorry to resurrect an old thread, but I'm also trying to add a new field or fields to Project Properties via the API and I'm getting stuck in a similar fashion.  I implemented CoderBoy's code, but I'm getting a crash at the SetAllowVaryBetweenGroups method:

 

 

************** Exception Text **************
Autodesk.Revit.Exceptions.ArgumentException: This parameter does not support the specified value of allowVaryBetweenGroups.
Parameter name: allowVaryBetweenGroups
at Autodesk.Revit.DB.InternalDefinition.SetAllowVaryBetweenGroups(Document document, Boolean allowVaryBetweenGroups)

You'd think it wouldn't be so difficult to add some metadata to a file.  I'm just trying to lace in some Shotgun data for pipeline purposes.  Stuff like project code, building code, asset name, etc.  I can pull the data from Shotgun, but trying to write it to Revit is turning out to be really difficult.

 

Thanks!

0 Likes
Message 14 of 20

Anonymous
Not applicable

Well Chris,

 

You can check your parameter through the CUI. With groups only text parameters are allowed to have this setting. The interesting parameters with values can't be used. THe only one I found and sometimes use as a boolean is a currency parameter. But length, area ect. parameters, forget it.

 

I mailed it to Adesk support some time ago and the gave an explanation that parameters like length and area, could make a family instable and that's why they restricted it to mostly textparameters.

 

 

Message 15 of 20

CoderBoy
Advocate
Advocate

Hey Chris.

 

Would using extensible storage be a solution for you?  I think you can attach an extensible storage object to each element of interest (each separate instance).  This should effectively give you values that vary by instance.  However, this data will be invisible to the user, so they won't be able to do things like include it in a schedule, as you could with parameters.

 

Otherwise it looks like you'll have to use all text parameters, but maybe that's ok for your purposes?

 

.

0 Likes
Message 16 of 20

Anonymous
Not applicable

Invisible to the user is actually preferred.  We're just trying to tie some metadata to the project to follow it along through the conversion pipeline for previs and other needs.  I'll look into this "extensible storage object" you speak of.

 

Thank you

0 Likes
Message 17 of 20

c_hanschen
Advocate
Advocate

@CoderBoy ,

 

Thanks a lot for sharing this...!!!

 

your code was very usable for me!

 

Chris Hanschen

The Netherlands

0 Likes
Message 18 of 20

Dronov.Dmitry
Advocate
Advocate

Thx.
I have the same problem for "Number" parameter in Revit 2022

DronovDmitry_0-1641125637033.png

It's time to get used to the performance )) and trying to relax with them))

 

0 Likes
Message 19 of 20

jeremy_tammik
Alumni
Alumni

Dear Dmitry,

 

Happy New Year to you!

  

Can you achieve the desired result manually in the end user interface? If not, the Revit API will hardly support it either...

 

Cheers,

 

Jeremy

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 20 of 20

Moustafa_K
Collaborator
Collaborator

Hi,

check this out. "vary by group instance" are subjected to limited variable types. see this link

  • Text
  • Area
  • Volume
  • Currency
  • Mass Density
  • URL
  • Material
  • <Family Type>

The Number Type is not one of those.

Moustafa Khalil
Cropped-Sharp-Bim-500x125-Autodesk-1
0 Likes