Author Topic: safearray for multiDimensional array data ..  (Read 6678 times)

0 Members and 1 Guest are viewing this topic.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
safearray for multiDimensional array data ..
« on: June 18, 2008, 06:46:52 PM »
In Mechanical2007
This is the VBA code to set the Data Property of PartData
Code: [Select]
  Set oObj = ThisDrawing.ModelSpace.AddCustomObject("AcmPartRef")
  Dim oPartRef As McadPartReference
' set part data   
   Dim partData(0 To 3, 0 To 1) As String   
     
   partData(0, 0) = "NAME"   
   partData(0, 1) = "My Part"   
   partData(1, 0) = "MATERIAL"   
   partData(1, 1) = "Aluminium"   
   partData(2, 0) = "NOTE"   
   partData(2, 1) = "This is test part"   
   partData(3, 0) = "VENDOR"   
   partData(3, 1) = "My Vendor"   

   ' set bom data   
   Dim oBOMMgr As McadBOMMgr       
   Set oBOMMgr = oSymBB.BOMMgr   
   Call oBOMMgr.SetPartData(oPartRef, partData)


Has anyone played with translating the same data used in a VBA multi-Array to a VLisp SafeArray [ so I can set the data from VLisp ]

ps:
sort of related to this ..
http://www.theswamp.org/index.php?topic=23601.msg285917;topicseen#msg285917
« Last Edit: June 18, 2008, 06:51:19 PM by Kerry Brown »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: safearray for multiDimensional array data ..
« Reply #1 on: June 18, 2008, 06:53:52 PM »
Would this help?  I did it when I was looking into excel files from Acad, but hadn't done anything with it in years.

Code: [Select]
    (defun MultiSafearray->List (MultiArray / RtnList)
        ; Turns a multi safearray variant into a list of lists.
       
        (foreach i (vlax-safearray->list (variant-value MultiArray))
            (setq RtnList
                (cons
                    (mapcar '(lambda (x) (vlax-variant-value x)) i)
                    RtnList
                )
            )
        )
        RtnList
    )
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: safearray for multiDimensional array data ..
« Reply #2 on: June 18, 2008, 07:21:58 PM »
Thanks Tim,
How are you defining the MultiArray parameter data

... as a list of lists ??
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: safearray for multiDimensional array data ..
« Reply #3 on: June 18, 2008, 07:28:58 PM »
I only gathered data, not set it.  I'm not sure how one would do it off the top of my head.  I just knew I had to come up with that code so that I could grab all the data I wanted from excel.  Let me think of a minute.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: safearray for multiDimensional array data ..
« Reply #4 on: June 18, 2008, 07:43:37 PM »
Would this help?  I got to go home now, but this came to mind.

Code: [Select]
(setq templist
    (list
        (list
            "test"
            "one"
        )
        (list
            "test"
            "two"
        )
        (list
            "test"
            "three"
        )
    )
)
(setq tempList2
    (mapcar
        '(lambda (x)
            (vlax-make-variant
                (vlax-safearray-fill
                    (vlax-make-safearray
                        vlax-vbString
                        (cons 0 (1- (length x)))
                    )
                    x
                )
            )
        )
        tempList
    )
)
(setq tempVariant
    (vlax-make-variant
        (vlax-safearray-fill
            (vlax-make-safearray
                vlax-vbVariant
                (cons 0 (1- (length tempList2)))
            )
            tempList2
        )
    )
)
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: safearray for multiDimensional array data ..
« Reply #5 on: June 18, 2008, 07:51:05 PM »

That looks like it should work Tim.

I'll test it this afternoon.

Thanks for the input !
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: safearray for multiDimensional array data ..
« Reply #6 on: June 18, 2008, 08:18:18 PM »
That code seems to work fine Tim, Thanks
Here's another option that seems to work ..
Code: [Select]
(defun listToVariantArray (lst varType)
  ;; Frank Oquendo acadx.dwg
  ;;
  (vlax-make-variant
    (vlax-safearray-fill
      (vlax-make-safearray varType (cons 0 (1- (length lst))))
      (mapcar '(lambda (x)
                 (cond ((= (type x) 'list)
                        (vlax-safearray-fill
                          (vlax-make-safearray
                            (if (apply '= (mapcar 'type x))
                              (cond ((= (type (car x)) 'REAL) vlax-vbdouble)
                                    ((= (type (car x)) 'INT) vlax-vbinteger)
                                    ((= (type (car x)) 'STR) vlax-vbstring)
                              )
                              vlax-vbvariant
                            )
                            (cons 0 (1- (length x)))
                          )
                          x
                        )
                       )
                       ((= (type x) 'ename)
                        (vla-get-objectid (vlax-ename->vla-object x))
                       )
                       (t x)
                 )
               )
              lst
      )
    )
  )
)

Code: [Select]
(defun lisp-value (v)
  ;; the Holy Grail of vla->lisp conversion? ;-)
  ;; Copyright 2002 Vladimir Nesterovsky.
  ;; Free for use by any commercial entity with
  ;; less then $100 million annual revenue.
  (cond ((= (type v) 'variant) (lisp-value (variant-value v)))
        ((= (type v) 'safearray) (mapcar 'lisp-value (safearray-value v)))
        (t v)
  )
)

Code: [Select]
(setq templist
    (list
        (list
            "testone"
            "one"
        )
        (list
            "testtwo"
            "two"
        )
        (list
            "testthree"
            "three"
        )
    )
)

Run Tim's code then :
(lisp-value tempVariant) ;->>
(("testone" "one") ("testtwo" "two") ("testthree" "three"))

(setq test2 (listToVariantArray templist vlax-vbVariant )) ;->>
#<variant 8204 ...>

(lisp-value test2) ;->>
(("testone" "one") ("testtwo" "two") ("testthree" "three"))


;;--------
I'll try to feed it to the ActiveX beast later today. :-)



kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: safearray for multiDimensional array data ..
« Reply #7 on: June 18, 2008, 11:15:03 PM »
Ooooops
Quote
Application Error: 0 :- Automation Error. Description was not provided.


I've passed it on to the ADN to see if anyone there can make sense of it


Code: [Select]

(defun c:test20080619b ()                                   ; leave vars global for now
  ;;--------------------------------
  ;; for AM2007
  ;; add a Part Ref Marker and Data (attempt)
  ;; by Kerry Brown 20080619 
  ;;--------------------------------
  ;; Get the Interface Object
  (setq symBB (vla-getinterfaceobject (vlax-get-acad-object)
                                      "SymBBAuto.McadSymbolBBMgr"
              )
  )
  ;;
  ;; Get BOM manager
  (setq BOM-manager (vlax-get-property symBB 'BOMMgr))
  ;;
  ;; Get standard manager       
  (setq STD-manager (vlax-get-property symBB 'StandardMgr))
  ;;
  ;; Get the current standard 
  (setq current-standard (vlax-get-property STD-manager 'CurrentStandard))
  ;;
  ;; Get BOM Standard
  (setq BOM-Standard (vlax-get-property current-standard 'BOMStandard))
  ;;
  ;; Get all BOM visible columns from BOM standard
  (setq BOM-Columns (vlax-get-property BOM-Standard 'Columns))
  ;;
  ;; Create part reference
  (setq g:PartRef (vlax-invoke-method kglobal:modelspace
                                      'AddCustomObject
                                      "AcmPartRef"
                  )
  )
  (setq acmApp (vla-getinterfaceobject (vlax-get-acad-object)
                                       "AcadmAuto.AcadmApplication"
               )
  )
  ;;
  ;; Select point to attach Partref
  (setq workPoint (getpoint "Marker Working point")
        oWpoint   (vlax-3d-point (trans workPoint acucs acworld))
  )
  ;; #<variant 8197 ...>
  ;; Attach partref to the location point
  (vlax-put-property g:PartRef 'Origin oWpoint)
  (vlax-put-property g:PartRef 'Scale (getvar "DIMSCALE"))
  ;; assign the Data
  (setq PARTREF-stringlist (list (list "BOM_UNITS" "ea")
                                 (list "DESCR" "150 UB 14")
                                 (list "STANDARD" "1000")
                                 (list "MATERIAL" "300PLUS")
                                 (list "MASS" "14.0")
                           )
        PARTREF-Count      22
        PARTREF-datalist   (listToVariantArray PARTREF-stringlist vlax-vbvariant)
  )
  ;;
  ;; Crashes here
  ;; Application Error: 0 :- Automation Error. Description was not provided.
  (vlax-put-property g:PartRef 'Data PARTREF-datalist)
  ;;
  ;; Release the Objects
  (if (and acmApp (null (vlax-object-released-p acmApp)))
    (progn (vlax-release-object acmApp) (setq acmApp nil))
  )
  (if (and symBB (null (vlax-object-released-p symBB)))
    (progn (vlax-release-object symBB) (setq symBB nil))
  )
  (princ)
)

;;--------------------------------
;;--------------------------------
;;
;;
;;=====================================================
(defun lisp-value (v)
  ;; the Holy Grail of vla->lisp conversion? ;-)
  ;; Copyright 2002 Vladimir Nesterovsky.
  ;; Free for use by any commercial entity with
  ;; less then $100 million annual revenue.
  (cond ((= (type v) 'variant) (lisp-value (variant-value v)))
        ((= (type v) 'safearray) (mapcar 'lisp-value (safearray-value v)))
        (t v)
  )
)
;;
;;=====================================================
(defun listToVariantArray (lst varType)
  ;; Frank Oquendo acadx.dwg
  ;;
  (vlax-make-variant
    (vlax-safearray-fill
      (vlax-make-safearray varType (cons 0 (1- (length lst))))
      (mapcar '(lambda (x)
                 (cond ((= (type x) 'list)
                        (vlax-safearray-fill
                          (vlax-make-safearray
                            (if (apply '= (mapcar 'type x))
                              (cond ((= (type (car x)) 'REAL) vlax-vbdouble)
                                    ((= (type (car x)) 'INT) vlax-vbinteger)
                                    ((= (type (car x)) 'STR) vlax-vbstring)
                              )
                              vlax-vbvariant
                            )
                            (cons 0 (1- (length x)))
                          )
                          x
                        )
                       )
                       ((= (type x) 'ename)
                        (vla-get-objectid (vlax-ename->vla-object x))
                       )
                       (t x)
                 )
               )
              lst
      )
    )
  )
)
(princ)
;;
;;=====================================================


I'll go and find something a little more prodictive to do :-)
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: safearray for multiDimensional array data ..
« Reply #8 on: June 19, 2008, 11:07:35 AM »
I hope you find the answer.  I have never needed any code like this, so I'm not even sure how to test ideas.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Jeff_M

  • King Gator
  • Posts: 4099
  • C3D user & customizer
Re: safearray for multiDimensional array data ..
« Reply #9 on: June 19, 2008, 03:57:59 PM »
Hi Kerry,
Don't have Mech here to test with you, but I do see one place that may be tripping it up. In the VBA code you have the array Dim'ed as a String, but in the lisp you are creating a Variant here:
Code: [Select]
       PARTREF-datalist   (listToVariantArray PARTREF-stringlist vlax-vbvariant)
changing that to be:
Code: [Select]
       PARTREF-datalist   (listToVariantArray PARTREF-stringlist vlax-vbstring)
may do it.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: safearray for multiDimensional array data ..
« Reply #10 on: June 19, 2008, 04:03:32 PM »

Thanks Jeff,
I'm running out the door to catch my train, so I'll check that when I get to work.

kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: safearray for multiDimensional array data ..
« Reply #11 on: June 19, 2008, 07:49:28 PM »
Won't accept it Jeff ..
I have the interals as strings and the array as a variant.
It's a long time since I've played with this stuff ..  :oops:
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Jeff_M

  • King Gator
  • Posts: 4099
  • C3D user & customizer
Re: safearray for multiDimensional array data ..
« Reply #12 on: June 20, 2008, 02:37:37 AM »
Can you post, or check, what a (vlax-get-property g:partref 'Data) returns (on a part that already has the data set)? It usually helps me to work backwards... 'put' will accept what 'get' returns.

Yeah, it's been quite a while since I've looked at this stuff, too.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: safearray for multiDimensional array data ..
« Reply #13 on: June 20, 2008, 08:36:15 AM »

I don't have mech' at home .. I'd planned on downloading tomorrow and installing here and having a play.
... that's what Saturdays are for :-)
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: safearray for multiDimensional array data ..
« Reply #14 on: June 21, 2008, 08:43:28 PM »
No Joy ..
Code: [Select]
(setq PARTREF
       (kdub:objsel
"Select Material Marker entity"
(list "ACMPARTREF")
nil
       )
)
;;->
;; (<Entity name: 7efcab98> (1042.34 -478.152 0.0))


(setq PARTREF-Object (vlax-ename->vla-object (car PARTREF)))
;;->
;; #<VLA-OBJECT IMcadPartReference 091ce12c>


(setq Data (vlax-get-property PARTREF-Object 'Data))
;; ->
;; #<variant 8200 ...>



(vlax-dump-Object PARTREF-Object T)

kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: safearray for multiDimensional array data ..
« Reply #15 on: June 25, 2008, 04:26:12 AM »

just an update ..
I have recieved information from the  Autodesk Developer Network regarding a solution to this.
After I've done some testing I'll post what I can.
 
 
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.