ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 6208|回复: 16

[求助] Office 2007不能调用Shell函数等3个问题[已解决]

[复制链接]

TA的精华主题

TA的得分主题

发表于 2013-10-16 08:54 | 显示全部楼层 |阅读模式
本帖已被收录到知识树中,索引项:脚本语言应用
本帖最后由 loquat 于 2013-10-18 17:51 编辑

1.软件版本Office2007,无法使用Shell函数,翻遍了百度没找到原因。
2013-10-16_084609.jpg
2.使用Shell对象遍历所有文件(包含所有子目录)
  1. Sub 遍历Shell()
  2. Dim objShell As Object, cmdExec As Object, t, command$
  3. t = Timer
  4. command = Environ$("comspec") & " /c dir ""C:"" /s /b"
  5. Set objShell = CreateObject("WScript.Shell")
  6. Set cmdExec = objShell.Exec(command)
  7. 'Debug.Print cmdExec.StdOut.ReadAll
  8. Debug.Print Timer - t
  9. End Sub
复制代码
使用cmd遍历目录效率奇高,比纯VB效果要好很多。
问题是:使用shell对象时,怎么隐藏cmd运行那个黑窗口。试了好多种办法。
例如这种就是不可以的。
  1. Set cmdExec = objShell.Exec(command, 0)
复制代码
3.同上,怎么将结果导出到数组或者字典里面。
   遍历是为了能批量处理,所以不能导出到变量里面的话,就没有意义了。
   也许有两种方法:1.直接在VBA里将cmd命令的结果赋值给数组或者字典,求教。
                               2.使用cmd命令的将结果输出的txt文件,然后从txt文件读取到数组或者字典。求教。

1.这一问我觉得是2007的问题,已成冤案
2.Exec和Run各有好处
3.具体代码见本帖10#

TA的精华主题

TA的得分主题

发表于 2013-10-16 13:48 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
Sub s()
Shell "explorer.exe E:", vbNormalFocus
End Sub

2010测试通过

TA的精华主题

TA的得分主题

发表于 2013-10-16 14:25 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2013-10-16 14:29 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-10-16 15:56 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
liucqa 发表于 2013-10-16 13:48
Sub s()
Shell "explorer.exe E:", vbNormalFocus
End Sub

这个我仍然不能用,不会是2007的问题吧

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-10-16 16:51 | 显示全部楼层
liucqa 发表于 2013-10-16 14:25
http://bbs.bathome.net/viewthread.php?tid=5695
VBS中run和exec的区别

这篇文章很到位,谢谢帮忙找到。

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-10-16 21:28 | 显示全部楼层
liucqa 发表于 2013-10-16 14:29
像你这种需求,我觉得还是API比较好
http://www.yesky.com/52/185052.shtml

主要是用API容易遗漏文件,递归效率又相对低一些。
DIR函数配合字典遗漏也比较严重。
所以想从文件入手,在你提供的链接里找到了不少遍历算法。直接尝试搜了好久没搜到这些好算法。

TA的精华主题

TA的得分主题

发表于 2013-10-16 21:46 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 liucqa 于 2013-10-16 21:50 编辑
loquat 发表于 2013-10-16 21:28
主要是用API容易遗漏文件,递归效率又相对低一些。
DIR函数配合字典遗漏也比较严重。
所以想从文件入手 ...

http://bbs.csdn.net/topics/390461605?page=1

看62楼,我觉得这个方法可行,你改成run方法,然后读文件,这样看不到窗口,也不漏文件。



  1. shell "dir /b /a-d c:\*.* >d:\allfile.txt",vbHide
  2. '读文件d:\allfile.txt的内容即C:\下所有文件的名字
  3. shell "dir /b /s /a-d c:\*.* >d:\allfiles.txt",vbHide
  4. '读文件d:\allfiles.txt的内容即C:\下所有文件的名字(包含子目录)
  5. shell "dir /b /ad  c:\*.* >d:\alldirs.txt",vbHide
  6. '读文件d:\alldirs.txt的内容即C:\下所有子目录的名字

  7. 请记住,能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作,而不要用各种API获取或者操作,因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时,API会处理的不全面或陷入死循环,而shell命令不会。
复制代码





TA的精华主题

TA的得分主题

 楼主| 发表于 2013-10-16 23:17 | 显示全部楼层
liucqa 发表于 2013-10-16 21:46
http://bbs.csdn.net/topics/390461605?page=1

看62楼,我觉得这个方法可行,你改成run方法,然后读文 ...

是的,这个网址之前已经看过了。发这个帖子也是和为了知道怎么隐藏窗口和怎么从文件读取列表到数组里面。
看了你给的那个网址,然后跟了一下所有回帖,等我消化一下,估计就可以继续研究别的遍历思路了。

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-10-18 15:04 | 显示全部楼层

使用Shell对象调用cmd遍历文件夹

本帖最后由 loquat 于 2013-10-18 15:59 编辑

特点就是效率高,以下是两种方法。
方法一:Exec方法,有一个黑窗口一闪而过
方法二:Run方法,有临时文件生成
具体cmd中dir的使用方法请在cmd中使用dir/?来查看。
  1. dir "C:\Program Files" /s /a:-d /b > C:\1.txt  '遍历所有文件
  2. dir "C:\Program Files" /s /a:d /b > C:\1.txt   '遍历所有目录
  3. dir "C:\Program Files" /s /b > C:\1.txt          '遍历所有目录和文件
  4. dir "C:\Program Files\*.doc" /s /a:-d /b > C:\1.txt  '遍历所有word文件
  5.   
复制代码
  1. Sub 方法一()
  2. Dim arr, t, folder$, brr
  3. folder = """" & "C:\Program Files" & """"
  4. t = Timer
  5. With CreateObject("WScript.Shell")
  6.        brr = .Exec(Environ$("comspec") & " /c dir " & folder & " /s /a:-d /b").StdOut.ReadAll
  7. End With
  8. arr = Split(brr, vbCrLf)
  9. Debug.Print UBound(arr) & "个文件" & vbCrLf & Timer - t & "秒" & vbCrLf & arr(100)
  10. End Sub
复制代码

'---------------------------------------------------------------------------------------------
  1. Sub 方法二()
  2. Dim arr, t, folder$
  3. t = Timer
  4. folder = """" & "C:\Program Files" & """"
  5. With CreateObject("WScript.Shell")
  6.        .Run Environ$("comspec") & " /c dir " & folder & " /s /a:-d /b > C:\temp.txt", 0, True
  7. End With
  8. Open "C:\temp.txt" For Input As #1
  9. arr = Split(StrConv(InputB(LOF(1), 1), vbUnicode), vbCrLf)
  10. Close #1
  11. Debug.Print UBound(arr) & "个文件" & vbCrLf & Timer - t & "秒" & vbCrLf & arr(100)
  12. End Sub
复制代码

'---------------------------------------------------------------------------------------------


补充内容 (2014-4-5 17:16):
shell调用在2007里是这样的call shell(filepath,windowstyle)

补充内容 (2014-12-21 14:19):
Shell函数默认是异步执行,不能实现同步。
使用Shell对象,第3个参数就是控制同步的参数。True-同步,False-异步
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-6-19 09:22 , Processed in 0.038265 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

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