ข้ามไปยังเนื้อหา

บทที่ 4 เชื่อม ETABS

สองวิธีเชื่อม ETABS

วิธีใช้เมื่อFunction
Attach (GetActiveObject)เชื่อม ETABS ที่เปิดอยู่แล้วcomtypes.client.GetActiveObject(...)
Create (CreateObject)สร้าง ETABS instance ใหม่comtypes.client.CreateObject(...)

ในงานจริง Attach ใช้บ่อยกว่า เพราะวิศวกรมักเปิด ETABS และโมเดลไว้แล้ว แล้วจึงรันสคริปต์ Python เพื่อดึงข้อมูล

วิธีที่ 1: Attach (แนะนำ)

เชื่อมกับ ETABS instance ที่เปิดอยู่:

import comtypes.client
# เชื่อมกับ ETABS ที่เปิดอยู่
# ProgID เดียวกันทุก version: "CSI.ETABS.API.ETABSObject"
etabs = comtypes.client.GetActiveObject("CSI.ETABS.API.ETABSObject")
# เข้าถึง SapModel (object หลักของโมเดล)
sap_model = etabs.SapModel

วิธีที่ 2: Create (สร้างใหม่)

สร้าง ETABS process ใหม่โดยไม่ต้องเปิดก่อน:

import comtypes.client
# สร้าง ETABS instance ใหม่ผ่าน ProgID
etabs = comtypes.client.CreateObject("CSI.ETABS.API.ETABSObject")
# เริ่ม ETABS application
etabs.ApplicationStart()
# เข้าถึง SapModel
sap_model = etabs.SapModel
# เปิดโมเดล
ret = sap_model.File.OpenFile(r"C:\Models\MyBuilding.EDB")

Error Handling ที่ควรมี

import comtypes.client
import gc
etabs = None
sap_model = None
try:
etabs = comtypes.client.GetActiveObject("CSI.ETABS.API.ETABSObject")
# ตรวจสอบว่า connect สำเร็จ
if etabs is None:
print("❌ ไม่สามารถเชื่อม ETABS ได้")
print(" → ตรวจสอบว่า ETABS เปิดอยู่")
exit(1)
sap_model = etabs.SapModel
if sap_model is None:
print("❌ ไม่สามารถเข้าถึง SapModel ได้")
print(" → ตรวจสอบว่าเปิดโมเดลใน ETABS แล้ว")
exit(1)
print("✅ เชื่อม ETABS สำเร็จ!")
# ... ทำงานกับ API ต่อ ...
except OSError as e:
print(f"❌ COM Error: {e}")
print(" → ตรวจสอบว่า ETABS เปิดอยู่ และ comtypes ติดตั้งถูกต้อง")
except Exception as e:
print(f"❌ Error: {e}")
finally:
# Cleanup COM objects (รายละเอียดในบทที่ 8)
if sap_model is not None:
del sap_model
if etabs is not None:
del etabs
gc.collect()

Helper Class: EtabsConnector

สำหรับโปรเจกต์ที่ใหญ่ขึ้น แนะนำสร้าง class แยกที่รองรับ with statement:

import comtypes.client
import gc
class EtabsConnector:
"""จัดการ connection และ lifecycle ของ ETABS COM objects
ใช้กับ with statement เพื่อ auto-cleanup
"""
def __init__(self):
self.etabs = None
self.sap_model = None
def attach(self) -> bool:
"""เชื่อม ETABS ที่เปิดอยู่ return True ถ้าสำเร็จ"""
try:
self.etabs = comtypes.client.GetActiveObject(
"CSI.ETABS.API.ETABSObject"
)
if self.etabs is None:
return False
self.sap_model = self.etabs.SapModel
return self.sap_model is not None
except OSError:
return False
def close(self):
"""Release COM objects"""
if self.sap_model is not None:
del self.sap_model
self.sap_model = None
if self.etabs is not None:
del self.etabs
self.etabs = None
gc.collect()
# Context Manager support
def __enter__(self):
if not self.attach():
raise ConnectionError("ไม่สามารถเชื่อม ETABS ได้")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
return False # ไม่ suppress exception

การใช้งานด้วย with:

with EtabsConnector() as conn:
# ใช้งาน conn.sap_model ตามปกติ
path = conn.sap_model.GetModelFilename()
print(f"Model: {path}")
# ← close() เรียกอัตโนมัติเมื่อออกจาก with block

ตรวจสอบว่า Connect สำเร็จ

หลัง connect แล้ว ทดสอบด้วยการอ่านข้อมูลง่ายๆ:

# ทดสอบอ่านชื่อไฟล์
model_file = sap_model.GetModelFilename()
print(f"📁 Model: {model_file}")
# ทดสอบอ่าน units ปัจจุบัน
units = sap_model.GetPresentUnits()
print(f"📐 Units: {units}")

Expected output:

📁 Model: C:\Models\MyBuilding.EDB
📐 Units: 6