Author Topic: Inserts Table Generation ?  (Read 12469 times)

0 Members and 1 Guest are viewing this topic.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Inserts Table Generation ?
« Reply #15 on: April 21, 2006, 09:58:54 PM »
.. and ditto for 2006
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

LE

  • Guest
Re: Inserts Table Generation ?
« Reply #16 on: April 21, 2006, 10:03:25 PM »
It must be the same but updated for the new properties and methods for the AcDbTable Class, I'm still using a2005.

I went and read like 20 or more times the one that comes with SDK 2005, and the only portion of code that was good is the part I used for the merging of the title row area, the rest it is very confused... and intended for blocks with attributes.


Thanks!

LE

  • Guest
Re: Inserts Table Generation ?
« Reply #17 on: April 22, 2006, 11:46:50 AM »
OK, we need code, here is what I end up using and works without any problems:

I am using some macros, to avoid some typing and they are very simple to reproduce, HTH

Code: [Select]
// by www.geometricad.com - LE
static int InsertsTable () {
AcDbTable *pTable = NULL;
pTable = new AcDbTable();
// 2 rows - title and headers
pTable->insertRows(0,10.0);
// 3 columns
pTable->insertColumns(0,10.0,2);
pTable->setTextString(0,0,"TITLE");
// merge the first row for the title
pTable->mergeCells(0,0,0,pTable->numColumns() - 1);
// headers titles
pTable->setTextString(1,0,"Preview");
pTable->setTextString(1,1,"Name");
pTable->setTextString(1,2,"Number");
if (pTable->generateLayout() == Acad::eOk) {
acutPrintf("\nTable updated.");
AcDbObjectId curSpaceId=CURDB()->currentSpaceId();
AcDbBlockTableRecord *pBlkRec = NULL;
if (acdbOpenObject(pBlkRec, curSpaceId, AcDb::kForWrite)==Acad::eOk) {
pBlkRec->appendAcDbEntity(pTable);
pBlkRec->close();
pTable->close();
}
Acad::ErrorStatus es;
AcDbObjectId objId;
ads_name ename;
acdbEntLast(ename);
acdbGetObjectId(objId,ename);
AcDbObjectPointer<AcDbTable> pTable(objId, AcDb::kForWrite);
if ((es = pTable.openStatus()) == Acad::eOk) {
int row = 2;
AcDbBlockTablePointer pBlockTable(CURDB(), AcDb::kForRead);
EOK(pBlockTable.openStatus());
AcDbBlockTableIterator *pBTIterator;
Acad::ErrorStatus es = pBlockTable->newIterator(pBTIterator, true, true);
if (!EOKM(es))
return false;
for (; !pBTIterator->done(); pBTIterator->step()) {
AcDbObjectId BTRId;
es = pBTIterator->getRecordId(BTRId);
if (!EOKM(es)) {
delete pBTIterator;
return false;
}
AcDbBlockTableRecordPointer pBlockTableRecord(BTRId, AcDb::kForRead);
EOK(pBlockTableRecord.openStatus());
if (// no anonymous blocks
pBlockTableRecord->isAnonymous() ||
// no xref's
pBlockTableRecord->isFromExternalReference() ||
// no overlaid xref's
pBlockTableRecord->isFromOverlayReference() ||
// no block layouts *MODEL_SPACE, *PAPER_SPACE...
pBlockTableRecord->isLayout()) {
continue;
}
AcDbBlockTableRecordIterator *pBTRIterator = NULL;
es = pBlockTableRecord->newIterator(pBTRIterator);
if (!EOKM(es))
continue;
const TCHAR *bName;
es = pBlockTableRecord->getName(bName);
if (!EOKM(es)) {
delete pBTIterator;
return false;
}
char text [33];
AcDbObjectIdArray ids;
if (pBlockTableRecord->getBlockReferenceIds(ids) == Acad::eOk) {
int cnt;
cnt = ids.length();
itoa(cnt,text,10);
}
if (pTable->insertRows(pTable->numRows(), pTable->rowHeight(1)) == Acad::eOk) {
pTable->setBlockTableRecordId(row,0,pBlockTableRecord->objectId(),true);
pTable->setAlignment(row,0,AcDb::kMiddleCenter);
pTable->setTextString(row,1,bName);
pTable->setAlignment(row,1,AcDb::kMiddleCenter);
pTable->setTextHeight(row,1,1.65);
pTable->setTextString(row,2,text);
pTable->setAlignment(row,2,AcDb::kMiddleCenter);
pTable->setTextHeight(row,2,1.65);
} else {
acutPrintf("\nIt is not a TABLE or it can not be opened: %s",
acadErrorStatusText(es));
}
row = (row + 1);
}
delete pBTIterator;
if (pTable->generateLayout() == Acad::eOk) {
acutPrintf("\nTable updated.");
}
}
}
}
« Last Edit: April 22, 2006, 11:56:36 AM by LE »

LE

  • Guest
Re: Inserts Table Generation ?
« Reply #18 on: April 22, 2006, 11:53:41 AM »
And here is the other try to first populate the table and later appending the object into the current data base, but does not work, it produces the table on the drawing, and after some seconds, autocad just close....  :-(

Code: [Select]
//by www.geometricad.com - LE
static int InsertsTable () {
AcDbTable *pTable = NULL;
pTable = new AcDbTable();
// 2 rows - title and headers
pTable->insertRows(0,10.0);
// 3 columns
pTable->insertColumns(0,10.0,2);
pTable->setTextString(0,0,"TITLE");
// merge the first row for the title
pTable->mergeCells(0,0,0,pTable->numColumns() - 1);
// headers titles
pTable->setTextString(1,0,"Preview");
pTable->setTextString(1,1,"Name");
pTable->setTextString(1,2,"Number");
int row = 2;
AcDbBlockTablePointer pBlockTable(CURDB(), AcDb::kForRead);
EOK(pBlockTable.openStatus());
AcDbBlockTableIterator *pBTIterator;
Acad::ErrorStatus es = pBlockTable->newIterator(pBTIterator, true, true);
if (!EOKM(es))
return false;
for (; !pBTIterator->done(); pBTIterator->step()) {
AcDbObjectId BTRId;
es = pBTIterator->getRecordId(BTRId);
if (!EOKM(es)) {
delete pBTIterator;
return false;
}
AcDbBlockTableRecordPointer pBlockTableRecord(BTRId, AcDb::kForRead);
EOK(pBlockTableRecord.openStatus());
if (// no anonymous blocks
pBlockTableRecord->isAnonymous() ||
// no xref's
pBlockTableRecord->isFromExternalReference() ||
// no overlaid xref's
pBlockTableRecord->isFromOverlayReference() ||
// no block layouts *MODEL_SPACE, *PAPER_SPACE...
pBlockTableRecord->isLayout()) {
continue;
}
AcDbBlockTableRecordIterator *pBTRIterator = NULL;
es = pBlockTableRecord->newIterator(pBTRIterator);
if (!EOKM(es))
continue;
const TCHAR *bName;
es = pBlockTableRecord->getName(bName);
if (!EOKM(es)) {
delete pBTIterator;
return false;
}
char text [33];
AcDbObjectIdArray ids;
if (pBlockTableRecord->getBlockReferenceIds(ids) == Acad::eOk) {
int cnt;
cnt = ids.length();
itoa(cnt,text,10);
}
if ((pTable->insertRows(pTable->numRows(),
pTable->rowHeight(1)) == Acad::eOk) &&
(pTable->generateLayout() == Acad::eOk)) {
pTable->setBlockTableRecordId(row,0,pBlockTableRecord->objectId(),true);
pTable->setAlignment(row,0,AcDb::kMiddleCenter);
pTable->setTextString(row,1,bName);
pTable->setAlignment(row,1,AcDb::kMiddleCenter);
pTable->setTextHeight(row,1,1.65);
pTable->setTextString(row,2,text);
pTable->setAlignment(row,2,AcDb::kMiddleCenter);
pTable->setTextHeight(row,2,1.65);
} else {
acutPrintf("\nIt is not a TABLE or it can not be opened: %s",
acadErrorStatusText(es));
}
row = (row + 1);
}
delete pBTIterator;
//if (pTable->generateLayout() == Acad::eOk) {
// acutPrintf("\nTable updated.");
AcDbObjectId curSpaceId=CURDB()->currentSpaceId();
AcDbBlockTableRecord *pBlkRec = NULL;
if (acdbOpenObject(pBlkRec, curSpaceId, AcDb::kForWrite) == Acad::eOk) {
pBlkRec->appendAcDbEntity(pTable);
pBlkRec->close();
pTable->close();
}
//}
}

Alexander Rivilis

  • Bull Frog
  • Posts: 212
  • Programmer from Kyiv (Ukraine)
Re: Inserts Table Generation ?
« Reply #19 on: April 22, 2006, 02:47:32 PM »
Ohhh, Luis!
Look this code:
Code: [Select]
  static void TableInsertTable(void)
  {
      AcDbTable *pTable = NULL;
      pTable = new AcDbTable();
      // 2 rows - title and headers
      pTable->insertRows(0,10.0);
      // 3 columns
      pTable->insertColumns(0,10.0,2);
      pTable->setTextString(0,0,"TITLE");
      // merge the first row for the title
      pTable->mergeCells(0,0,0,pTable->numColumns() - 1);
      // headers titles
      pTable->setTextString(1,0,"Preview");
      pTable->setTextString(1,1,"Name");
      pTable->setTextString(1,2,"Number");
      int row = 2;
      AcDbBlockTablePointer pBlockTable(acdbCurDwg(), AcDb::kForRead);
      if (pBlockTable.openStatus() != Acad::eOk) return;
      AcDbBlockTableIterator *pBTIterator = NULL;
      Acad::ErrorStatus es = pBlockTable->newIterator(pBTIterator, true, true);
      if (es != Acad::eOk || !pBTIterator) {
        acutPrintf("\npBlockTable->newIterator(pBTIterator, true, true)=%s",acadErrorStatusText(es));
        return;
      }
      for (; !pBTIterator->done(); pBTIterator->step()) {
        AcDbObjectId BTRId;
        es = pBTIterator->getRecordId(BTRId);
        if (es != Acad::eOk) {
          acutPrintf("\npBTIterator->getRecordId(BTRId)=%s",acadErrorStatusText(es));
          delete pBTIterator;
          return;
        }
        AcDbBlockTableRecordPointer pBlockTableRecord(BTRId, AcDb::kForRead);
        if (pBlockTableRecord.openStatus() != Acad::eOk) return;
        if (pBlockTableRecord->isAnonymous() || // no anonymous blocks
            pBlockTableRecord->isFromExternalReference() || // no xref's
            pBlockTableRecord->isFromOverlayReference() || // no overlaid xref's
            pBlockTableRecord->isLayout()) { // no block layouts *MODEL_SPACE, *PAPER_SPACE...
            continue;
          }
          const char *bName;
          es = pBlockTableRecord->getName(bName);
          if (es != Acad::eOk) {
            acutPrintf("\npBlockTableRecord->getName(bName)=%s",acadErrorStatusText(es));
            delete pBTIterator;
            return;
          }
          char text [256]="";;
          AcDbObjectIdArray ids;
          if (pBlockTableRecord->getBlockReferenceIds(ids) == Acad::eOk) {
            int cnt;
            cnt = ids.length();
            sprintf(text,"%d",cnt);
          }
          if ((pTable->insertRows(pTable->numRows(),pTable->rowHeight(1)) == Acad::eOk) &&
              (pTable->generateLayout() == Acad::eOk)) {
              pTable->setBlockTableRecordId(row,0,pBlockTableRecord->objectId(),true);
              pTable->setAlignment(row,0,AcDb::kMiddleCenter);
              pTable->setTextString(row,1,bName);
              pTable->setAlignment(row,1,AcDb::kMiddleCenter);
              pTable->setTextHeight(row,1,1.65);
              pTable->setTextString(row,2,text);
              pTable->setAlignment(row,2,AcDb::kMiddleCenter);
              pTable->setTextHeight(row,2,1.65);
            } else {
              acutPrintf("\nIt is not a TABLE or it can not be opened: %s",
                acadErrorStatusText(es));
            }
            row = (row + 1);
      }
      delete pBTIterator;
      //-----------------------------------------------------------
      // You *MUST* close BlockTable before open
      // any BlockTableRecord for Write
      //-----------------------------------------------------------
      pBlockTable->close();
      AcDbObjectId curSpaceId = acdbCurDwg()->currentSpaceId();
      AcDbBlockTableRecord *pBlkRec = NULL;
      if (acdbOpenObject(pBlkRec, curSpaceId, AcDb::kForWrite) == Acad::eOk) {
        pBlkRec->appendAcDbEntity(pTable);
        pBlkRec->close();
        pTable->close();
      }
    }

LE

  • Guest
Re: Inserts Table Generation ?
« Reply #20 on: April 22, 2006, 03:19:17 PM »
Thank you Alexander;

Yes it works!, I notice the lines where you made the changes, I will repass them, so in the future I will be able to write better code,  nice!

I was very close!

Just a minor notice, after running this new function into one command, if you call the command ERASE and by simple picking a point in any part of the screen, without touching the table, this one is selected, you know why?.... if I run the function I had before this does not happen.

Quote
ERASE
Select objects: 1 found

Again thanks.

LE

  • Guest
Re: Inserts Table Generation ?
« Reply #21 on: April 22, 2006, 04:51:16 PM »
Also, is there a chance to get the real number of inserts when using the function: getBlockReferenceIds() as it is being use is not providing the right number of AcDbBlockReferences known as inserts.

Thanks.

Alexander Rivilis

  • Bull Frog
  • Posts: 212
  • Programmer from Kyiv (Ukraine)
Re: Inserts Table Generation ?
« Reply #22 on: April 22, 2006, 05:51:15 PM »
IMHO It is look like AutoCAD bug. It is interesting that if you comment this code:
Code: [Select]
//  pTable->setBlockTableRecordId(row,0,blkId,true);
command ERASE nоt picked this table in other part of screen. Sometimes after REGENALL or MOVE this table - it is look ok, sometimes no... :(
Quote
Also, is there a chance to get the real number of inserts when using the function: getBlockReferenceIds() as it is being use is not providing the right number of AcDbBlockReferences known as inserts.
I have not any problem with getBlockReferenceIds(). If you have INSERT in other block and need to culculate it - try getBlockReferenceIds(ids, false);

LE

  • Guest
Re: Inserts Table Generation ?
« Reply #23 on: April 22, 2006, 06:11:20 PM »
[getBlockReferenceIds(ids, false);

Nope;

It is not giving the right number of blocks.... every time I ran the routine, it gives a different number....  :-(

LE

  • Guest
Re: Inserts Table Generation ?
« Reply #24 on: April 22, 2006, 11:43:47 PM »
Enough for today on this, to be continue

LE

Alexander Rivilis

  • Bull Frog
  • Posts: 212
  • Programmer from Kyiv (Ukraine)
Re: Inserts Table Generation ?
« Reply #25 on: April 23, 2006, 05:36:09 AM »
[getBlockReferenceIds(ids, false);

Nope;

It is not giving the right number of blocks.... every time I ran the routine, it gives a different number....  :-(

Code: [Select]
      AcDbObjectId  modelSpaceId, paperSpaceId;
      pBlockTable->getAt(ACDB_MODEL_SPACE, modelSpaceId);
      pBlockTable->getAt(ACDB_PAPER_SPACE, paperSpaceId);
      pBlockTable->close();

Code: [Select]
        char text [256]="";
        AcDbObjectIdArray ids;
        if (pBlockTableRecord->getBlockReferenceIds(ids) == Acad::eOk) {
          int cnt = 0;
          for (int i=0; i < ids.length(); i++) {
            AcDbObjectPointer<AcDbBlockReference> pRef(ids[i],kForRead);
            if (pRef.openStatus() == Acad::eOk &&
               (pRef->blockId() == modelSpaceId || pRef->blockId() == paperSpaceId)) {
              cnt++;                 
            }
          }
          sprintf(text,"%d",cnt);
        }

Other words - getBlockReferenceIds also calculate references to blocks in your's table. With this code we calculate only references in model and paper spaces.

LE

  • Guest
Re: Inserts Table Generation ?
« Reply #26 on: April 23, 2006, 11:22:52 AM »
Quote
Other words - getBlockReferenceIds also calculate references to blocks in your's table. With this code we calculate only references in model and paper spaces.

Thanks!

Is now providing the right number of inserts...  :-)

Alexander Rivilis

  • Bull Frog
  • Posts: 212
  • Programmer from Kyiv (Ukraine)
Re: Inserts Table Generation ?
« Reply #27 on: April 23, 2006, 12:59:11 PM »
Is now providing the right number of inserts...  :-)
Yes for my test dwg-file. Try with your's. :)
Another solution:
Code: [Select]
        char text [256]="";
        AcDbObjectIdArray ids;
        if (pBlockTableRecord->getBlockReferenceIds(ids) == Acad::eOk) {
          int cnt = 0;
          for (int i=0; i < ids.length(); i++) {
            AcDbObjectPointer<AcDbBlockReference> pRef(ids[i],AcDb::kForRead);
            if (pRef.openStatus() == Acad::eOk) {
              AcDbBlockTableRecordPointer pBtr(pRef->blockId(),AcDb::kForRead);
              if (pBtr.openStatus() == Acad::eOk && pBtr->isLayout()) {
                cnt++;                 
              }
            }
          }
          sprintf(text,"%d",cnt);
        }
« Last Edit: April 23, 2006, 01:19:07 PM by Rivilis »

LE

  • Guest
Re: Inserts Table Generation ?
« Reply #28 on: April 23, 2006, 03:31:16 PM »
Code: [Select]
        char text [256]="";
        AcDbObjectIdArray ids;
        if (pBlockTableRecord->getBlockReferenceIds(ids) == Acad::eOk) {
          int cnt = 0;
          for (int i=0; i < ids.length(); i++) {
            AcDbObjectPointer<AcDbBlockReference> pRef(ids[i],AcDb::kForRead);
            if (pRef.openStatus() == Acad::eOk) {
              AcDbBlockTableRecordPointer pBtr(pRef->blockId(),AcDb::kForRead);
              if (pBtr.openStatus() == Acad::eOk && pBtr->isLayout()) {
                cnt++;                 
              }
            }
          }
          sprintf(text,"%d",cnt);
        }

I like it.... I will use this instead...  Thanks!

A question.... I had on my code the same names for two variables [the ones in blue], is there any problems by doing that.... so far I am running the routine and it is working pretty good!

Quote
      AcDbObjectPointer<AcDbBlockReference> pRef(objId,AcDb::kForRead);
      if (pRef.openStatus() == Acad::eOk) {
         AcDbBlockTableRecordPointer pBtr(pRef->blockTableRecord(),AcDb::kForRead);
         if ((pBtr.openStatus () == Acad::eOk) &&
            // filter xref's and overlaid xref's
            (!pBtr->isFromExternalReference() ||
            !pBtr->isFromOverlayReference())) {
               const char *bName;
               es = pBtr->getName(bName);
               if (es != Acad::eOk) {
                  acutPrintf("\nBlock name error =%s",acadErrorStatusText(es));
                  return;
               }
               char text [256]="";
               AcDbObjectIdArray ids;
               if (pBtr->getBlockReferenceIds(ids) == Acad::eOk) {
                  int cnt = 0;
                  for (int i=0; i < ids.length(); i++) {            
                     AcDbObjectPointer<AcDbBlockReference> pRef(ids,AcDb::kForRead);
                     if (pRef.openStatus() == Acad::eOk) {
                        AcDbBlockTableRecordPointer pBtr(pRef->blockId(),AcDb::kForRead);
                        if (pBtr.openStatus() == Acad::eOk && pBtr->isLayout()) {
                           cnt++;
                        }
                     }
                  }
                  sprintf(text,"%d",cnt);
               }

Alexander Rivilis

  • Bull Frog
  • Posts: 212
  • Programmer from Kyiv (Ukraine)
Re: Inserts Table Generation ?
« Reply #29 on: April 23, 2006, 04:48:27 PM »
Quote
A question.... I had on my code the same names for two variables [the ones in blue], is there any problems by doing that.... so far I am running the routine and it is working pretty good!
No problem. :) These variables has different "area of visibility". It is described in any C++ handbook. Read it!