Unable to permanently change a parameter group

I was trying to obtain the same thing as this post, i.e. changing parameter groups and noticed the same error: once I save the family or the project then the parameters do not remember that they were moved and go back to their original state.

This is a similar post with a different code posted by @Konrad_K_Sobon but with the same concpet: OLDparameterDefinition.ParameterGroup=NEWgroup

I tried both in the project and the family environment and could not permanently save the changed group, i.e. if I closed and reopened the file the parameters did not change. However if I did it by hand it worked. It seems like we are missing some sort of “update” button, or maybe we have to trick revit in thinking that the edit was done by a human and not by python.

Cattura

In the project environment:

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
import Autodesk

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
import System
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument

pgINstr=IN[0]
pgOUTstr=IN[1]

#From the input strings find the corresponding BuiltInParameterGroup
bpgs=System.Enum.GetValues(BuiltInParameterGroup)
for bpg in bpgs:
	if str(bpg)==pgINstr:
		pgIN=bpg
	if str(bpg)==pgOUTstr:
		pgOUT=bpg

#Create a list with all the project parameters
params = []
iterator = doc.ParameterBindings.ForwardIterator()
while iterator.MoveNext():
	params.append(iterator.Key)

#Change the parameter group of all parameters in the desired paramgroup
pchanged=[]

for pdef in params:
	TransactionManager.Instance.EnsureInTransaction(doc)
	if pdef.ParameterGroup==pgIN:
		pdef.ParameterGroup=pgOUT
		test=pdef.ParameterGroup
		pchanged.append(pdef.Name)
	TransactionManager.Instance.TransactionTaskDone()
	#TransactionManager.Instance.ForceCloseTransaction()

OUT = pchanged

In the family environment:

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

import System

pgGroupStr=IN[0]
pgGroupStr2=IN[1]

bpgs=System.Enum.GetValues(BuiltInParameterGroup)
for bpg in bpgs:
	if str(bpg)==pgGroupStr2:
		pgGroup2=bpg
	if str(bpg)==pgGroupStr:
		pgGroup=bpg

rtn=[]
TransactionManager.Instance.EnsureInTransaction(doc)
params=doc.FamilyManager.Parameters	
for p in params:
	if p.Definition.ParameterGroup==pgGroup:
		rtn.append(p)
		p.Definition.ParameterGroup=pgGroup2

TransactionManager.Instance.ForceCloseTransaction()

OUT=rtn

I tried playing around with ForceCloseTransaction() instead of TransactionTaskDone(), and inserting the transaction in the for loop but nothing changed.

I am not talking about changing a parameter group in a family, uploading it (again) in a project and noticing that the group does not change: this is a well known issue regardless of what Autodesk says: link

A really horrible “workaroud” I found is the following:

  • For the project environemt: run the script, create a new file(rvt or rte template, as in my case), and transfer the standards (the parameters in my case) to the new file.Now use the new file…
  • For the family environment: run the script, create a new file(rvt or rte), load and close the family in the project, export the family from the project.

This is the second time I found such a behaviour (recently I could not permanently change some MEP settings) and would love to understand what line of code I am missing
Thanks

Hi @GregX have you any news about for this task?
Thanks
Cheers

In your project you can loop your desired parameters and write something like this:

for p,g in zip(parameters,desidered_groups)    
	p.GetDefinition().ParameterGroup = g

Hi @GregX thank you for the information,
I’d like to change the type of “Group parameter under” for some of my Project Parameters (project parameter or shared parameter) available in my revit project

it’s possible with GetDefinition method?
Thanks for your efforts
Cheers

Hello @paris could you show what you tried? This forum is to help each other and give hints on something you already tried, people aren’t going to do all the work for you

Hi @GregX
thanks for your answer, yes of course, below the error into my python code:






_Example_change a parameter group_D203.dyn (20.4 KB)
Thanks for your efforts
Cheers

You are nearly there, here are some corrections:

  1. When you bring elements from dynamo to python you have to “unwrap” them, just to “convert” them from “dynamo elements” to “revit elements”. You can do that simply by adding this:
    parameters=UnwrapElement(IN[0])

  2. Next, the error your python gives you is that you are feeding only one parameter group (a single item, not a list), while the iteration thinks that you will give it many parameter groups as parameters. You can either:
    a) repeat your desired parameter group:

OR
b) simply tell python to read only one parameter group:
desidered_group=IN[1]
for p in parameters:
p.GetDefinition().ParameterGroup = desidered_group
(there should be a tab space at the beginning of the last row)

Hi @GregX , awesome, thaks for you answer, you’re right, now it’s work, but if I close the project and after I reopen the project then the parameters do not remember that they were moved and go back to their original state, it’s maybe a bug?
Thanks for your efforts
Cheers

Yes that was my problem at the beginning of this thread. I then used the same code but with shared parameters (and in revit 18 maybe) and I think it worked, maybe try testing it with project parameters and shared parameters to see if there are any differences?
I don’t remember finding out other differences, maybe also the revit version?

Hi @GregX , I’m on Revit 2019 and it doesn’t work as expected, I’m looging for something with Transaction or another method.

Thanks very much
Have a good day
Cheers

Hello
try with this method (tested on Revit 2021)
image

import clr
import System
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument

lstNamepara = IN[0]
pg = IN[1]
outDef = []
newgroup = System.Enum.Parse(BuiltInParameterGroup, pg)

for namPara in lstNamepara:
	bmap = doc.ParameterBindings
	iterator =  doc.ParameterBindings.ForwardIterator()
	while iterator.MoveNext():
		internalDef = iterator.Key
		binding = iterator.Current
		if internalDef.Name == namPara:
			TransactionManager.Instance.EnsureInTransaction(doc)
			bmap.ReInsert(internalDef, binding, newgroup)
			outDef.append(internalDef)
			TransactionManager.Instance.TransactionTaskDone()
			break

OUT = outDef
1 Like

Hi @c.poupin , great! It’s very impressive, on Revit 2019 it’s working as expected but only for shared parameters and not for project parameters, is there a reason? Thank you very much
Have a good day.
Cheers

It’s a Revit API Limitation, Insert() and ReInsert() parameter methods works only with externalDefinition (so need SharedParameter )

Hi @c.poupin
now I understand better, thank you very much for the help on the python node and for the clear explanation.
Have a good day
Thanks
Cheers