development of

Tieghaに関する備忘録とおまけ

【AutoCAD Mechanical】全ての部品表を取得する

全ての部品表を取得するには

図面内に存在する全ての部品表を取得するには、AcmBOMManager::getAllBomTables メソッドを使用します。
このメソッドを使用すると、図面内のすべての部品表のオブジェクトIDを取得できます。

サンプルコード

void GetAllBom()
{
    AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();

    AcDbObjectIdArray bomIds;

    // 全ての部品表のObjectIdを取得
    acmBomMgr->getAllBomTables(bomIds);

    for each (AcDbObjectId bomId in bomIds)
    {
        CMapStringToString valueMap;
        CString bomName;

        // 部品表のデータを取得
        acmBomMgr->getBomData(bomId, bomName, valueMap);
        acutPrintf(_T("\n部品表 [%s] の対象は、"), (LPCTSTR)bomName);

        bool isStructuralyExpanded;
        bool isUsingAssmPath;
        CString structSeparator;
        AcDbObjectIdArray assocLayoutIds;
        AcDbObjectId targetId;

        // 部品表のプロパティを取得
        acmBomMgr->getBomProperties(
            bomId,
            isStructuralyExpanded,
            isUsingAssmPath,
            structSeparator,
            assocLayoutIds,
            targetId);

        AcDbObject *obj;

        // 部品表の対象オブジェクトを取得
        acdbOpenAcDbObject(obj, targetId, AcDb::kForRead);

        // 対象オブジェクトが何なのか確認
        if (obj->isKindOf(AcDbBlockReference::desc()))
        {
            // ブロック参照の場合

            AcDbBlockReference *insert = AcDbBlockReference::cast(obj);
            AcDbObjectId blockId = insert->blockTableRecord();
            AcDbBlockTableRecord *block;
            acdbOpenObject(block, blockId, AcDb::kForRead);
            ACHAR *name;
            block->getName(name);
            acutPrintf(_T("図面枠 [%s] です。"), name);
            block->close();
        }
        else if (obj->isKindOf(AcDbBlockTableRecord::desc()))
        {
            // ブロックテーブルレコードの場合

            AcDbBlockTableRecord *block = AcDbBlockTableRecord::cast(obj);
            ACHAR *name;
            block->getName(name);
            if (acdbSymUtil()->isBlockModelSpaceName(name))
            {
                acutPrintf(_T("図面全体です。"));
            }
            else
            {
                acutPrintf(_T("不明のオブジェクトです。"));
            }
        }
        else
        {
            // その他のオブジェクトの場合

            CString cmpdef = _T("ACAMCOMPDEF");
            // オブジェクトのDXF名を確認
            if (cmpdef.Compare(obj->isA()->dxfName()) == 0)
            {
                // DXF名がコンポーネント定義の場合はストラクチャと判断しています
                acutPrintf(_T("ストラクチャです。"));
            }
            else
            {
                acutPrintf(_T("不明のオブジェクトです。"));
            }
        }
        obj->close();
    }
}

※サンプルコードの補足

サンプルコードでは図面全体の部品表、図面枠の部品表、ストラクチャの部品表かどうかをチェックしていて、ブロック参照を対象としている部品表は図面枠の部品表、モデル空間のブロックテーブルレコードを対象としている部品表は図面全体の部品表、その他のオブジェクトの中で "ACAMCOMPDEF" という DXF 名をもつオブジェクトの場合はストラクチャと判断しています。