บทที่ 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 ใหม่ผ่าน ProgIDetabs = comtypes.client.CreateObject("CSI.ETABS.API.ETABSObject")
# เริ่ม ETABS applicationetabs.ApplicationStart()
# เข้าถึง SapModelsap_model = etabs.SapModel
# เปิดโมเดลret = sap_model.File.OpenFile(r"C:\Models\MyBuilding.EDB")Error Handling ที่ควรมี
import comtypes.clientimport gc
etabs = Nonesap_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.clientimport 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