GetOpenFileName在后台打开

时间:2018-02-22 15:48:59

标签: excel-vba background vba excel

我有一个提示用户选择逗号分隔值文件的宏,但是,每当宏运行时,它会打开所有其他打开窗口后面的窗口。永远不会从excel调用宏,而只能通过其他脚本调用宏。我曾尝试弄乱Application.DisplayAlertsApplication.ActiveWindow,但无济于事。非常感谢任何建议。

Function folderselection()
    Dim fnameandpath As Variant
    Dim path As String

    Dim objshell As Object
    Set objshell = CreateObject("wscript.shell")
    objshell.AppActivate "excel"

    Application.DisplayAlerts = False
    path = ActiveWorkbook.path
    ChDrive (path)
    ChDir (path)

    Application.ActiveWindow.Visible = True
    Application.WindowState = xlMaximized

    fnameandpath = Application.GetOpenFilename(FileFilter:=("BOM CSV/RPT (*.CSV;*.RPT), *.CSV; *.RPT"), Title:="Select The BOM File To Copy Values From")
    Application.WindowState = xlMinimized

    If fnameandpath = False Then Exit Function
    Workbooks.Open Filename:=fnameandpath, ReadOnly:=True

    Application.DisplayAlerts = True
    folderselection = CStr(fnameandpath)
    ActiveWorkbook.Close
End Function

1 个答案:

答案 0 :(得分:1)

查看代码的某些部分:

Function folderselection()
Dim fnameandpath As Variant
...
fnameandpath = Application.GetOpenFilename(...
...
folderselection = CStr(fnameandpath)

这些行是多余的。这样就可以用一半代码完成同样的事情(因此更简单):

Function folderSelection() as String
...
folderSelection = Application.GetOpenFilename(...
Dim path As String
path = ActiveWorkbook.path
ChDrive (path)
ChDir (path)

这些线条什么也没做。 GetOpenFilename对话框默认为与ActiveWorkbook.Path相同的文件夹。

Dim objshell As Object
Set objshell = CreateObject("wscript.shell")
objshell.AppActivate "excel"

这些行也不会。我想您可能正在尝试激活现有的Excel窗口?如果是这样,您需要阅读这些命令的文档。

我保证您没有名为excel的标题栏。您可能有一个名为“Book1.xlsm - Excel”,但这是无关紧要的,因为您不需要激活当前窗口,除非您在0.01秒内使用其他应用程序,因为您[我假设]手动执行此过程。

此外,需要以某种方式处理对象,例如在完成内存后释放内存(即 Set ... Nothing ;请参阅下面的“崩溃”)否则,某些进程将保留在内存中,占用空间,直到重新启动。

重要的是要理解在任意使用它们之前应该至少部分地理解某些命令,因为你可能会有意想不到的结果。在这种情况下, Windows脚本主机 wscript),以及调用“外部” 命令行程序 shell.exe)可能/将影响其他应用程序和/或导致崩溃。

Application.DisplayAlerts = False
Application.DisplayAlerts = True

这并没有完成与您尝试做的事情相关的任何事情(并且应该谨慎使用某些设置或者根本不使用某些设置 - 例如在代码中禁用警告或安全警报,以免开始时正常运行。把这些线留下来吧。

Application.ActiveWindow.Visible = True

活动窗口,按照定义,已经可见。这条线没有任何作用。

Application.WindowState = xlMaximized 
Application.WindowState = xlMinimized 

真的?显然这些“互相取消”,更不用说“最后一个” 使窗口最小化 “无法看到窗口”是您的主要问题吗?

fNameAndPath = Application.GetOpenFilename(FileFilter:=("BOM CSV/RPT (*.CSV;*.RPT), *.CSV; *.RPT"), Title:="Select The BOM File To Copy Values From")

具有讽刺意味的是,您认为的命令是问题,实际上是唯一正常运行的行(无论语法和组织问题有多少)。诸如间隔和使用“精确记录的语法”之类的小事情最终会对代码的成功产生影响,并且在仍处于故障排除阶段时尤为重要。

匹配命令的文档,以及如上所述更改目标:

folderSelection = Application.GetOpenFilename("Comma Separated Files (*.csv),*.csv,Report Files (*.rpt),*.rpt.", 1, "Select the Source BOM File")
If fNameAndPath = False Then Exit Function

这条线没什么问题!就个人而言,我会使用:

 If Not fNameAndPath Then Exit Function

......但结果是一样的。

 Workbooks.Open Filename:=fNameAndPath, ReadOnly:=True

根据文档,更好地说明该行是:

Workbooks.Open Workbooks.Open fNameAndPath, , True, 2

2指定逗号分隔。由于您指定文件以逗号分隔,我将假设您指定的其他选项(“.RPT”文件)也是基于文本的逗号分隔文件。

该行可能可以正常运行,这很好,因为它是子程序的关键部分。

除了 ,0.01秒后,最后一个命令 关闭刚刚打开的文件

ActiveWorkbook.Close

使用VBA和/或Excel,通常(通常是?)有多种方法可以完成相同的任务,增加了灵活性和易用性,使Excel在几乎“每个桌面和每个家庭中都很常见。 “ [其他人都抓住了那个参考资料?!]

不幸的是,反面(在这里很常见)是用户不必要地过度复杂化任务;甚至[不知不觉]尝试从头开始构建功能 - 这已经已经内置到Excel和Office套件的其余部分。