We value your input!
Please participate in Archicad 28 Home Screen and Tooltips/Quick Tutorials survey

Archicad Python API
About automating tasks in Archicad using the Python API.
SOLVED!

Zone number to match zone ID using Python?

kmitotk
Advocate

The zone numbering python script that GS provides is nice but has limitations.

As an alternative, I'm trying to make use of the Element ID Manager functionality to automate zone numbering.

Is it possible to overwrite zone numbers with zone IDs using Python?

Operating system used: Windows

Kei Mito

Architect | Graphisoft Certified BIM Manager
ArchiCAD 27 JPN USA & INT | Windows 10

1 ACCEPTED SOLUTION

Accepted Solutions
Solution

I think I've considerably simplified the script:

from archicad import ACConnection

conn = ACConnection.connect()
assert conn, 'Communication Link is not available - timed out'

acc = conn.commands
act = conn.types
acu = conn.utilities

zoneElems = acc.GetElementsByType('Zone')
zoneGuids = [zone.elementId for zone in zoneElems]

zoneNrPropId = acu.GetBuiltInPropertyId('Zone_ZoneNumber')
elemIdPropId = acu.GetBuiltInPropertyId('General_ElementID')

propValues = acc.GetPropertyValuesOfElements(zoneGuids, [elemIdPropId])
EPVArray = []
for zoneGuid, elemProp in zip(zoneGuids, propValues):
    # We can assume that there's only one value,
    # since we pass only one Property Id to GetPropertyValuesOfElements
    elemIdPropVal = elemProp.propertyValues[0]

    normalString = act.NormalStringPropertyValue(elemIdPropVal.propertyValue.value)
    EPV = act.ElementPropertyValue(zoneGuid, zoneNrPropId, normalString)
    EPVArray.append(EPV)

result = acc.SetPropertyValuesOfElements(EPVArray)
print(result)

 
All the checks are not necessary in this case I think, since the built in property General_ElementID should be available for every zone and we know already that it's a string.

View solution in original post

7 REPLIES 7

Unfortunately to my knowledge it's not possible directly with existing Python commands. In general it's not possible to change elements directly and I think the Zone ID is information directly in the element (in contrast to properties, which you can change with the Python API).

Though there's always the possibility to write an Add-On which exposes this to the json/python interface

Edit: My response is completely wrong. Please see the further discussion for clarification.

If I'm not terribly mistaken, there are several built-in properties that can be modified with Python, Zone_ZoneNumber being one of them. See an example script for Zone Numbering at https://graphisoft.com/downloads/python.

 

I'm not sure what is meant by zone id, but Zone_ZoneCategoryCode and Zone_ZoneName are also available as built-in properties.

 

One could also create a new property for zones and use a formula to retrieve the necessary value. This property could then be read with a Python script to populate the built-in property Zone_ZoneNumber.

Thanks for clarifying @vlahtinen! And sorry for causing confusion. I keep making the same mistake and forget about the builtin properties in the Python API! Too focused on the limitations that I forget that there are actually quite a few things possible 😅

So maybe @kmitotk you want to change the Element ID? That would also be a built-in property I think. 'General_ElementID' could do the trick there.

Yeah, no worries, totally understandable given how limited the Python api actually is. 😅

kmitotk
Advocate

Thanks Bernd and vlahtinen.

 

I've found this post that shares python script that can replace wall element ID with its own custom properties. 

 

https://community.graphisoft.com/t5/Archicad-Python-API/Dynamic-ID-Coding-of-Building-Elements/m-p/3... 

 

I'm not even a beginner when it comes to python but after a lot of struggle I was able to modify the script and come up with one that can replace zone number with zone ID. I'll share the script if anyone is interested, but let's give credits to Gerry and _c_ who posted the original scripts.

 

Please note that the original script was intended to replace the wall element ID with a concatenated string of element's two different properties. In my case I didn't need any concatenation so I wanted to remove that function from the script but I couldn't figure out how. So the script has some unnecessary part but nonetheless it works. If anyone can clean up and simply the script, that would be super cool. Thanks!

Kei Mito

Architect | Graphisoft Certified BIM Manager
ArchiCAD 27 JPN USA & INT | Windows 10

Solution

I think I've considerably simplified the script:

from archicad import ACConnection

conn = ACConnection.connect()
assert conn, 'Communication Link is not available - timed out'

acc = conn.commands
act = conn.types
acu = conn.utilities

zoneElems = acc.GetElementsByType('Zone')
zoneGuids = [zone.elementId for zone in zoneElems]

zoneNrPropId = acu.GetBuiltInPropertyId('Zone_ZoneNumber')
elemIdPropId = acu.GetBuiltInPropertyId('General_ElementID')

propValues = acc.GetPropertyValuesOfElements(zoneGuids, [elemIdPropId])
EPVArray = []
for zoneGuid, elemProp in zip(zoneGuids, propValues):
    # We can assume that there's only one value,
    # since we pass only one Property Id to GetPropertyValuesOfElements
    elemIdPropVal = elemProp.propertyValues[0]

    normalString = act.NormalStringPropertyValue(elemIdPropVal.propertyValue.value)
    EPV = act.ElementPropertyValue(zoneGuid, zoneNrPropId, normalString)
    EPVArray.append(EPV)

result = acc.SetPropertyValuesOfElements(EPVArray)
print(result)

 
All the checks are not necessary in this case I think, since the built in property General_ElementID should be available for every zone and we know already that it's a string.

Awesome! This is nice and clean. Thanks so much Bernd!

Now I feel like I should learn a lot more about Python. Seems like there is a huge untapped potential in AC Python API.

Kei Mito

Architect | Graphisoft Certified BIM Manager
ArchiCAD 27 JPN USA & INT | Windows 10

Setup info provided by author