张和平 发表于 2013-5-22 19:11:45

【讨论】保存程序系统变量

本帖最后由 张和平 于 2013-5-27 12:30 编辑

关于保存变量的问题,我在论坛里搜索了一下,caoyin版主给出过以下指导性的说法
===引自:http://bbs.mjtd.com/forum.php?mod=viewthread&tid=89166

方法很多种:
1.直接使用全局变量,这种方法最简单。(特点:关闭文档“记忆”就被关闭)
2.写入、读取图形词典。(特点:记忆只储存在当前图形文档)
3.写入、读取注册表。(特点:记忆储存于计算机,可以任何文档任何时候读取或修改)
4.写入、读取文件,如TXT文件(特点:同上)
5.写入、读取环境变量(特点:同上)
==========================================
我想实现永久记住变量的效果(即,在一个文档中修改过,其余文档中也改变),显然要用3,4,5这三种方法。但是,在论坛里好像没有这方面系统性的介绍。
大神们能不能详细地来介绍一下这三个方法呢?最好是能给出适当的范例。

我自己的一些想法:
若用注册表的方法,那么,一个变量设定一个注册表项,觉得有点乱,那么我就想,我弄一个表,这个表里的元素是一个类似(变量名变量值)这样的点对,然后把这个表存入注册表,这样就显得比较简洁。
若用文件的话,显得对系统的“侵染”没有那么大,但是速度方面是否会慢?另外,变量有更新时,更新的具体操作如何?读取的具体操作如何?
若用环境变量的话,是个什么原理和模式呢?


====自己琢磨着弄出来的保存变量至txt的函数,,如下,水平有限,望高手能贴出你们的保存变量至txt的函数,让我对比学习一下。。具体参考10楼(vl-load-com)
(defun c:test()
(defun *error* (msg);错误处理函数
    (princ "\n**error: ")
    (princ msg)      ;_ 打印错误信息
    (princ)         
)
(setq PEACE:SYSVAL1 3;设定变量
PEACE:SYSVAL2 2
PEACE:SYSVAL3 3
PEACE:SYSVAL4 "4"
PEACE:SYSVAL5 "5"
PEACE:SYSVAL6 "DFFDS"
)

(PEACE:SAVESYSVAL "PEACE:SYSVAL1" PEACE:SYSVAL1)
(PEACE:SAVESYSVAL "PEACE:SYSVAL2" PEACE:SYSVAL2)
(PEACE:SAVESYSVAL "PEACE:SYSVAL3" PEACE:SYSVAL3)
(PEACE:SAVESYSVAL "PEACE:SYSVAL4" PEACE:SYSVAL4)
(PEACE:SAVESYSVAL "PEACE:SYSVAL5" PEACE:SYSVAL5)
(PEACE:SAVESYSVAL "PEACE:SYSVAL6" PEACE:SYSVAL6)
;(princ (strcat "\n变量成功保存入" acadpath "\\PEACESYSVAL.TXT"))
(princ)
)
(defun PEACE:SaveSysVal(valname valvalue / acadpath f datalist data valvalue_old i isthere)
(setq acadpath(vlax-get-property (vlax-get-acad-object) 'Path))
(IF (null (findfile "PEACESYSVAL.TXT"))
    (progn ;若文件不存在
      (setq f (open (strcat acadpath "\\PEACESYSVAL.TXT") "w"))
      (prin1 (list valname valvalue) f)
      (close f)
    )
    (progn ;若文件已存在
      (setq datalist '())
      (setq f (open (strcat acadpath "\\PEACESYSVAL.TXT") "r"))
      (while (setq data (read-line f))
      (setq datalist (cons data datalist))
      )
      (reverse datalist)
      (close f)
      (princ "\n")
      (princ datalist)
      (setq       i 0
            isthere 0)
      (repeat (length datalist)
      (if (= valname (car (read (nth i datalist))))
          (progn
          (setq datalist (subst (list valname valvalue) (read (nth i datalist)) datalist))
          (setq isthere 1)
          )
      )
      (setq i (1+ i))
      )
      (princ "\n")
      (princ isthere)
      (if (= 1 isthere)
      (progn
          (setq f (open (strcat acadpath "\\PEACESYSVAL.TXT") "w"))
          (prin1 (read (nth 0 datalist)) f)
          (close f)
          (setq i 1)
          (setq f (open (strcat acadpath "\\PEACESYSVAL.TXT") "a"))
          (repeat (- (length datalist) 1)
            (write-line "" f)
            (prin1 (read (nth i datalist)) f)
            (setq i (1+ i))
          )
          (close f)
      )
      (progn
          (setq f (open (strcat acadpath "\\PEACESYSVAL.TXT") "a"))
          (write-line "" f)
          (prin1 (list valname valvalue) f)
          (close f)
      )
      )
    )
)
(princ)
)
更新:读取存在txt中的变量名和变量值:(vl-load-com)
(defun c:test()
(defun *error* (msg);错误处理函数
    (princ "\n**error: ")
    (princ msg)      ;_ 打印错误信息
    (princ)         
)
;|(setq PEACE:SYSVAL1 3;设定变量
      PEACE:SYSVAL2 2
      PEACE:SYSVAL3 3
      PEACE:SYSVAL4 "4"
      PEACE:SYSVAL5 "5"
      PEACE:SYSVAL6 "DFFDS"
)

(PEACE:SAVESYSVAL "PEACE:SYSVAL1" PEACE:SYSVAL1)
(PEACE:SAVESYSVAL "PEACE:SYSVAL2" PEACE:SYSVAL2)
(PEACE:SAVESYSVAL "PEACE:SYSVAL3" PEACE:SYSVAL3)
(PEACE:SAVESYSVAL "PEACE:SYSVAL4" PEACE:SYSVAL4)
(PEACE:SAVESYSVAL "PEACE:SYSVAL5" PEACE:SYSVAL5)
(PEACE:SAVESYSVAL "PEACE:SYSVAL6" PEACE:SYSVAL6)
;(princ (strcat "\n变量成功保存入" acadpath "\\PEACESYSVAL.TXT"))|;
;以下涉及的PEACE:SYSVAL7~10是自己手动输入的,,,
(PEACE:READSYSVAL)
(princ "\n")
(princ PEACE:SYSVAL7)
(princ "\n")
(princ PEACE:SYSVAL8)
(princ "\n")
(princ PEACE:SYSVAL9)
(princ "\n")
(princ PEACE:SYSVAL10)
(princ)
)
(defun PEACE:SaveSysVal(valname valvalue / acadpath f datalist data valvalue_old i isthere)
(setq acadpath(vlax-get-property (vlax-get-acad-object) 'Path))
(IF (null (findfile "PEACESYSVAL.TXT"))
    (progn ;若文件不存在
      (setq f (open (strcat acadpath "\\PEACESYSVAL.TXT") "w"))
      (prin1 (list valname valvalue) f)
      (close f)
    )
    (progn ;若文件已存在
      (setq datalist '())
      (setq f (open (strcat acadpath "\\PEACESYSVAL.TXT") "r"))
      (while (setq data (read-line f))
            (setq datalist (cons data datalist))
      )
      (reverse datalist)
      (close f)
      ;(princ "\n")
      ;(princ datalist)
      (setq       i 0
            isthere 0)
      (repeat (length datalist)
      (if (= valname (car (read (nth i datalist))))
          (progn
          (setq datalist (subst (list valname valvalue) (read (nth i datalist)) datalist))
          (setq isthere 1)
          )
      )
      (setq i (1+ i))
      )
      ;(princ "\n")
      ;(princ isthere)
      (if (= 1 isthere)
      (progn
          (setq f (open (strcat acadpath "\\PEACESYSVAL.TXT") "w"))
          (prin1 (read (nth 0 datalist)) f)
          (close f)
          (setq i 1)
          (setq f (open (strcat acadpath "\\PEACESYSVAL.TXT") "a"))
          (repeat (- (length datalist) 1)
            (write-line "" f)
            (prin1 (read (nth i datalist)) f)
            (setq i (1+ i))
          )
          (close f)
      )
      (progn
          (setq f (open (strcat acadpath "\\PEACESYSVAL.TXT") "a"))
          (write-line "" f)
          (prin1 (list valname valvalue) f)
          (close f)
      )
      )
    )
)
(princ)
)
(defun PEACE:ReadSysVal( / acadpath data datalist i)
(setq acadpath(vlax-get-property (vlax-get-acad-object) 'Path))
(if (findfile "PEACESYSVAL.TXT")
    (progn
    (setq datalist '())
    (setq f (open (strcat acadpath "\\PEACESYSVAL.TXT") "r"))
      (while (setq data (read-line f))
            (setq datalist (cons data datalist))
      )
      (reverse datalist)
    (close f)
    (setq i 0)
    (repeat (length datalist)
      (set (read (car (read (nth i datalist)))) ;注意字符和表之间的转换,字符串是不能作为变量名的
            (cadr (read (nth i datalist)))      ;car对字符串也是不起作用的
      )
      (setq i (1+ i))
    )
    )
)
)
整理一下思路:
将变量存入txt时:1、判断PEACESYSVAL.TXT(当然也可以是你命名的)是否存在,若不存在,则创建(我默认将此txt放在cad安装目录);2、写入变量名和变量值时,先判断此变量是否已经存在,若存在,则更新为新的变量值,若不存在,则直接在最后面append;3、第2条判断变量是否存在时,先把txt中各行数据读取,形成一个表,然后依次检查表中有没有变量名和要存入的变量名相同即可,更新也操作此表,然后将txt中原内容删除,重新写入此表;4、变量名和变量值组成一个表格,形如(“变量名”变量值)存入txt中,一个变量占据一行,形如下面:("PEACE:SYSVAL1" 3)
("PEACE:SYSVAL2" 2)
("PEACE:SYSVAL3" 3)
("PEACE:SYSVAL4" "4")
("PEACE:SYSVAL5" "5")
("PEACE:SYSVAL6" "DFFDS")将txt中变量读取时:同上,先读取出来,形成一个大表,其中每个元素为一个形如(“变量名”变量值)的小表,然后将以此将小表的第一个作为变量名,第二个作为变量值,给当前函数赋予变量。


=========2013/05/25更新
昨天贴上的命令流还是有误,不能更新变量值,后发现有一行代码有误,现更新上最新的,还望大家帮忙测试。
另,新码中,加入了infotext,即(PEACE:SaveSysVarPeace valname valvalue)变成 (PEACE:SaveSysVarPeace valname valvalue infotext),也即,txt中存储变量的形式由(“变量名”变量值)变为(“变量名”变量值 “备注”),备注中可以存放对变量的描述。
贴上源码:

vlisp2012 发表于 2013-5-22 19:21:36

我也想知道这个问题,哪位高手路过?

ZHENYOUDNG 发表于 2013-5-22 19:39:26

同求此类问题是解答!

wowan1314 发表于 2013-5-22 20:37:22

本帖最后由 wowan1314 于 2013-5-22 20:39 编辑

5、CAD有15个自定义的环境变量。不过好像只存到图形,还不如字典好用。其他不清楚
4、txt文件保存很明显是可行的。可去研究下read-line及write-line这两函数.
3、注册表没玩过。帮你查到这两函数

注册表样例:

1)_$ (vl-registry-write "HKEY_CURRENT_USER\\Test" "" "test data")

"test data"

2)_$(vl-registry-read "HKEY_CURRENT_USER\\Test")

"test data"

张和平 发表于 2013-5-22 22:57:36

wowan1314 发表于 2013-5-22 20:37 static/image/common/back.gif
5、CAD有15个自定义的环境变量。不过好像只存到图形,还不如字典好用。其他不清楚
4、txt文件保存很明显是 ...

注册表可按http://bbs.mjtd.com/thread-99350-1-1.html这个来弄,讲得比较清晰,,txt就不是很清楚了,我先按您的指引研究下那俩函数。。。感谢

张和平 发表于 2013-5-23 08:52:32

早上来顶一下

ucuc2003 发表于 2013-5-23 09:19:25

关注下这里

张和平 发表于 2013-5-24 13:29:01

(vl-load-com)
(defun c:test()
(defun *error* (msg)
    (princ "\n**error: ")
    (princ msg)      ;_ 打印错误信息
    (princ)         
)
(setq PEACE:SYSVAL1 1
        PEACE:SYSVAL2 2
        PEACE:SYSVAL3 3
        PEACE:SYSVAL4 "4"
        PEACE:SYSVAL5 "5"
        PEACE:SYSVAL6 "DFFDS"
)
(PEACE:SYSVAL_SAVE (cons "PEACE:SYSVAL4" PEACE:SYSVAL4))
(PEACE:SYSVAL_SAVE (cons "PEACE:SYSVAL1" PEACE:SYSVAL1))
(PEACE:SYSVAL_SAVE (cons "PEACE:SYSVAL2" PEACE:SYSVAL2))
(PEACE:SYSVAL_SAVE (cons "PEACE:SYSVAL3" PEACE:SYSVAL3))
(PEACE:SYSVAL_SAVE (cons "PEACE:SYSVAL5" PEACE:SYSVAL5))
(PEACE:SYSVAL_SAVE (cons "PEACE:SYSVAL6" PEACE:SYSVAL6))
(princ (strcat "\n变量成功保存入" acadpath "\\PEACESYSVAL.TXT"))
(princ)
)
(defun PEACE:SYSVAL_SAVE(val / acadpath f)
(setq acadpath(vlax-get-property (vlax-get-acad-object) 'Path))
(IF (null (findfile "PEACESYSVAL.TXT"))
    (progn
      (setq f (open (strcat acadpath "\\PEACESYSVAL.TXT") "w"))
      (prin1 val f)
      (close f)
    )
    (progn
      (setq f (open (strcat acadpath "\\PEACESYSVAL.TXT") "a"))
      (write-line "" f)
      (prin1 val f)
      (close f)
    )
)
(princ)
)
变量以点表的形式保存入txt中,自动保存在ACAD安装目录下。
目前在保存这方面还有以下问题:
1、上述命令流中,对于(PEACE:SYSVAL_SAVE (cons "PEACE:SYSVAL4" PEACE:SYSVAL4))这个如何简化?我想把这个工作放到(PEACE:SYSVAL_SAVE)函数中去,即我引用的时候就是(PEACE:SYSVAL_SAVE PEACE:SYSVAL4)但是能达到现在的效果。
2、若我新保存的变量,在txt中已经存在了,那么就变成替换的问题了,不是简单地在后面append的问题了,我目前的构思是这样的:保存变量前,先把txt中的变量读取形成一个表,类似图元表,然后判断要保存的变量是否在表中已存在,若存在,便替换新值,若不存在,则append。不知有没有简单一点的方法。

fl202 发表于 2013-5-24 17:42:34

放在txt中最简单,就用read-line及write-line,不用vl等函数,适用性广。把txt文件存在该dwg文档同一个文件夹下,安全,易于查看及修改,你的程序发布给别人后,别人也很好改。
至于变量值改变后,你可以先读出来,然后比较判断后再存,这方法已经很简单了,还要怎样?

张和平 发表于 2013-5-24 18:07:00

编好了保存变量的函数,,自己测试通过,大家也帮忙测试一下。。。
这里主要涉及要几方面:
1、判断txt是否已经存在,若尚不存在则创建
2、判断变量在txt中是否已经存在,若存在则修改更新变量值,若不存在则增加此变量(vl-load-com)
(defun c:test()
(defun *error* (msg);错误处理函数
    (princ "\n**error: ")
    (princ msg)      ;_ 打印错误信息
    (princ)         
)
(setq PEACE:SYSVAL1 3;设定变量
        PEACE:SYSVAL2 2
        PEACE:SYSVAL3 3
        PEACE:SYSVAL4 "4"
        PEACE:SYSVAL5 "5"
        PEACE:SYSVAL6 "DFFDS"
)

(PEACE:SAVESYSVAL "PEACE:SYSVAL1" PEACE:SYSVAL1)
(PEACE:SAVESYSVAL "PEACE:SYSVAL2" PEACE:SYSVAL2)
(PEACE:SAVESYSVAL "PEACE:SYSVAL3" PEACE:SYSVAL3)
(PEACE:SAVESYSVAL "PEACE:SYSVAL4" PEACE:SYSVAL4)
(PEACE:SAVESYSVAL "PEACE:SYSVAL5" PEACE:SYSVAL5)
(PEACE:SAVESYSVAL "PEACE:SYSVAL6" PEACE:SYSVAL6)
;(princ (strcat "\n变量成功保存入" acadpath "\\PEACESYSVAL.TXT"))
(princ)
)
(defun PEACE:SaveSysVal(valname valvalue / acadpath f datalist data valvalue_old i isthere)
(setq acadpath(vlax-get-property (vlax-get-acad-object) 'Path))
(IF (null (findfile "PEACESYSVAL.TXT"))
    (progn ;若文件不存在
      (setq f (open (strcat acadpath "\\PEACESYSVAL.TXT") "w"))
      (prin1 (list valname valvalue) f)
      (close f)
    )
    (progn ;若文件已存在
      (setq datalist '())
      (setq f (open (strcat acadpath "\\PEACESYSVAL.TXT") "r"))
      (while (setq data (read-line f))
              (setq datalist (cons data datalist))
      )
      (reverse datalist)
      (close f)
      (princ "\n")
      (princ datalist)
      (setq       i 0
            isthere 0)
      (repeat (length datalist)
      (if (= valname (car (read (nth i datalist))))
          (progn
          (setq datalist (subst (list valname valvalue) (read (nth i datalist)) datalist))
          (setq isthere 1)
          )
      )
      (setq i (1+ i))
      )
      (princ "\n")
      (princ isthere)
      (if (= 1 isthere)
      (progn
          (setq f (open (strcat acadpath "\\PEACESYSVAL.TXT") "w"))
          (prin1 (read (nth 0 datalist)) f)
          (close f)
          (setq i 1)
          (setq f (open (strcat acadpath "\\PEACESYSVAL.TXT") "a"))
          (repeat (- (length datalist) 1)
            (write-line "" f)
            (prin1 (read (nth i datalist)) f)
            (setq i (1+ i))
          )
          (close f)
      )
      (progn
          (setq f (open (strcat acadpath "\\PEACESYSVAL.TXT") "a"))
          (write-line "" f)
          (prin1 (list valname valvalue) f)
          (close f)
      )
      )
    )
)
(princ)
)
页: [1] 2 3
查看完整版本: 【讨论】保存程序系统变量