Excel VBA 如何使用默认应用程序打开文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18921168/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 16:40:51  来源:igfitidea点击:

How can Excel VBA open file using default application

vbaexcel-vbaexcel

提问by Michael11B12

I want an Excel spreadsheet that has a file path and name in column A. When a macro is run, let's say the file specified in A1 should be opened on the user's machine. The file could be .doc, .xls, .txt, etc.... rather than my vba needing to know the full path the to application, how could I have the vba tell the machine "please open this file and use your application associated with the extension" ?

我想要一个 Excel 电子表格,它在 A 列中有一个文件路径和名称。当运行宏时,假设 A1 中指定的文件应该在用户的机器上打开。该文件可能是 .doc、.xls、.txt 等......而不是我的 vba 需要知道应用程序的完整路径,我怎么能让 vba 告诉机器“请打开这个文件并使用你的应用程序与扩展相关”?

I have already found this to work with the full path:

我已经发现这适用于完整路径:

dblShellReturned = Shell("C:\Windows\System32\notepad.exe myfile.txt, vbNormalFocus)

how could I get it to work with something like:

我怎样才能让它与类似的东西一起工作:

dblShellReturned = Shell("myfile.txt", vbNormalFocus) ' how do I get this to work

Thank you in advance!

先感谢您!

回答by Tin Bum

This works for me in Excel & Word

这在 Excel 和 Word 中对我有用

Sub runit()
   Dim Shex As Object
   Set Shex = CreateObject("Shell.Application")
   tgtfile = "C:\Nax\dud.txt"
   Shex.Open (tgtfile)
End Sub

or ... as per Expenzor's comment below

或...根据下面的 Expenzor 评论

CreateObject("Shell.Application").Open("C:\Nax\dud.txt")

CreateObject("Shell.Application").Open("C:\Nax\dud.txt")

回答by AndASM

The code below is a template. However you might want to update the default (working) directory to the location of the file.

下面的代码是一个模板。但是,您可能希望将默认(工作)目录更新为文件所在的位置。

Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
                   (ByVal hwnd As Long, ByVal lpszOp As String, _
                    ByVal lpszFile As String, ByVal lpszParams As String, _
                    ByVal LpszDir As String, ByVal FsShowCmd As Long) _

Function StartDoc(DocName As String) As Long
      Dim Scr_hDC As Long
      Scr_hDC = GetDesktopWindow()
      StartDoc = ShellExecute(Scr_hDC, "Open", DocName, _
      "", "C:\", SW_SHOWNORMAL)
 End Function

回答by Tony Emrud

VBA's Shell command wants an exe, so I've been launching the explorer.exe and passing in my file path as an argument. It also seems to work with *.lnk shortcuts and web urls.

VBA 的 Shell 命令需要一个 exe,所以我一直在启动 explorer.exe 并将我的文件路径作为参数传递。它似乎也适用于 *.lnk 快捷方式和网址。

Shell "explorer.exe C:\myfile.txt"

回答by Toby Ovod-Everett

I can't comment on existing answers (not enough points), so I'm answering to add information.

我无法评论现有答案(分数不够),所以我正在回答以添加信息。

Working from Access 2010, I ran into silent failures with the following syntax:

从 Access 2010 开始,我遇到了以下语法的静默失败:

Dim URL As String
URL = "http://foo.com/"
CreateObject("Shell.Application").Open URL

I could get it to work if I wrapped URLin parentheses, but that just seems wrong for subroutine (instead of function) call syntax. I tried swallowing the return value, but that failed with function call syntax, unless I doubled up the parentheses. I realized that the parentheses weren't just syntactic sugar - they had to be doing something, which lead me to believe they might be facilitating implicit casting.

如果我用URL括号括起来,我可以让它工作,但这对于子例程(而不是函数)调用语法来说似乎是错误的。我尝试吞下返回值,但是函数调用语法失败了,除非我将括号加倍。我意识到括号不仅仅是语法糖 - 他们必须做一些事情,这让我相信他们可能会促进隐式转换。

I noticed that Openexpects a Variant, not a String. So I tried CVar, which did work. With that in mind, the follwing is my preferred approach since it minimizes the "why are there extraneous parentheses here?" questions.

我注意到Open期望 a Variant,而不是 a String。所以我尝试了CVar,确实有效。考虑到这一点,以下是我的首选方法,因为它最大限度地减少了“为什么这里有多余的括号?” 问题。

Dim URL As String
URL = "http://foo.com/"
CreateObject("Shell.Application").Open CVar(URL)

The lesson is that when making OLE Automation calls, be explicit about having Access VBA cast things appropriately!

教训是,在进行 OLE 自动化调用时,要明确让 Access VBA 适当地投射内容!

回答by ivan_pozdeev

Shell32.ShellCOM objectaka Shell.Applicationcan be used that wraps the ShellExecuteWin32 API function:

Shell32.ShellShell.Application可以使用COM 对象来包装ShellExecuteWin32 API 函数:

  • Add a reference to Microsoft Shell Controls And Automationtype library to VBA project via Tools->References..., then

    Dim a As New Shell32.Shell
    Call a.ShellExecute("desktop.ini")
    
  • Alternatively, without any references:

    Call CreateObject("Shell.Application").ShellExecute("desktop.ini")
    
  • Microsoft Shell Controls And Automation通过 向 VBA 项目添加对类型库的引用Tools->References...,然后

    Dim a As New Shell32.Shell
    Call a.ShellExecute("desktop.ini")
    
  • 或者,没有任何参考:

    Call CreateObject("Shell.Application").ShellExecute("desktop.ini")
    

Interestingly, here (WinXP), when using a typed variable (that provides autocomplete), ShellExecuteis missing from the members list (but works nonetheless).

有趣的是,这里 (WinXP) 在使用类型化变量(提供自动完成功能)时ShellExecute从成员列表中丢失(但仍然有效)。