aardio官方社区

标题: 如何判断Excel文件已打开? [打印本页]

作者: lly10011    时间: 2018-5-30 12:55
标题: 如何判断Excel文件已打开?
    程序中会打开一个Excel文件进行读、写、保存、关闭等操作,但是如果这个Excel在操作系统中已经打开的话,就会造成异常。
    因此,我想程序在打开这个Excel文件之前,判断该文件是否已在操作系统中打开,该如何操作?
    耽误大家宝贵时间帮忙指导一下,谢谢
作者: Jacen.He    时间: 2018-5-30 15:07
我试了一下没有报错,提问注意提供可重现问题的代码。

另外即然有异常,用try捕获异常就知道能不能正常打开了。
作者: lly10011    时间: 2018-6-5 00:31
  1. import win.ui;
  2. import fsys.dlg;
  3. import com.excel;
  4. /*DSG{{*/
  5. var winform = win.form(text="aardio form";right=396;bottom=146;parent=...)
  6. winform.add(
  7. button={cls="button";text="打开Excel文件";left=87;top=38;right=311;bottom=95;z=1}
  8. )
  9. /*}}*/

  10. var excel, book = null, null;
  11. winform.button.oncommand = function(id,event){
  12.     if ("关闭Excel文件" == winform.button.text) {
  13.         winform.button.text = "打开Excel文件";
  14.             book.save(); book.close();
  15.             return;
  16.     }
  17.    
  18.         var file_path = fsys.dlg.open("Excel文件|*.xls;*xlsx|",,,winform.hwnd);
  19.         if (null == file_path) {
  20.                 return;
  21.         }
  22.            
  23.         excel = com.excel(true);
  24.         if (!excel) error ("Excel未正确安装!");
  25.        
  26.         excel.Visible = false;                                                                                                                                // Excel窗口不可见

  27.         book = excel.WorkBooks.Open(file_path);
  28.         var sheet = book.Worksheets(1);
  29.        
  30.         sheet.Cells(1,1).Value2 = tostring(time(, "%Y%m%d%H%M%S"));
  31.         sheet.Range("A1").HorizontalAlignment         = -4108/*_xlCenter*/; sheet.Columns(1).ColumnWidth = 48;
  32.        
  33.         winform.button.text = "关闭Excel文件";
  34. }

  35. winform.enableDpiScaling();
  36. winform.show();

  37. win.loopMessage();
  38. return winform;
复制代码
测试环境:32位 WIN7 SP1,WPS软件
    1、系统桌面存在一个1234.xls的文件,当桌面已打开该1234.xls的文件时,此时代码所示程序如何判断1234.xls已被其他软件打开?
    2、当代码所示程序打开该1234.xls文件后,然后在桌面打开其他非1234.xls的文件,此时可以看到该1234.xls的文件被同时打开,该如何避免?

    以上两个问题麻烦大家指导一下,问题1我通过复制一个临时文件解决了,但是问题2我没有办法。


作者: alajia    时间: 2018-6-5 15:14
两种思路:
1、当XLS文件已打开时,再次以读写方式打开会不成功,这样你的第一和第二个问题就都可以判断出来:
  1. import console;
  2. import fsys.file;

  3. file = fsys.file("C:\1234.xls","r+");
  4. if( file ){
  5.         console.log( "未被占用,可以正常打开" );
  6.         file.close();       
  7. }
  8. else {
  9.         console.log( "已占用,先关闭吧" );
  10. }

  11. console.pause(true);
复制代码


2、用com方式判断,并且在判断已打开的情况下可以选择继续使用,或者关闭后再用其他程序打开。
  1. import console;
  2. import com;

  3. var Application = null;

  4. try{
  5.         Application = ..com.GetObject("Excel.Application");
  6. }

  7. if( Application ){
  8.         for(i=1;Application.Workbooks.count;1){
  9.                 console.log( Application.Workbooks(i).Name );       
  10.                 if( Application.Workbooks(i).Name == "1234.xls"){
  11.                         //关闭退出
  12.                         Application.Workbooks(i).close();
  13.                         break ;
  14.                 }               
  15.         }
  16. }

  17. console.pause(true);
复制代码

作者: lly10011    时间: 2018-6-5 18:32
谢谢 alajia
问题1可以通过这个方案解决,关键是问题2.
问题1我通过复制一个临时文件处理,在操作这个临时文件时,我肯定是不希望被别人看到的(感官上不好),所以程序在处理临时文件时,如何解决桌面打开其他文件时,顺便也将该临时文件显示的问题?
作者: alajia    时间: 2018-6-7 14:26
想不显示特定的文件,就在打开后找到该子窗口句柄,隐藏。
作者: lly10011    时间: 2018-6-7 18:24
alajia 发表于 2018-6-7 14:26
想不显示特定的文件,就在打开后找到该子窗口句柄,隐藏。

其实这个显示特定的文件也不是每次都发生,我有点怀疑是WPS的问题。
另外,请问如何隐藏窗口?
作者: lly10011    时间: 2018-6-7 18:33
alajia 发表于 2018-6-7 14:26
想不显示特定的文件,就在打开后找到该子窗口句柄,隐藏。

刚刚在论坛里面找了下,找到了隐藏窗口的代码。
不过,我的那个代码中,窗口是已经隐藏了的(excel.Visible = false),自身操作时并不会有显示,完全是在打开其他excel文件时带出来的
作者: alajia    时间: 2018-6-7 20:35
注意,是“子窗口”,就是你打开的临时文件,在EXCEL中只是其中的一个子窗口,是一个EXECEL类的窗口
作者: lly10011    时间: 2018-6-8 17:08
alajia 发表于 2018-6-7 20:35
注意,是“子窗口”,就是你打开的临时文件,在EXCEL中只是其中的一个子窗口,是一个EXECEL类的窗口

    我反复验证了,应该是wps(或者微软excel)机制导致的。
    在该代码中,我打开了一个A.xls文件,可以看到任务管理器中生成了一个et.exe的进程,然后在系统中打开B.xls文件,可以看到任务管理中会立即生成另外一个et.exe的进程,然后这个新et.exe关闭,再然后系统界面同时显示出A.xls和B.xls文件,此时若代码中执行excel.quit(),会导致A.xls和B.xls同时关闭。
    所以,有没有办法使第一个et.exe被独占?
作者: alajia    时间: 2018-6-11 13:19
  1. import console;
  2. import win;
  3. import winex;

  4. winex.enum(
  5.         function(hwnd,depth){
  6.                 //隐藏A.xls窗口
  7.                 win.show(hwnd/*窗口*/,0x0/*_SW_HIDE*/)                       
  8.                 sleep(20000);
  9.                 //还原A.xls显示
  10.                 win.show(hwnd/*窗口*/,0x1/*_SW_NORMAL*/);       
  11.         }
  12.         ,
  13.         ,"EXCEL"
  14.         ,"A.xls"
  15. )

  16. console.pause(true);
复制代码

作者: lly10011    时间: 2018-6-11 14:07
alajia 发表于 2018-6-11 13:19

谢谢,刚才已经测试这个方法了。现象是一样的,当打开新的Excel文件时,被隐藏的文件仍然连带被显示出来




欢迎光临 aardio官方社区 (http://bbs.aardio.com/) Powered by Discuz! X3.4