【问题标题】:VBA - Detect if an application is installed to use itVBA - 检测是否安装了应用程序以使用它
【发布时间】:2017-07-03 10:05:18
【问题描述】:

我制作了一个 Excel 文件,其中存储了许多定制工业零件的信息。
它允许用户通过 Outlook 发送预先格式化的邮件来询问新价格。

不幸的是,一些用户的“轻”桌面没有 Outlook,他们收到错误:

找不到项目或库

很遗憾,安装 Outlook 不是一个选项,延迟投标已经完成。


我在考虑预处理器指令,但我不知道如何在我的情况下使用它们...

我知道我们可以在 Windows 和 VBA 版本中使用的常量:see here

我会做这样的事情:

#If Outlook then
    MsgBox "Outlook is installed"
#Else
    MsgBox "Outlook is NOT installed"
#End if

但这只会检测代码是否从 Outlook 运行,这不是我需要的...:/


所以我想我可以用On Error 做一些事情,但它看起来并不整洁,有什么建议吗?

【问题讨论】:

  • 删除引用并使用后期绑定 (createobject("Outlook.Application")) - 捕获如果 Outlook 不可用时将引发的错误。
  • 你会在函数中使用on error,比如OUTLOOK_INSTALLED() as Boolean,然后做一些错误捕获,创建一个outlook实例,很多关于这个的文章,在任何错误点,都返回false。然后说If OUTLOOK_INSTALLED then......

标签: excel vba outlook preprocessor preprocessor-directive


【解决方案1】:

我试图找到其他方法来检测应用程序,而不依赖于 CreateObject 中的错误

这使用了 WMI 对象,它似乎工作得很好,但它不区分演示版本
它列出了注册表路径Microsoft\Windows\CurrentVersion\App Paths(32 位和 64 位)中已安装的应用程序


Public Function AppDetected() As Boolean
    Const HKEY_LOCAL_MACHINE = &H80000002   'HKEY_CURRENT_USER = &H80000001
    Const APP_PATH = "\Microsoft\Windows\CurrentVersion\App Paths\"
    Const APP_PATH_32 = "SOFTWARE" & APP_PATH
    Const APP_PATH_64 = "SOFTWARE\Wow6432Node" & APP_PATH
    Const REG_ITM = "!\\.\root\default:StdRegProv"
    Const REG = "winmgmts:{impersonationLevel=impersonate}" & REG_ITM
    Const ID = "Outlook"   '"OUTLOOK.EXE"

    Dim wmi As Object, subKeys As Variant, found As Variant

    If wmi Is Nothing Then Set wmi = GetObject(REG)

    If wmi.EnumKey(HKEY_LOCAL_MACHINE, APP_PATH_32, subKeys) = 0 Then
        If Not IsNull(subKeys) Then found = UBound(Split(Join(subKeys), ID)) > 0
    End If
    If Not found Then
        If wmi.EnumKey(HKEY_LOCAL_MACHINE, APP_PATH_64, subKeys) = 0 Then
            If Not IsNull(subKeys) Then found = UBound(Split(Join(subKeys), ID)) > 0
        End If
    End If
    AppDetected = found
End Function

注意:我只在没有 Outlook 的机器上测试过

来自 MS 的有关 WMI Tasks: Registry 的更多详细信息


另一个使用 MIME 的 WMI 版本,在 VBScript 中显示已安装的 MS 应用程序:

Set wmi = GetObject("winmgmts:\\.\root\CIMV2")
Set itms = wmi.ExecQuery("SELECT * FROM Win32_MIMEInfoAction", "WQL", &h10 + &h20)

For Each itm In itms
    WScript.Echo itm.Name
Next

检测MS Mail,类似于CreateObject:Application.ActivateMicrosoftApp xlMicrosoftMail


确定 Outlook 用户帐户:

'If Outlook exists, set reference to Microsoft Outlook *
Public Function ShowOutlookAccount() As Long
    Dim appOutlook As Outlook.Application, i As Long

    Set appOutlook = CreateObject("Outlook.Application")
    For i = 1 To appOutlook.Session.Accounts.Count
        Debug.Print appOutlook.Session.Accounts.Item(i) & " : Account number " & i
    Next
End Function

来自 Ron de Bruin 的更多 Outlook utils

【讨论】:

    【解决方案2】:

    你可以这样做:

    Sub Whatever()
        Dim obj As Object
        Set obj = CreateObjectType("Outlook.Application")
    
        If Not obj Is Nothing Then
            '...
        End If
    
    End Sub
    
    Public Function CreateObjectType(objectType As Variant) As Object
        On Error Resume Next
        CreateObjectType = CreateObject(objectType)
    End Function
    

    【讨论】:

    • 将函数声明为布尔值可能是一个更好的主意 - 请参阅第二条评论。
    • @Vityata 也许,但是这样你可以根据需要创建不同的对象类型,例如CreateObjectType("Excel.Application")CreateObjectType("Word.Application").
    • 没错,但它仍然可以是布尔值。
    【解决方案3】:

    你可以试试类似的...

    Dim olApp As Object
    On Error Resume Next
    Set olApp = GetObject(, "Outlook.Application")
    If Err <> 0 Then Set olApp = CreateObject("Outlook.Application")
    On Error GoTo 0
    If olApp Is Nothing Then
       MsgBox "Outlook is not installed on your system." & vbNewLine & vbNewLine & _
             "Please Install & Configure The Outlook And Then Try Again...", vbExclamation, "Outlook Not Installed!"
       Exit Sub
    End If
    

    【讨论】:

      【解决方案4】:

      这是我的解决方案:

      Option Explicit
      
      Sub TestMe()
      
          Debug.Print blnObjectInstalled
      
      End Sub
      
      Public Function blnObjectInstalled(Optional strObjectType As String = "Outlook.Application") As Boolean
      
          On Error GoTo blnobjectInstalled_Error
      
          Dim obj As Object
          Set obj = CreateObject(strObjectType)
      
          blnObjectInstalled = True
      
          On Error GoTo 0
          Exit Function
      
      blnobjectInstalled_Error:
      
          blnObjectInstalled = False
      
      End Function
      

      我们的想法是我们做一个布尔函数,定义对象是否被安装,接受一个可选的字符串,因此它可以检查各种对象。作为字符串值,更容易检查。

      用预处理器指令来做这件事似乎是不可能的,因为你需要设置一个等于检查 Outlook 是否安装的函数的常量,而常量不喜欢这样。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-29
        • 1970-01-01
        • 1970-01-01
        • 2013-09-16
        相关资源
        最近更新 更多