Showing results for 
Search instead for 
Did you mean: 
Showing results for 
Search instead for 
Did you mean: 
2024 Technology Preview Program

2024 Technology Preview Program:
Master powerful new features and shape the latest BIM-enabled innovations

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

Python script for column numbering


Is it possible to use a python script to set the ID of the columns, so that all columns of the same dimensions have a common ID.


I have edited zone script and that's working, but every column have unique ID, I need unique ID for column with same dimensions (width, hight, length).



from archicad import ACConnection
from typing import List, Tuple, Iterable
from itertools import cycle

conn = ACConnection.connect()
assert conn

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

propertyId = acu.GetBuiltInPropertyId('General_ElementID')

propertyValueStringPrefix = 'POS S'
elements = acc.GetElementsByType('Column')


def GeneratePropertyValueString(storyIndex: int, elemIndex: int) -> str:
    return f"{propertyValueStringPrefix}{storyIndex:1d}{elemIndex:02d}"

def generatePropertyValue(storyIndex: int, elemIndex: int) -> act.NormalStringPropertyValue:
    return act.NormalStringPropertyValue(GeneratePropertyValueString(storyIndex, elemIndex))

def createClusters(positions: Iterable[float], limit: float) -> List[Tuple[float, float]]:
    positions = sorted(positions)
    if len(positions) == 0:
        return []
    clusters = []
    posIter = iter(positions)
    firstPos = lastPos = next(posIter)

    for pos in posIter:
        if pos - lastPos <= limit:
            lastPos = pos
            clusters.append((firstPos, lastPos))
            firstPos = lastPos = pos
    clusters.append((firstPos, lastPos))
    return clusters

boundingBoxes = acc.Get3DBoundingBoxes(elements)
elementBoundingBoxes = list(zip(elements, boundingBoxes))
zClusters = createClusters((bb.boundingBox3D.zMin for bb in boundingBoxes), STORY_GROUPING_LIMIT)

storyIndex = 0
elemPropertyValues = []
for (zMin, zMax) in zClusters:
    elemIndex = 1
    elemsOnStory = [e for e in elementBoundingBoxes if zMin <= e[1].boundingBox3D.zMin <= zMax]
    yClusters = createClusters((e[1].boundingBox3D.yMin for e in elemsOnStory), ROW_GROUPING_LIMIT)

    for ((yMin, yMax), reverseOrder) in zip(yClusters, cycle([False, True])):
        elemsInRow = [e for e in elemsOnStory
                        if yMin <= e[1].boundingBox3D.yMin <= yMax]

        for (elem, bb) in sorted(elemsInRow, key=lambda e: e[1].boundingBox3D.xMin, reverse=reverseOrder):
                elem.elementId, propertyId, generatePropertyValue(storyIndex, elemIndex)))
            elemIndex += 1
    storyIndex += 1


newValues = acc.GetPropertyValuesOfElements(elements, [propertyId])
elemAndValuePairs = [(elements[i].elementId.guid, v.propertyValue.value) for i in range(len(newValues)) for v in newValues[i].propertyValues]
for elemAndValuePair in sorted(elemAndValuePairs, key=lambda p: p[1]):


Can this script used for change column ID?