| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3136 人关注过本帖
标题:VFP对EXCEL读操作,如何防止用户另外启动EXCEL而造成错误。
取消只看楼主 加入收藏
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:400
帖 子:11857
专家分:43421
注 册:2006-5-13
收藏
得分:0 
应该说也是有效的办法之一,但缺点也是显而易见的,就是在读数据的期间剥夺了用户使用电脑的权利。如果读操作时间较长,用户就不能进行其他事务处理,正如T版主所说的那样,有点太“野蛮”了,而且也影响用户正常工作。

活到老,学到老!http://www.(该域名已经被ISP盗卖了)E-mail:hu-jj@
2012-05-11 07:44
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:400
帖 子:11857
专家分:43421
注 册:2006-5-13
收藏
得分:0 
感谢各位的热心参与!尽管还没有找到理想的解决方案,但因为不想看到论坛的结贴提示,只好先结贴。结贴之后仍希望各位继续各抒已见。

活到老,学到老!http://www.(该域名已经被ISP盗卖了)E-mail:hu-jj@
2012-05-12 07:21
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:400
帖 子:11857
专家分:43421
注 册:2006-5-13
收藏
得分:0 
感谢楼上的积极参与!不过我的问题是:在VFP对EXCEL文件进行读操作的过程中,如果用户又打开了任意的EXCEL文件,就会导致读入的数据错误。并不是事先检查用户有无打开EXCEL文件的问题。
在VFP中建立EXCEL对象时,操作系统是建立了一个新的进程,与原来用户打开的EXCEL文件不会共用一个进程。问题是VFP在自己建立的EXCEL进程中操作时,倘若用户又打开EXCEL文件时,操作系统可能就会用VFP建立的进程(也是最新的进程),从而导致读数据出错。

活到老,学到老!http://www.(该域名已经被ISP盗卖了)E-mail:hu-jj@
2012-05-12 15:27
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:400
帖 子:11857
专家分:43421
注 册:2006-5-13
收藏
得分:0 
刚才又测试了一下,先打开一个EXCEL文件进行操作,然后运行VFP程序对另一个EXCEL文件进行读操作,再对先打开的EXCEL文件进行修改、保存、退出等操作,都不会影响到VFP程序的读操作。证实了VFP建立的EXCEL进程不与原来用户已经建立的进程有关系这个判断。

活到老,学到老!http://www.(该域名已经被ISP盗卖了)E-mail:hu-jj@
2012-05-12 15:43
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:400
帖 子:11857
专家分:43421
注 册:2006-5-13
收藏
得分:0 
事实上用户先打开一个EXCEL文件,在没有关闭的前提下,VFP程序又打开同一个EXCEL文件时,操作系统会自动以只读的方式打开副本,不会对先前的文件有影响,也不会影响VFP的读操作。只是用户先关闭这个文件时,系统会提示。

活到老,学到老!http://www.(该域名已经被ISP盗卖了)E-mail:hu-jj@
2012-05-12 16:34
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:400
帖 子:11857
专家分:43421
注 册:2006-5-13
收藏
得分:0 
操作系统不允许用户选择用哪个进程来打开EXCEL文件的。
假设用户先打开的EXCEL进程为进程1,VFP再建立的EXCEL对象为进程2。此时用户若再打开EXCEL文件,操作系统不会用进程1来打开,而是用进程2来打开,以至影响到VFP程序的读操作。
不知道VFP建立EXCEL对象时能否申请到独占的进程么,用户再要使用EXCEL进程,只能用进程1,或者新建进程。

活到老,学到老!http://www.(该域名已经被ISP盗卖了)E-mail:hu-jj@
2012-05-12 17:07
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:400
帖 子:11857
专家分:43421
注 册:2006-5-13
收藏
得分:0 
在VFP中是用CREATEOBJECT("Excel.application")建立对象,然后打开特定的EXCEL文件。

活到老,学到老!http://www.(该域名已经被ISP盗卖了)E-mail:hu-jj@
2012-05-12 18:46
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:400
帖 子:11857
专家分:43421
注 册:2006-5-13
收藏
得分:0 
以下的内容是从楼上给出的网址复制粘贴过来的。我还没来得及仔细研究。在此向楼上表示谢意!

文件关联是指打开一种类型的文件的默认方式比如默认状态下文本文件txt是与记事本程序相关联的我们双击文本文件就能直接运行记事本程序来编辑它。文件的关联是通过注册表得以实现的本例就是利用API函数RegCreateKey和RegSetValue来对注册表进行修改从中可以看到这两个函数的用法。   

  --------------------------------------
  利用WinApi函数实现文件关联
  --------------------------------------
  程序说明:
  例中利用两个API函数RegCreateKey和
  RegSetValue修改注册表中的相应键值
  实现某一类型文件.log同一个应用程序
  notepad.exe的关联.
  --------------------------------------
  说明&作为数据类型的标示而不是“与”运算符
  &指Long长整型数据其范围从   -2,147,483,648      2,147,483,647。Long   的类型声明字符为和号   (&)。   

  当关联按钮被按下时读写注册表完成   .log   文件和   记事本Notepad   的关联
  如果你对注册表的结构和使用不熟悉的话可以参看“电脑乐园”中的相关教程

Private   Sub   Command1_Click()
If   CmdPressed   =   True   Then   Exit   Sub   

  Dim   sKeyName   As   String   键的名称
  Dim   sKeyValue   As   String   键值
  Dim   ret&   返回错误信息的变量
  Dim   lphKey&   此变量用来保存创建的键的句柄

  实际效果是在注册表的HKEY_CLASSES_ROOT下创建MyApp目录
  sKeyName   =   "MyApp "   *名为MyApp的键名
  sKeyValue   =   "Logfiles "   *把键值设为 "Logfiles "
  在HKEY_CLASSES_ROOT中创建名为sKeyName的键并返回句柄lphKey&
  ret&   =   RegCreateKey&(HKEY_CLASSES_ROOT,   sKeyName,   lphKey&)
  向句柄lphKey&所指的位置写入键值sKeyValue
  ret&   =   RegSetValue&(lphKey&,   " ",   REG_SZ,   sKeyValue,   0&)

 在注册表的HKEY_CLASSES_ROOT下创建另外一个目录   .log
  sKeyName   =   ".log "   *名为.log的键名
  sKeyValue   =   "MyApp "   *把键值设为 "MyApp "

ret&   =   RegCreateKey&(HKEY_CLASSES_ROOT,   sKeyName,   lphKey&)
ret&   =   RegSetValue&(lphKey&,   " ",   REG_SZ,   sKeyValue,   0&)   

  为“MyApp”设置了一个命令行
  sKeyName   =   "MyApp "   *名为MyApp的键名
  sKeyValue   =   "notepad.exe   %1 "   *把键值设为 "notepad.exe   %1 "如果你知道DOS下的.Bat文件的语法的话便知%1指的是要打开的文件
  如果该键已经创建则RegCreateKey那么函数会打开现有的项
  ret&   =   RegCreateKey&(HKEY_CLASSES_ROOT,   sKeyName,   lphKey&)
  下面一句的实际效果是在MyApp键下建立shell\open\command目录并写入键值sKeyValue
  说明:放在一个键的shell\open\command下的是打开某一类型文件的应用程序的名称
  ret&   =   RegSetValue&(lphKey&,   "shell\open\command ",   REG_SZ,   sKeyValue,   MAX_PATH)

  Command1.Caption   =   "关联已经创建 "


Command1.Enabled   =   False
CmdPressed   =   True
End   Sub   

Private   Sub   Form_Load()
CmdPressed   =   False
End   Sub     

  以下是模块文件中的代码:

Declare   Function   RegCreateKey&   Lib   "advapi32.dll "   Alias   "RegCreateKeyA "   (ByVal   hKey&,   ByVal   lpszSubKey$,   lphKey&)   

【VB声明】

Private   Declare   Function   RegCreateKey   Lib   "advapi32.dll "   Alias   "RegCreateKeyA "   (ByVal   hKey   As   Long,   ByVal   lpSubKey   As   String,   phkResult   As   Long)   As   Long   
【说明】
在指定的项下创建一个新项。如指定的项已经存在那么函数会打开现有的项   

【返回值】
Long零(ERROR_SUCCESS)表示成功。其他任何值都代表一个错误代码   

【参数表】
hKey   -----------   Long要打开项的句柄或者一个标准项名   

lpSubKey   -------   String欲创建的新子项。可同时创建多个项只需用反斜杠将它们分隔开即可。例如level1\level2\newkey   

phkResult   ------   Long指定一个变量用于装载新子项的句柄

Declare   Function   RegSetValue&   Lib   "advapi32.dll "   Alias   "RegSetValueA "   (ByVal   hKey&,   ByVal   lpszSubKey$,   ByVal   fdwType&,   ByVal   lpszValue$,   ByVal   dwLength&)   

【VB声明】

Private   Declare   Function   RegSetValue   Lib   "advapi32.dll "   Alias   "RegSetValueA "   (ByVal   hKey   As   Long,   ByVal   lpSubKey   As   String,   ByVal   dwType   As   Long,   ByVal   lpData   As   String,   ByVal   cbData   As   Long)   As   Long   

【说明】
设置指定项或子项的默认值   

【返回值】
Long零(ERROR_SUCCESS)表示成功。其他任何值都代表一个错误代码   
【参数表】
hKey   -----------   Long一个已打开项的句柄或指定一个标准项名   

lpSubKey   -------   String欲对它的值进行设置的一个子项的名字。如指定vbNullString表示设置hKey的默认值。如指定的子项不存在则会创建它   

dwType   ---------   Long必须是REG_SZ   

lpData   ---------   String新值   

cbData   ---------   Long指定lpData的长度不包括空中止字符


Public   Const   ERROR_SUCCESS   =   0&
Public   Const   ERROR_BADDB   =   1&
Public   Const   ERROR_BADKEY   =   2&
Public   Const   ERROR_CANTOPEN   =   3&
Public   Const   ERROR_CANTREAD   =   4&
Public   Const   ERROR_CANTWRITE   =   5&
Public   Const   ERROR_OUTOFMEMORY   =   6&
Public   Const   ERROR_INVALID_PARAMETER   =   7&
Public   Const   ERROR_ACCESS_DENIED   =   8&
Global   Const   HKEY_CLASSES_ROOT   =   &H80000000
Public   Const   MAX_PATH   =   256&
Public   Const   REG_SZ   =   1   
 我们先来声明API函数本例中用到的两个函数声明如下:


   Private   Declare   Function   RegCreateKey&   Lib   "advapi32.dll "   Alias   "RegCreateKeyA "   (ByVal   hKey&,   ByVal   lpszSubKey$,   lphKey&)   As   Long   

   Private   Declare   Function   RegSetValue&   Lib   "advapi32.dll "   Alias   "RegSetValueA "   (ByVal   hKey&,   ByVal   lpszSubKey$,   ByVal   fdwType&,   ByVal   lpszValue$,   ByVal   dwLength&)   As   Long     

  RegCreateKey函数的作用是在注册表中指定的主键下创建一个新的主键而如指定的键已经存在那么函数会打开现有的主键其中各个参数的意义如下表所示:   

    参数   意义   
hKey   Long   要打开键的句柄或者一个标准键名。例如:HKEY_CLASSES_ROOT   是标准键名   
lpSubKey   String   欲创建的新子键。如创建多个键需用反斜杠将它们分隔开。例如:level1\newkey     
phkResult   Long   指定一个变量用于得到新子键的句柄在设置键值时要用到它   
返回值   Long   零(ERROR_SUCCESS)表示成功。其他任何值都代表一个错误代码     

  RegSetValue函数用于设置指定键或子键的默认值它的各个参数的意义如下:

参数   意义   
hKey   Long   一个已打开键的句柄可从上面phkResult得到或是指定一个标准键名   
lpSubKey   String   要设置键值的一个子键的名字。如指定vbNullString表示设置hKey的默认值。如指定的子键不存在则会创建它   
dwType   Long   必须是REG_SZ   
lpData   String   新的键值   
cbData   Long   指定lpData的长度不包括空中止字符   
返回值   Long   零(ERROR_SUCCESS)表示成功。其他任何值都代表一个错误代码   

  下面我们看看怎样实现文件关联步骤一:在在注册表的HKEY_CLASSES_ROOT下创建MyApp主键:

   ret&   =   RegCreateKey&(HKEY_CLASSES_ROOT,   sKeyName,   lphKey&)   
  语句中sKeyName已经预先赋值为 "MyApp "而函数执行完后lphKey&会返回新创建的主键的句柄然后我们向句柄lphKey&所指的位置写入键值sKeyValue(已经赋值为 "Logfiles ")

   ret&   =   RegSetValue&(lphKey&,   " ",   REG_SZ,   sKeyValue,   0&)   

  如果这时查看注册表会发现如下图所示的新主键和键值:   

  步骤二:在注册表的HKEY_CLASSES_ROOT下创建另外一个主键键名为“.log”键值为“MyApp”创建的方法与第一步相同只不过键名和键值不同。建立此键值的作用是把“.log”文件关联到“MyApp”主键所规定的内容这时的注册表如下:   

  第三步:我们为“MyApp”设置了一个命令行也就是在主键MyApp下建立如下主键:   

  实现的代码是:

   sKeyName   =   "MyApp "          *名为MyApp的键名   
   sKeyValue   =   "notepad.exe   %1 "     *把键值设为 "notepad.exe   %1 "%1指的是要打开的文件   
      如果该键已经创建则RegCreateKey那么函数会打开现有的项   
   ret&   =   RegCreateKey&(HKEY_CLASSES_ROOT,   sKeyName,   lphKey&)   
      下面一句的实际效果是在MyApp键下建立shell\open\command目录并写入键值sKeyValue   
      说明:放在一个键的shell\open\command下的是打开某一类型文件的应用程序的名称   
   ret&   =   RegSetValue&(lphKey&,   "shell\open\command ",   REG_SZ,   sKeyValue,   MAX_PATH)   

  经过以上几个步骤我们已经建立了“.log”文件和“记事本”程序的关联。总结前面的内容可以发现在VB中采用API对注册表操作的基本思路都是类似的只要我们知道了两个API函数的用法然后熟悉注册表操作就能灵活的写出与注册表相关的程序来。

活到老,学到老!http://www.(该域名已经被ISP盗卖了)E-mail:hu-jj@
2012-05-15 13:36
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:400
帖 子:11857
专家分:43421
注 册:2006-5-13
收藏
得分:0 
打开多个窗口是肯定可以的,但如何指定操作对应的窗口却是个难题。我推测,VFP可能是对当前活动的EXCEL窗口进行操作,而不是认定自己打开的EXCEL窗口,所以才造成这个问题。

活到老,学到老!http://www.(该域名已经被ISP盗卖了)E-mail:hu-jj@
2013-07-23 07:12
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:400
帖 子:11857
专家分:43421
注 册:2006-5-13
收藏
得分:0 
一年多了,S版还在关注这个问题?

活到老,学到老!http://www.(该域名已经被ISP盗卖了)E-mail:hu-jj@
2013-07-23 07:13
快速回复:VFP对EXCEL读操作,如何防止用户另外启动EXCEL而造成错误。
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.029671 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved