找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 877|回复: 11

[教学] VLISP中级教学(一)Visual LISP中的数组

[复制链接]

已领礼包: 20个

财富等级: 恭喜发财

发表于 2017-5-16 09:32:56 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 marting 于 2017-5-16 09:50 编辑

Arrays with Visual LISP

by Kenny Ramage
If you've programmed in VBA or other languages, you're probably familiar with the concept of arrays. An array is a named collection of variables of the same data type. Each array element can be distinguished from other elements by one or more integer indexes. For example, if the "sheetNames" array contains three names, you can set and return the names in VBA as shown in the following example :
sheetNames(0) = "Sheet1"
sheetNames(1) = "Sheet2"
sheetNames(2) = "Sheet3"
MsgBox sheetNames(1)
Would return a message :
"Sheet2"
Arrays allow you to group related variables in a way that makes it easier for you to keep track of, access, and manipulate them all at once, while still being able to access each variable individually. This helps you create smaller and simpler routines in many situations, because you can set up loops using index numbers to deal efficiently with any number of cases.
When you create an array, its size is determined by the number of dimensions it has and the by the upper and lower bounds for the index numbers in each dimension. The "sheetNames" array in the earlier example has one dimension and three elements; the lower bound is 0 and the upper bound is 2.
"That's fine Kenny, but how do we create an Array in Visual Lisp?"
OK I hear you, there's no need to yell!
Enter this at the Console prompt :
_$ (vl-load-com)_$ (setq sheet_type (vlax-make-safearray vlax-vbString '(0 . 2)))#<safearray...>
_$ (vlax-safearray-fill sheet_type '("Sheet1" "Sheet2" "Sheet3"))#<safearray...>

Have a look at the "sheet_ type" variable in the Watch window :

0.jpg

This tells us that the Array contains strings, has one dimension and contains 3 elements. Let's convert it to an AutoLisp List :
_$ (setq alist (vlax-safearray->list sheet_type))("Sheet1" "Sheet2" "Sheet3")

Did a light just go off in your head? An Array is just a List in a slightly different format. To create an Array, or safearray as they are know in Visual Lisp, we use the "vlax-make-safearray" function. To populate a safearray we use the "vlax-safearray-fill" or the "vlax-safearray-put" functions.
The "vlax-make-safearray" function requires a minimum of two arguments. The first argument identifies the type of data that will be stored in the array.

One of the following constants must be specified for the data type :

ConstantDescription
vlax-vbInteger
Integer
vlax-vbLong
Long Integer
vlax-vbSingle
Single-precision floating point number
vlax-vbDouble
Double-precision floating point number
vlax-vbString
String
vlax-vbObject
Object
vlax-vbBoolean
Boolean
vlax-vbVariant
Variant

The remaining arguments to "vlax-make-safearray" specify the upper and lower bounds of each dimension of the array. The lower bound for an index can be zero or any positive or negative number. Have another look at the function we called earlier :
_$ (setq sheet_type (vlax-make-safearray vlax-vbString '(0 . 2)))

This function created a single-dimension array consisting of three strings with a starting index of 0 (element 0, element 1 and element 2).
Consider this :
_$ (setq pt1 (vlax-make-safearray vlax-vbDouble '(1 . 3)))

The lower bound specified in this example is one and the upper bound specified is three, so the array will hold three doubles (element 1, element 2 and element 3).
The "vla-safearray-fill" function requires two arguments: the variable containing the array you are populating and a list of the values to be assigned to the array elements. You must specify as many values as there are elements in the array or vla-safearray-fill" results in an error.
The following code populates a single-dimension array of three doubles :
_$ (vlax-safearray-fill pt1 '(100 100 0))
To convert an array to an AutoLisp list, you can use the (vlax-safearray->list) function. Try it out :
_$ (vlax-safearray->list pt1)(100.0 100.0 0.0)
Let's create a Array with two dimensions, each dimension with three elements :
_$ (setq two_dim (vlax-make-safearray vlax-vbString '(0 . 1) '(1 . 3)))#<safearray...>
_$ (vlax-safearray-fill two_dim '(("Sheet1" "Sheet2" "Sheet3") ("a" "b" "c")))#<safearray...>
_$ (vlax-safearray->list two_dim)(("Sheet1" "Sheet2" "Sheet3") ("a" "b" "c"))

This is just a list of lists.
The first list, '(0 .1) is the number of dimensions.
The second list, '(1 . 3) is the number of elements
And now a three dimensional Array with two elements in each dimension :
_$ (setq three_dim (vlax-make-safearray vlax-vbString '(0 . 2) '(1 . 2)))#<safearray...>
_$ (vlax-safearray-fill three_dim '(("Sheet1" "Sheet2") ("a" "b") ("d" "e")))#<safearray...>
_$ (vlax-safearray->list three_dim)(("Sheet1" "Sheet2") ("a" "b") ("d" "e"))

Here we have a list of three lists.
This time, the first list '(0 . 2) defines three dimensions and the second '(1 . 2) defines 2 elements in each dimension.
One place you will be using "vlax-safearray-fill" is when creating selection sets with filters. The syntax in ActiveX for "Selecting All with Filters" is as follows :
object.Select Mode[, Point1][, Point2][, Filter_Code][, Filter_Value]
Filter_Code must be an Integer array and Filter_Value a Variant array.
In Visual Lisp, the coding would be written like this :

;create a 2 element integer array for the DXF Codes.(setq filter_code (vlax-make-safearray vlax-vbinteger '(0 . 1)));create a 2 element variant array for the values.(setq filter_value (vlax-make-safearray vlax-vbvariant '(0 . 1)));DXF Codes for Objects and Layer : " 0" for Object," 8" for Layer.(vlax-safearray-fill filter_code '(0 8));Name of Object and Layer.(vlax-safearray-fill filter_value '("CIRCLE" "2"));select ALL Circles on Layer 2.(vla-select newsset acSelectionSetAll nil nil filter_code filter_value)

For more information on Selections Sets, pop along to my "Selection Sets" tutorial page and get yourself even more confused.
The "vlax-safearray-put-element" function can be used to assign values to one or more elements of a safearray. The number of arguments required by this function depends on the number of dimensions in the array.

  • The first argument always names the safearray to which you are assigning a value.
  • The next set of arguments identifies index values pointing to the element to which you are assigning a value. For a single-dimension array, specify one index value: for a two-dimension array, specify two index values, and so on.
  • The final argument is always the value to be assigned to the safearray element.

Have a look at the following :
_$ (setq pt1 (vlax-make-safearray vlax-vbDouble '(1 . 3)))#<safearray...>
_$ (vlax-safearray-put-element pt1 1 100)100
_$ (vlax-safearray-put-element pt1 2 100)100
_$ (vlax-safearray-put-element pt1 3 75)75
_$ (vlax-safearray->list pt1)(100.0 100.0 75.0)
_$ (vlax-safearray-put-element pt1 1 50)50
_$ (vlax-safearray->list pt1)(50.0 100.0 75.0)

Now let's populate a two-dimension array of strings :

_$ (setq two_dim (vlax-make-safearray vlax-vbString '(0 . 1) '(1 . 3)))#<safearray...>
_$ (vlax-safearray-put-element two_dim 0 1 "a")"a"
_$ (vlax-safearray->list two_dim)(("a" "" "") ("" "" ""))
_$ (vlax-safearray-put-element two_dim 0 2 "b")"b"
_$ (vlax-safearray-put-element two_dim 0 3 "c")"c"
_$ (vlax-safearray-put-element two_dim 1 1 "d")"d"
_$ (vlax-safearray-put-element two_dim 1 2 "e")"e"
_$ (vlax-safearray-put-element two_dim 1 3 "f")"f"
_$ (vlax-safearray->list two_dim)(("a" "b" "c") ("d" "e" "f"))

You can use "vlax-safearray-get-element" to get the value of any element in any array. Here we'll use "vlax-safearray-get-element" to retrieve the second element in the first dimension of the array :
_$ (vlax-safearray-get-element matrix 1 2)"b"

(vlax-safearray-get-l-bound) returns the lower boundary (starting index) of a dimension of an array :
Get the starting index value of the second dimension of the array :
_$ (vlax-safearray-get-l-bound two_dim  2) 1

The second dimension starts with index 1.
Conversley, "vlax-safearray-get-u-bound" returns the upper boundary (end index) of a dimension of an array
Get the end index value of the second dimension of the array :
_$ (vlax-safearray-get-u-bound two_dim  2)
3
The second dimension ends with index 3.
You can use "vlax-safearray-get-dim" to get the number of dimensions in a safearray object :
Get the number of dimensions in "two_dim" :
_$ (vlax-safearray-get-dim two_dim) 2
There are 2 dimensions in "two_dim".
Using Arrays
Let's have a look at putting some of this to good use :

  1. (vl-load-com)
  2. (defunc:Line_VL
  3.   (/ acApp acDoc mspace p1 p2 sp ep lineObj)
  4.   (setq acApp (vlax-get-acad-object))
  5.   (setq acDoc (vla-get-activedocument acApp))
  6.   (setq mspace (vla-get-modelspace acDoc))
  7.   (setq p1 (getpoint "\nFirst Point : "))
  8.   (setq p2 (getpoint p1 "\nSecond Point : "))
  9.   (setq sp (vlax-make-safearray vlax-vbdouble '(0 . 2)))
  10.   (setq ep (vlax-make-safearray vlax-vbdouble '(0 . 2)))
  11.   (vlax-safearray-fill sp p1)
  12.   (vlax-safearray-fill ep p2)
  13.   (setq lineObj (vla-addline mspace sp ep))
  14.   (princ)
  15. )



There is an easier way of writing this routine :

  1. (vl-load-com)
  2. (defun c:Line_VL (/ acApp acDoc mspace p1 p2 lineObj)
  3.   (setq acApp (vlax-get-acad-object))
  4.   (setq acDoc (vla-get-activedocument acApp))
  5.   (setq mspace (vla-get-modelspace acDoc))
  6.   (setq p1 (getpoint "\nFirst Point : "))
  7.   (setq p2 (getpoint p1 "\nSecond Point : "))
  8.   (setq
  9.     lineObj (vla-addline mspace (vlax-3d-point p1) (vlax-3d-point p2))
  10.   )
  11.   (princ)
  12. )



For methods that require you to pass a three-element array of doubles (typically to specify a point), you can use the "vlax-3d-point" function.
Well, that's it with Arrays. I haven't covered absolutely everything pertaining to Arrays, but you should now have enough to get you started. I hope that you understood everything I was warbling on about, and that I didn't confuse you too much!
Adios for now, amigo…



论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 2476个

财富等级: 金玉满堂

发表于 2017-5-16 09:42:01 | 显示全部楼层
(defun SerialNumber(Tag / OBJW) ;(SerialNumber "BaseBoard")
  (vl-load-com)
  (if(SETQ OBJW(VLAX-CREATE-OBJECT "wbemScripting.SwbemLocator"))
    (vlax-for item(vlax-invoke(VLAX-INVOKE OBJW 'ConnectServer ".""\\root\\cimv2" "" """" "" 128 nil)
                                                           'ExecQuery(strcat"Select SerialNumber,Tag from Win32_"Tag))
      (vlax-get item 'SerialNumber))
    ))
上面函数可以读主板号
(VLAX-INVOKE OBJW 'ConnectServer ".""\\root\\cimv2" "" """" "" 128 nil)
这句的参数怎么来的..我不知道哪里可以查到哈...大师能不能指导一下哈..万分感谢了!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 20个

财富等级: 恭喜发财

 楼主| 发表于 2017-5-16 09:47:56 | 显示全部楼层

论坛就有,用 WMI 搜索下论坛看看
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 2476个

财富等级: 金玉满堂

发表于 2017-5-16 10:07:35 | 显示全部楼层

查不到..我想知道"wbemScripting.SwbemLocator"对应方法的参数有哪些...论坛没有相关介绍..
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 19个

财富等级: 恭喜发财

发表于 2017-5-16 10:20:30 | 显示全部楼层

用 (vlax-dump-object item t) 看不到方法和属性吗?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 2476个

财富等级: 金玉满堂

发表于 2017-5-16 10:28:04 | 显示全部楼层

还真查不到..不然就不到处问了..
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 2476个

财富等级: 金玉满堂

发表于 2017-5-16 10:32:04 | 显示全部楼层

你也试试..参数完全看不懂..
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2017-5-16 11:44:09 | 显示全部楼层

下面代码
(vlax-invoke wmi 'connectserver nil nil nil nil nil nil nil nil) 相当于连接到WMI数据库
win32_diskdrive相当于下面的一个表
Select * from Win32_DiskDrive  是数据库查询语句,*代码查询Win32_DiskDrive表下所有的字段。


你循环处理,打印这些字段的名字,就知道支持什么字段查询了。

  1. (defun c:tt (/ lst)
  2.   (setq        wmi (vlax-create-object "WbemScripting.SWbemLocator")
  3.         srv (vlax-invoke
  4.               wmi 'connectserver nil nil nil nil nil nil nil nil)
  5.         drv (vlax-invoke srv 'execquery "Select * from Win32_DiskDrive")
  6.   )
  7.   (vlax-for item drv
  8.     (vlax-for prop (vlax-get item 'Properties_)
  9.       (setq lst (cons (vlax-get prop 'name) lst))
  10.     )
  11.   )
  12.   (setq lst (reverse lst))
  13.   (princ "\n支持的字段查询(前十):")
  14.   (setq i 0)
  15.   (repeat 10 (princ "\n") (prin1 (nth i lst)) (setq i (1+ i)))
  16.   (princ)
  17. )




下面是打印前10个

"Availability"
"BytesPerSector"
"Capabilities"
"CapabilityDescriptions"
"Caption"
"CompressionMethod"
"ConfigManagerErrorCode"
"ConfigManagerUserConfig"
"CreationClassName"
"DefaultBlockSize"


评分

参与人数 1D豆 +5 收起 理由
/db_自贡黄明儒_ + 5 热心帮忙奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 2476个

财富等级: 金玉满堂

发表于 2017-5-16 13:59:24 | 显示全部楼层

太感谢了..找死我了..
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 2476个

财富等级: 金玉满堂

发表于 2017-5-16 14:23:27 | 显示全部楼层

是不是我太笨了..还没明白哈..

(vlax-invoke wmi 'connectserver nil nil nil nil nil nil nil nil)
这个参数表多长怎么知道的...

(VLAX-INVOKE OBJW 'ConnectServer ".""\\root\\cimv2" "" """" "" 128 nil)

这个是主板号的参数..

我怎么知道参数应该写些什么...??
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-9-24 04:24 , Processed in 0.475144 second(s), 54 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表