VBA';未定义用户定义的类型';使用Outlook编译错误

VBA';未定义用户定义的类型';使用Outlook编译错误,vba,excel,outlook,Vba,Excel,Outlook,我有一个很大的Excel文件,它通过一个命令按钮将电子邮件发送给工作中的经理,然后他们可以按下按钮,它将文件发送给他们下面的经理 因为每个经理都有自己版本的MS Office,我有一个sub,检查他/她计算机上的版本,并在参考文件中标记V 保存文件时,我将其保存为Outlook对象库未标记为V,并且我有其他人生成的代码。代码通过3个子节点运行。第一个子模块有一个msgbox,当您回答时,它会将您发送到下一个子模块 Public Sub before_send_mail() answer

我有一个很大的Excel文件,它通过一个命令按钮将电子邮件发送给工作中的经理,然后他们可以按下按钮,它将文件发送给他们下面的经理

因为每个经理都有自己版本的
MS Office
,我有一个sub,检查他/她计算机上的版本,并在
参考文件中标记
V

保存文件时,我将其保存为
Outlook对象库
未标记为
V
,并且我有其他人生成的代码。代码通过3个子节点运行。第一个子模块有一个
msgbox
,当您回答时,它会将您发送到下一个子模块

Public Sub before_send_mail()

    answer = MsgBox("Send Email?", vbYesNo + vbQuestion, "Empty Sheet")

    If answer = vbYes Then
        Call excel_ver
        Call sendMail
        Call remove_ref
    Else
     'do nothing
    End If

End Sub
然后,我有一个“按office版本选择引用选择器”,它检查计算机上安装了哪个版本,并在
Tools-->references
中自动标记
Outlook
对象中的
V
。这一部分似乎也很有效

Sub excel_ver()

    On Error Resume Next
    ver = Application.Version

    If ver = 16 Then
        tmp_name = "C:\Program Files\Microsoft Office\Office16\MSOUTL.OLB"
        Application.VBE.ActiveVBProject.References.AddFromFile tmp_name
        Exit Sub
    End If

    If ver = 15 Then
        tmp_name = "C:\Program Files\Microsoft Office\Office15\MSOUTL.OLB"
        Application.VBE.ActiveVBProject.References.AddFromFile tmp_name
        Exit Sub
    End If

    If ver = 14 Then
        tmp_name = "C:\Program Files\Microsoft Office\Office14\MSOUTL.OLB"
        Application.VBE.ActiveVBProject.References.AddFromFile tmp_name
        Exit Sub
    End If

End Sub
然后我们开始讨论这个问题。当我转到sub
sendMail
时,它在
Dim applOL As Outlook.Application

Public Sub sendMail()

    Call ini_set

    If mail_msg.Cells(200, 200) = 1 Then

        lr = main_dist.Cells(main_dist.Rows.Count, "A").End(xlUp).Row

        On Error Resume Next

        For i = 2 To lr

            Application.DisplayAlerts = False

            Dim applOL As Outlook.Application 'Here is the error ---- that line
            Dim miOL As Outlook.MailItem
            Dim recptOL As Outlook.Recipient

            mail_msg.Visible = True

            mailSub = mail_msg.Range("B1")
            mailBody = mail_msg.Range("B2")

            mail_msg.Visible = False

            Set applOL = New Outlook.Application
            Set miOL = applOL.CreateItem(olMailItem)
            Set recptOL = miOL.Recipients.Add(main_dist.Cells(i, 5))
            recptOL.Type = olTo

            tempPath = ActiveWorkbook.Path & "\" & main_dist.Cells(i, 4) & ".xlsm"

            With miOL
                .Subject = mailSub
                .Body = mailBody
                .Attachments.Add tempPath
                .send     
            End With

            Set applOL = Nothing
            Set miOL = Nothing
            Set recptOL = Nothing

            Application.DisplayAlerts = True

        Next i
   End If
End Sub

在预编译过程中,
Outlook.Application
无效,因为它未在
Tools\References…
中设置。如果你想让你的代码继续工作,你需要先运行
ini\u set
,然后再编译
sendMail
。尝试添加新的子例程以按顺序调用这两个函数:

Sub MainSub()
    call ini_set
    call sendMail
End Sub
为了清楚起见,请从您的
sendMail
中删除
Call ini\u set
,每次必须调用这两个函数时,请从单独的子例程中执行此操作


重要使用此解决方案,您可以保留
outlook应用程序常量
(如
olMailItem
),这在切换到
后期绑定解决方案时是不可能的
,应在无需参考的情况下运行:

Public Sub sendMail()

    Dim applOL As Object, miOL As Object, recptOL As Object
    Dim i As Long

    ini_set

    If mail_msg.Cells(200, 200) = 1 Then

        Set applOL = CreateObject("Outlook.Application")

        For i = 2 To main_dist.Cells(main_dist.Rows.Count, "A").End(xlUp).Row

            Set miOL = applOL.CreateItem(0)  'olMailItem=0
            Set recptOL = miOL.Recipients.Add(main_dist.Cells(i, 5))
            recptOL.Type = 1  ' olTo=1

            With miOL
                .Subject = mail_msg.Range("B1")
                .Body = mail_msg.Range("B2")
                .Attachments.Add ActiveWorkbook.Path & "\" & _
                                 main_dist.Cells(i, 4) & ".xlsm"
                .send
            End With
        Next i
        Set applOL = Nothing
   End If
End Sub

编辑:在上面的代码中,我删除了一些“一次性”变量,但这只是我的首选…

提前绑定到“Office14”Outlook(最低分母)。如果用户具有更高版本,VBA将自动修复引用。
在引用中标记V
<代码>给我一个错误< /代码>?或者如果性能没有可怕的影响考虑后期绑定?消除了对大量代码的需要。@ashleedawg我已经尝试过纠正这一点,希望OP会回来并进一步改进。而实际问题似乎没有了!