Author Topic: Add row in a Table - Question  (Read 9469 times)

0 Members and 1 Guest are viewing this topic.

LE

  • Guest
Add row in a Table - Question
« on: March 16, 2006, 09:30:10 PM »
What method, should I need to use in order to have the new row added, in real time ?

When I run the below code, it does work but I need to select [grip], the table in order to have the Table updated.

Thanks!

Code: [Select]
static void LESQsomefunctions_ADDROW(void)
{
ads_name ename;
ads_point ptres;
if ( acedEntSel( "\nSelect TABLE:", ename, ptres ) == RTNORM ) {
AcDbTable *pTable = NULL;
AcDbObjectId entId;
acdbGetObjectId( entId, ename );
acdbTransactionManager->startTransaction();
if ( acdbTransactionManager->getObject(
( AcDbObject*& )pTable, entId, AcDb::kForRead) == Acad::eOk) {
if ( pTable->isKindOf( AcDbTable::desc() ) ) {
pTable->upgradeOpen();
if (( pTable->insertRows( pTable->numRows(),
pTable->rowHeight( 1 ) ) == Acad::eOk ) &&
( pTable->generateLayout() == Acad::eOk )) {
acutPrintf( "\nAdded one row and table updated." );
} else {
acutPrintf( "\nTable not updated." );
}
}// end of is AcDbTable
}// end of getObject
acdbTransactionManager->endTransaction();
}// end of acedEntSel
}//end of command ADDROWS

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Add row in a Table - Question
« Reply #1 on: March 16, 2006, 09:35:41 PM »
Do you need to Commit   the transaction in CPP ?
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: Add row in a Table - Question
« Reply #2 on: March 16, 2006, 09:46:29 PM »
Do you need to Commit   the transaction in CPP ?

That is not available as function on ARX, I know what that function does in .NET, now what happens is that it is needed to wait for the transactionEnded() signal and after that, do the modifications... hmm...

It is contradictory, since when it is used the transaction manager, the good about it is to not care of closing objects.... unless [and it is possible] I am wrong...

I will change my code to use smart pointers... and see what happens.

Thanks.

MickD

  • Gator
  • Posts: 3300
  • (x-in)->[process]->(y-out)
Re: Add row in a Table - Question
« Reply #3 on: March 16, 2006, 09:51:15 PM »
it seems .net commit wraps the ::endTransaction() method.

from the doc's
Quote
virtual Acad::ErrorStatus

endTransaction() = 0;

Ends the top transaction, committing all changes to objects obtained within that transaction. Also clears the undo marker associated with the transaction out of the undo file for all transaction-resident objects (this means resident in any transaction).


Luis, does it work with a regen in the editor??
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: “To attain knowledge, add things
every day; to obtain wisdom, remove things every day.”

LE

  • Guest
Re: Add row in a Table - Question
« Reply #4 on: March 16, 2006, 09:58:15 PM »
it seems .net commit wraps the ::endTransaction() method.

from the doc's
Quote
virtual Acad::ErrorStatus

endTransaction() = 0;

Ends the top transaction, committing all changes to objects obtained within that transaction. Also clears the undo marker associated with the transaction out of the undo file for all transaction-resident objects (this means resident in any transaction).


Luis, does it work with a regen in the editor??

It is the same part of the help that I just read, my friend.... editor [drawing session?]... no it does not do it magically..... as Kerry mentioned...

Grrrrr......

LE

  • Guest
Re: Add row in a Table - Question
« Reply #5 on: March 16, 2006, 10:03:54 PM »
Got it... here is the code that works, using smart pointers!

Code: [Select]
static void LESQsomefunctions_ADDROW(void)
{
ads_name ename;
ads_point ptres;
Acad::ErrorStatus es;
if ( acedEntSel( "\nSelect TABLE:", ename, ptres ) == RTNORM ) {
AcDbObjectId objId;
acdbGetObjectId( objId, ename );
AcDbObjectPointer<AcDbTable> pTable( objId, AcDb::kForWrite );
if ( ( es = pTable.openStatus() ) == Acad::eOk ) {
if (( pTable->insertRows( pTable->numRows(),
pTable->rowHeight( 1 ) ) == Acad::eOk) &&
( pTable->generateLayout() == Acad::eOk )) {
acutPrintf( "\nAdded one row and table updated." );
}
} else {
acutPrintf("\nIt is not a TABLE or it can not be opened: %s",
acadErrorStatusText( es ) );
}
}
}//end of command ADDROW

MickD

  • Gator
  • Posts: 3300
  • (x-in)->[process]->(y-out)
Re: Add row in a Table - Question
« Reply #6 on: March 16, 2006, 10:17:52 PM »
hmm, loose memory, no good 'ay.


.... editor [drawing session?]


sort of, the editor as I referred to it is just that, the place where the user edits the currently active document and is an object in its own right (a Windows UI object).
The only time you should use the editor is for user interaction/input otherwise everything else can be done directly on the database object. That's why it's not good practice to use sendCommand etc. as you're playing with an interface to a different object (Windows) and could cause unnecessary overhead and troubles ;)
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: “To attain knowledge, add things
every day; to obtain wisdom, remove things every day.”

LE

  • Guest
Re: Add row in a Table - Question
« Reply #7 on: March 16, 2006, 10:25:20 PM »
Thanks Mick;

On my previous code using the transaction manager, it is not possible, it has to be done following the normal way of opening an object, do the changes and later closing them, Or go the smart pointer route...

I can see the magic Kerry was referring....  :-)

Alexander Rivilis

  • Bull Frog
  • Posts: 212
  • Programmer from Kyiv (Ukraine)
Re: Add row in a Table - Question
« Reply #8 on: March 17, 2006, 04:45:59 AM »
Thanks Mick;

On my previous code using the transaction manager, it is not possible, it has to be done following the normal way of opening an object, do the changes and later closing them, Or go the smart pointer route...

I can see the magic Kerry was referring....  :-)
You was not right. You Can use transaction manager. Look at this code and compare with yours code:
Code: [Select]
  static void TableAddRow(void)
  {
    ads_name ename;
    ads_point ptres;
    if ( acedEntSel( "\nSelect TABLE: ", ename, ptres ) == RTNORM ) {
      AcDbObject *pObj = NULL;
      AcDbObjectId entId;
      acdbGetObjectId( entId, ename );
      acdbTransactionManager->startTransaction();
      if (acdbTransactionManager->getObject(pObj, entId, AcDb::kForWrite) == Acad::eOk) {
        AcDbTable *pTable = AcDbTable::cast(pObj);
        if (pTable &&
            pTable->insertRows(pTable->numRows(),pTable->rowHeight(1)) == Acad::eOk &&
            pTable->generateLayout() == Acad::eOk) {
          acutPrintf( "\nAdded one row and table updated." );
        } else {
          acutPrintf( "\nTable not updated." );
        }
      }
      acdbTransactionManager->endTransaction();
    }
  }
In other words You can not use acdbTransactionManager->getObject(...,AcDb::kForRead) and after then use upgradeOpen(). upgradeOpen() is valid only with objects not in transaction.
« Last Edit: March 17, 2006, 05:01:01 AM by Rivilis »

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Add row in a Table - Question
« Reply #9 on: March 17, 2006, 04:59:09 AM »
Hello Alexander, thanks for posting.

Do you compile that as managed code only ?
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<--

Alexander Rivilis

  • Bull Frog
  • Posts: 212
  • Programmer from Kyiv (Ukraine)
Re: Add row in a Table - Question
« Reply #10 on: March 17, 2006, 05:04:12 AM »
Hello Alexander, thanks for posting.

Do you compile that as managed code only ?


No! I've compiled that code as native and tested it in AutoCAD 2006 SP1.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Add row in a Table - Question
« Reply #11 on: March 17, 2006, 05:10:02 AM »
Thanks, I'm not a CPP'er really, but I had a suspicion that transaction were used with native as well as managed.

I Hope you enjoy your time here :-)
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<--

Alexander Rivilis

  • Bull Frog
  • Posts: 212
  • Programmer from Kyiv (Ukraine)
Re: Add row in a Table - Question
« Reply #12 on: March 17, 2006, 05:17:53 AM »
I'm CPP'er and Lisp'er.  And in 99.9% I'm using only native code in C++. For managed code I prefer C#. But in C# I'm beginner.

Glenn R

  • Water Moccasin
  • Posts: 1932
  • What idiot child of married cousins wrote this?!
Re: Add row in a Table - Question
« Reply #13 on: March 17, 2006, 06:46:45 AM »
Rivilis is quite correct Luis. You can use transactions in the code you posted. However, is it better than using smart pointer objects and checking all return codes...open for debate.
Smart pointers let you take some syntactical shortcuts in my opinion, however, transactions are Adesk's *preferred* method is transactions and have their own benefits.

The only thing I would change in Rivilis's code is to add the explicit use of abortTransaction() in the 'else' clause of the 'if' statement.

Now that I think about it, that 'if' statement is a bit unclear, so I would re-write myself. A general rule I adopted in C++ is to bail out immediately if a condition is not met...and my 'if' statements/switch etc. statement would reflect this.

Example:

if (!Whatever)
  return;

// Continue processing here.

instead of:

if (Whatever) {
  // Dome some lengthy and very much indented code here.
}

Just some bourbon ramblings.

Cheers,
Glenn.

P.S. I *miss* my C++.... < sigh >
Me

Alexander Rivilis

  • Bull Frog
  • Posts: 212
  • Programmer from Kyiv (Ukraine)
Re: Add row in a Table - Question
« Reply #14 on: March 17, 2006, 06:53:34 AM »
...
The only thing I would change in Rivilis's code is to add the explicit use of abortTransaction() in the 'else' clause of the 'if' statement.
...
I also agree with you! :)
Another style of code:
Code: [Select]
class Trans
{
public:
   Trans()  { tr = acTransactionManagerPtr()->startTransaction(); }
  ~Trans()  {
    if (tr == acTransactionManagerPtr()->topTransaction()) {
      acTransactionManagerPtr()->endTransaction();
    }
  }
  AcTransactionManager *operator->() {return acTransactionManagerPtr();};
private: 
  AcTransaction *tr;
};

class TransExpt {}; 

static void TableAddRow(void)
{
  ads_name ename;
  ads_point ptres;
  if ( acedEntSel( "\nSelect TABLE: ", ename, ptres ) == RTNORM ) {
    AcDbObject *pObj = NULL;
    AcDbObjectId entId;
    acdbGetObjectId( entId, ename );
    Trans tr;
    try {
      if (tr->getObject(pObj, entId, AcDb::kForWrite) != Acad::eOk)
        throw TransExpt();
      AcDbTable *pTable = AcDbTable::cast(pObj);
      if (!pTable)  throw TransExpt();
      if (pTable->insertRows(pTable->numRows(),pTable->rowHeight(1)) != Acad::eOk)
        throw TransExpt();
      if (pTable->generateLayout() != Acad::eOk)
        throw TransExpt();
      tr->flushGraphics();
      acutPrintf( "\nAdded one row and table updated." );
    }
    catch (TransExpt) {
      acutPrintf( "\nTable not updated." );
      tr->abortTransaction();
    }
  }
}
« Last Edit: March 17, 2006, 08:43:58 AM by Rivilis »