Author Topic: Headaches with SetBlockTableRecordID Method  (Read 9163 times)

0 Members and 1 Guest are viewing this topic.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Headaches with SetBlockTableRecordID Method
« on: March 02, 2011, 04:27:17 PM »
This is related to my Block Counter program as posted in this thread, which errors when run on 64-bit systems.

The error occurs when attempting to add the Block Thumbnail to the table cells, i.e. the SetBlockTableRecordID Method.

I don't have a 64-bit system on which to test the code, and the program doesn't error when run on a 32-bit system, so its been a bit of trial-and-error when trying to fix the code.

I have tried changing the way the method is implemented, changing the format of the parameters, removing some parameters - but nothing seems to work and the format described in the documentation for this method doesn't seem to result in a working solution.

Hence I have constructed the following code:

Code: [Select]
(defun c:test ( / _GetObjectID _GetBlockName acdoc acspc acblk block blockid pt table ) (vl-load-com)

  (setq acdoc (vla-get-ActiveDocument (vlax-get-acad-object))
        acspc (vlax-get-property acdoc (if (= 1 (getvar 'CVPORT)) 'Paperspace 'Modelspace))
        acblk (vla-get-blocks acdoc)
  )

  (defun _GetObjectID ( doc obj )
    (if (vl-string-search "64" (strcase (getenv "PROCESSOR_ARCHITECTURE")))
      (vlax-invoke-method (vla-get-Utility doc) 'GetObjectIdString obj :vlax-false)
      (itoa (vla-get-Objectid obj))
    )
  )

  (defun _GetBlockName ( obj )
    (if (vlax-property-available-p obj 'effectivename)
      (vla-get-effectivename obj)
      (vla-get-name obj)
    )
  )

  (if
    (and
      (setq block (car (entsel "\nSelect Block: ")))
      (eq "INSERT" (cdr (assoc 0 (entget block))))
      (setq pt (getpoint "\nPick Point for Table: "))
    )
    (progn
      (setq table   (vla-AddTable acspc (vlax-3D-point (trans pt 1 0)) 2 2 1.0 5.0)
            blockid (atoi (_GetObjectID acdoc (vla-item acblk (_GetBlockName (vlax-ename->vla-object block)))))
            i 0
      )
      (princ (strcat "\n\nRunning Version: " (itoa (atoi (substr (ver) 13))) "  " (getenv "PROCESSOR_ARCHITECTURE")))

      (if
        (not
          (vl-some
            (function
              (lambda ( expr / err ) (setq err (vl-catch-all-apply 'eval (list expr)))
                (princ
                  (strcat "\n--> Method " (itoa (setq i (1+ i))) ": "
                    (if (vl-catch-all-error-p err)
                      (strcat "Failed\n    Reason: " (vl-catch-all-error-message err))
                      "Succeeded"
                    )
                  )
                )
                (not (vl-catch-all-error-p err))
              )
            )
           '(
              (vla-SetBlockTableRecordID   table 1 0 blockid :vlax-true)
              (vla-SetBlockTableRecordID2  table 1 0 acblockcell blockid :vlax-true)
              (vla-SetBlockTableRecordID32 table 1 0 acblockcell blockid :vlax-true)
              (vla-SetBlockTableRecordID32 table 1 0 blockid :vlax-true)
              (vla-SetBlockTableRecordID32 table 1 0 acblockcell blockid)
              (vlax-invoke table 'SetBlockTableRecordID   table 1 0 blockid :vlax-true)
              (vlax-invoke table 'SetBlockTableRecordID2  table 1 0 acblockcell blockid :vlax-true)
              (vlax-invoke table 'SetBlockTableRecordID32 table 1 0 acblockcell blockid :vlax-true)
              (vlax-invoke table 'SetBlockTableRecordID32 table 1 0 blockid :vlax-true)
              (vlax-invoke table 'SetBlockTableRecordID32 table 1 0 acblockcell blockid)
            )
          )
        )
        (princ "\n--> All Methods have Failed.")
      )
    )
  )

  (princ)
)

[ Code updated to improve GetObjectID function ]

The above code prompts for a selection of a block, then a point to place a table. A 2x2 table is then created at the point.

The code then attempts to add a block thumbnail to the cell 0,1 using various methods - stopping when a successful method is found.

I would ask as many of you as possible to test the above code, and please post the return printed to the command line (containing the system details and method report).

If anyone has any suggestions for how to implement this method, or see any mistakes in my code or the code in the linked program, I would sincerely appreciate any input you have to offer.

Thank you all for your time reading this.

Kind Regards,

Lee
« Last Edit: March 02, 2011, 05:05:56 PM by Lee Mac »

trogg

  • Bull Frog
  • Posts: 255
Re: Headaches with SetBlockTableRecordID Method
« Reply #1 on: March 02, 2011, 05:01:17 PM »

Code: [Select]
Command: test

Select Block:
Pick Point for Table:

Running Version: 2011  AMD64
--> Method 1: Failed
    Reason: Automation Error. Null object ID
--> Method 2: Failed
    Reason: Automation Error. Null object ID
--> Method 3: Failed
    Reason: Too many actual parameters; error: Exception occurred: 0xC0000005
(Access Violation)
; warning: unwind skipped on unknown exception

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Headaches with SetBlockTableRecordID Method
« Reply #2 on: March 02, 2011, 05:04:21 PM »
Aha!

My method for detecting 64-bit is flawed!  :oops:

Thanks Greg!

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Headaches with SetBlockTableRecordID Method
« Reply #3 on: March 02, 2011, 05:06:13 PM »
Would you mind testing the updated code above please?  :-)

Jeff_M

  • King Gator
  • Posts: 4096
  • C3D user & customizer
Re: Headaches with SetBlockTableRecordID Method
« Reply #4 on: March 02, 2011, 05:44:34 PM »
Lee, it's not how you check for 64-bit systems. It's how you are converting from a string to the ObjectId. With a few small changes this works in both 2010-32 and 2011-64.

First, your _GetObjectID function. This works fine when you NEED a string, such as using in a Mtext Field. But once you try to convert the string to an Integer it fails, because the 64 bit systems want a Long, not an int. If you walk through the code, you will see that the ObjectId gets changed to another number. Instead, just get the Objectid or Objectid32:


  (defun _GetObjectID ( obj )
    (if (_Is64Bit)
      (vla-get-Objectid32 obj)
      (vla-get-Objectid obj)
    )
  )

Then, in your cell creation code remove the (atoi .....) and just use:

row 0 (_GetObjectID (_itemp blocks block)) :vlax-true

As I said, this works in both 2010-32 & 2011-64

HTH

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Headaches with SetBlockTableRecordID Method
« Reply #5 on: March 02, 2011, 06:10:22 PM »
Jeff,

Your help is greatly appreciated.

The method I used for retrieving the ObjectID on 64-bit systems was the only method I had seen used, and I have mostly used it for Field Strings, as you point out - so I hadn't seen its consequences for this situation until now.

I didn't know of the ObjectID32 property, many thanks for pointing me in that direction.

Your testing in both environments is very encouraging - I'm so glad that it was a mistake on my part and not a bug in the method. Relief.

Once again, many thanks for your time in looking into this for me, much appreciated.

Lee

Jeff_M

  • King Gator
  • Posts: 4096
  • C3D user & customizer
Re: Headaches with SetBlockTableRecordID Method
« Reply #6 on: March 02, 2011, 06:16:35 PM »
I'm glad I was finally able to be able to jump in and lend a hand. I read through all these posts, and usually by the time I get to the point of thinking I may have something to add someone else has already made the observation, or the OP has figured out the problem.

I had some hope with this one though, since it looked like you've been struggling with it for a while :-)

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Headaches with SetBlockTableRecordID Method
« Reply #7 on: March 02, 2011, 06:24:29 PM »
I'm glad I was finally able to be able to jump in and lend a hand. I read through all these posts, and usually by the time I get to the point of thinking I may have something to add someone else has already made the observation, or the OP has figured out the problem.

You should jump in a lot more, I'm sure you have a lot to add  :-)

since it looked like you've been struggling with it for a while :-)

Definitely... the major headache was not having the 64-bit system on which the test the code. But I've learnt a lot from this thread, so thanks for your participation.

trogg

  • Bull Frog
  • Posts: 255
Re: Headaches with SetBlockTableRecordID Method
« Reply #8 on: March 02, 2011, 07:16:26 PM »
Lee,
You fixed it!!!
great job!!!

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Headaches with SetBlockTableRecordID Method
« Reply #9 on: March 02, 2011, 07:18:40 PM »
Fantastic news Greg!

Thanks for your patience  8-)

Enjoy!

Lee

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: Headaches with SetBlockTableRecordID Method
« Reply #10 on: March 03, 2011, 08:43:47 AM »
Interesting stuff guys. Out of curiosity, wouldn't something like one of these be sufficient?

Code: [Select]
(defun objectID (o / i)
  (if
    (vl-some
      (function
        (lambda (p)
          (not (vl-catch-all-error-p (setq i (vl-catch-all-apply (function vlax-get) (list o p)))))
        )
      )
      '(objectID objectID32)
    )
     i
  )
)


(defun objectID (o)
  (vl-some
    (function
      (lambda (p / i)
        (if
          (not (vl-catch-all-error-p (setq i (vl-catch-all-apply (function vlax-get) (list o p)))))
           i
        )
      )
    )
    '(objectID objectID32)
  )
)
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Headaches with SetBlockTableRecordID Method
« Reply #11 on: March 03, 2011, 02:50:13 PM »
Interesting stuff guys. Out of curiosity, wouldn't something like one of these be sufficient?

I suppose, but some errors can't be caught by the vl-catch-all-apply function (as shown in Trogg's command line printout), so for the sake of testing whether the system is 64-bit I'd rather not take that chance.

I tend to only use vl-catch-all-apply when I really have to.

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: Headaches with SetBlockTableRecordID Method
« Reply #12 on: March 03, 2011, 02:52:06 PM »
Interesting stuff guys. Out of curiosity, wouldn't something like one of these be sufficient?

I suppose, but some errors can't be caught by the vl-catch-all-apply function (as shown in Trogg's command line printout), so for the sake of testing whether the system is 64-bit I'd rather not take that chance.

I tend to only use vl-catch-all-apply when I really have to.
Agreed, but if it avoids the need to fuss with checking the architecture, then I'd say it's worth the vl-catch. I'd love to know if it actually works on a 64-bit machine.
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Headaches with SetBlockTableRecordID Method
« Reply #13 on: March 03, 2011, 02:58:27 PM »
Agreed, but if it avoids the need to fuss with checking the architecture

That's only a quick vl-string-search of an environmental variable

Code: [Select]
(vl-string-search "64" (getenv "PROCESSOR_ARCHITECTURE"))
I'd use this method:

Code: [Select]
(vlax-get-property obj (if (vl-string-search "64" (getenv "PROCESSOR_ARCHITECTURE")) 'ObjectID32 'ObjectID))
« Last Edit: March 03, 2011, 03:01:48 PM by Lee Mac »

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: Headaches with SetBlockTableRecordID Method
« Reply #14 on: March 03, 2011, 03:05:01 PM »
Agreed, but if it avoids the need to fuss with checking the architecture

That's only a quick vl-string-search of an environmental variable

Code: [Select]
(vl-string-search "64" (getenv "PROCESSOR_ARCHITECTURE"))
I'd use this method:

Code: [Select]
(vlax-get-property obj (if (vl-string-search "64" (getenv "PROCESSOR_ARCHITECTURE")) 'ObjectID32 'ObjectID))
Point taken. Mind changed.
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox