MicroStation Python, C++ and C# programmers work mostly with UORs (Units-of-Resolution). Many functions receive or yield values in UORs. If you want to present your measurements to a user, then you should convert from UORs to a human metric, such as …
The classes introduced here perform conversion from UORs to your preferred units …
MicroStation Visual Basic for Applications (VBA) works with master units, not UORs. The formatters discussed here do not work with VBA.
Use class DistanceFormatter.
Here's an example …
def format_distance_value(value_uors: float, dgn_model: DgnModel = ISessionMgr.GetActiveDgnModel()) -> str:
"""
Format a numeric value (in storage units) using DistanceFormatter.
The script:
- Uses the active model's master & storage units
- Sets a decimal precision
- Returns the formatted string (e.g. "1.23" or "1.2345" depending on precision)
"""
modelInfo = dgn_model.GetModelInfo()
if modelInfo is None:
print("format_distance_value Error: Could not get ModelInfo.", file=sys.stderr)
return ""
# Get master and storage units from the model
master_unit = modelInfo.GetMasterUnit()
sub_unit = modelInfo.GetSubUnit()
storage_unit = modelInfo.GetStorageUnit()
uor_per_storage = modelInfo.GetUorPerStorage()
formatter = DistanceFormatter.Create()
# Basic settings – adjust as needed
formatter.SetWorkingUnits(master_unit, sub_unit)
formatter.SetStorageUnit(storage_unit, uor_per_storage)
formatter.SetPrecision(PrecisionFormat.eDecimal2Places) # 2 decimal places
formatter.SetUnitLabelFlag(True)
formatter.SetLeadingZero(True)
formatter.SetTrailingZeros(True)
formatter.SetInsertThousandsSeparator(False)
formatter.SetThousandsSeparator(',')
formatter.SetDecimalSeparator('.')
# Do not suppress zero master/sub units
formatter.SetSuppressZeroMasterUnits(False)
formatter.SetSuppressZeroSubUnits(False)
# Use master/sub unit format (e.g. "1.234 m" or similar)
formatter.SetUnitFormat(DgnUnitFormat.eMU)
# Scale factor: 1.0 means no extra scaling beyond units
formatter.SetScaleFactor(1.0)
# Set UOR-per-storage for the formatter
formatter.SetStorageUnit(storage_unit, uor_per_storage)
# The DistanceFormatter expects the value in "uor" (storage units).
# If the caller passes a value in master-unit, convert it.
# Here we assume the input is in master-unit and convert to storage.
#
# Convert 1 master-unit distance to storage units:
# storage_val = storage_unit.ConvertDistanceFrom(1.0, master_unit)[1]
try:
conv_status, storage_per_master = storage_unit.ConvertDistanceFrom(1.0, master_unit)
if conv_status != BentleyStatus.eSUCCESS:
print("Warning: Unit conversion failed, using raw value.", file=sys.stderr)
value_uor2 = value
else:
distance_scale = storage_per_master * storage_per_master
value_uor2 = value_uors * distance_scale
except Exception as ex:
print(f"Warning: format_distance_value exception during unit conversion: {ex}", file=sys.stderr)
value_uor2 = value
# Format the value
out_wstr = formatter.ToString(value_uor2)
return str(out_wstr)
Use class AreaFormatter
def format_area_value(value: float, dgn_model: DgnModel = ISessionMgr.GetActiveDgnModel()) -> str:
"""
Format a numeric value (in storage units^2) using AreaFormatter.
The script:
- Uses the active model's master & storage units
- Sets a decimal precision
- Returns the formatted string (e.g. "1.23m2" or "1.2345m2" depending on precision)
"""
modelInfo = dgn_model.GetModelInfo()
if modelInfo is None:
print("Error: Could not get ModelInfo.", file=sys.stderr)
return ""
# Get master and storage units from the model
master_unit = modelInfo.GetMasterUnit()
storage_unit = modelInfo.GetStorageUnit()
uor_per_storage = modelInfo.GetUorPerStorage()
formatter = AreaFormatter.Create()
# Basic settings – adjust as needed
formatter.SetPrecision(PrecisionFormat.eDecimal2Places) # 2 decimal places
formatter.SetShowUnitLabel(True)
formatter.SetLeadingZero(True)
formatter.SetTrailingZeros(True)
formatter.SetInsertThousandsSeparator(False)
formatter.SetThousandsSeparator(',')
formatter.SetDecimalSeparator('.')
# Scale factor: 1.0 means no extra scaling beyond units
formatter.SetScaleFactor(1.0)
# Set units and UOR-per-storage for the formatter
formatter.SetMasterUnit(master_unit)
formatter.SetStorageUnit(storage_unit, uor_per_storage)
# The AreaFormatter expects the value in "uor^2" (storage units squared).
# If the caller passes a value in master-unit^2, convert it.
# Here we assume the input is in master-unit^2 and convert to storage^2.
#
# Convert 1 master-unit distance to storage units:
# storage_val = storage_unit.ConvertDistanceFrom(1.0, master_unit)[1]
# Then area scale = storage_val^2
try:
conv_status, storage_per_master = storage_unit.ConvertDistanceFrom(1.0, master_unit)
if conv_status != BentleyStatus.eSUCCESS:
print("Warning: Unit conversion failed, using raw value.", file=sys.stderr)
value_uor2 = value
else:
area_scale = storage_per_master * storage_per_master
#print(f"format_area_value area_scale={area_scale}")
value_uor2 = value * area_scale
#print(f"format_area_value value_uor2={value_uor2}")
except Exception as ex:
print(f"Warning: Exception during unit conversion: {ex}", file=sys.stderr)
value_uor2 = value
# Format the value
out_wstr = formatter.ToString(value_uor2)
return str(out_wstr)
You'll find an implementation of distance and area formatters in the Grouped Holes Example.
Use class VolumeFormatter.