Excel ';编译错误:未定义用户定义的类型';通过代码添加word对象库后显示错误
我是VBA编程的新手,这是我在论坛上的第一篇帖子,如果我犯了任何错误,我想事先道歉 我正在自动化Excel工作簿,该工作簿打开并使用模板中的新Word文件。我使用“WithEvents”跟踪Word中的应用程序事件。在关闭工作簿时,我还使用代码删除word对象库引用,然后在“工作簿\打开”处再次添加它们,以确保此工作簿可以在具有不同版本word的其他计算机上工作 除每次打开工作簿时出现“编译错误:用户定义类型未定义”错误外,所有操作均按预期进行,但随后的编译工作正常。我知道是什么导致了它-在第一次编译试用期间没有对word对象库的引用,因此编译器不知道“word.Application”是什么,但从第二个实例开始它就知道了,因此不会产生错误 我就是不知道该怎么解决这个问题。我已经研究了LateBinding,但从研究中我发现WithEvents与LateBinding不兼容。任何帮助都将不胜感激 提前感谢您抽出时间Excel ';编译错误:未定义用户定义的类型';通过代码添加word对象库后显示错误,excel,vba,Excel,Vba,我是VBA编程的新手,这是我在论坛上的第一篇帖子,如果我犯了任何错误,我想事先道歉 我正在自动化Excel工作簿,该工作簿打开并使用模板中的新Word文件。我使用“WithEvents”跟踪Word中的应用程序事件。在关闭工作簿时,我还使用代码删除word对象库引用,然后在“工作簿\打开”处再次添加它们,以确保此工作簿可以在具有不同版本word的其他计算机上工作 除每次打开工作簿时出现“编译错误:用户定义类型未定义”错误外,所有操作均按预期进行,但随后的编译工作正常。我知道是什么导致了它-在第一
'ThisWorkbook'
'------------'
Option Explicit
Private Sub Workbook_Open()
ThisWorkbook.VBProject.References.AddFromGuid GUID:="{00020905-0000-0000-C000-000000000046}", Major:=0, Minor:=0
ThisWorkbook.VBProject.References.AddFromGuid GUID:="{00062FFF-0000-0000-C000-000000000046}", Major:=0, Minor:=0
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If IsEmpty(ThisWorkbook.VBProject.References.Item("Word")) = False Then
ThisWorkbook.VBProject.References.Remove ThisWorkbook.VBProject.References.Item("Word")
End If
If IsEmpty(ThisWorkbook.VBProject.References.Item("Outlook")) = False Then
ThisWorkbook.VBProject.References.Remove ThisWorkbook.VBProject.References.Item("Outlook")
End If
ActiveWorkbook.Save
Set wdAppClass = Nothing
Set wdAppClass.wdApp = Nothing
'Set wdApp = Nothing
Set wdDoc = Nothing
Set button = Nothing
End Sub
-
-
似乎在打开工作簿时首先编译模块和类模块。尝试在工作表中使用
Public with events wdApp作为Word.Application
,以便在工作簿打开后对其进行编译 打开工作簿时,似乎先编译模块和类模块。尝试在工作表中使用Public with events wdApp作为Word.Application
,以便在工作簿打开后对其进行编译 你好,伊茨莱克斯!谢谢你的快速回复。关于首先编译的模块和类模块,您似乎是对的,正因为如此,当我尝试您的建议将公共对象声明放在工作表上时,它才继续在类模块中标记子声明的第一行,并且出现了相同的错误。还有其他建议吗?如果你坚持在一个类中使用Word/Outlook项目,也许你可以在一个专用(非常隐藏)的工作表中定义整个类,用于此目的?如果只使用一个实例,可能会起作用。您的意思是完全摆脱wdappclass模块吗?我很抱歉,我担心我仍然在处理类和类模块。你介意再详细一点吗?也许可以用一个例子或伪代码等等?非常感谢。是的,去掉Module和Classmodule。但最重要的是,摆脱Sub AutoOpen()
。我知道,这需要重新编写应用程序的工作方式。通过将代码保存在工作表中,您可以进行调用,如Set Sheet9.wdApp=Word.Application
。祝你好运。itsLex非常感谢你的解决方案。您在工作表中隐藏classmodule代码的巧妙想法很有魅力!虽然我确实删除了模块和类模块,但我必须恢复模块,因为我需要一些公共变量和sub才能正常工作。我还从这个练习中了解到,即使在公开声明时,工作表甚至工作簿本身也无法“看到”彼此的代码。再次感谢你!你好,伊茨莱克斯!谢谢你的快速回复。关于首先编译的模块和类模块,您似乎是对的,正因为如此,当我尝试您的建议将公共对象声明放在工作表上时,它才继续在类模块中标记子声明的第一行,并且出现了相同的错误。还有其他建议吗?如果你坚持在一个类中使用Word/Outlook项目,也许你可以在一个专用(非常隐藏)的工作表中定义整个类,用于此目的?如果只使用一个实例,可能会起作用。您的意思是完全摆脱wdappclass模块吗?我很抱歉,我担心我仍然在处理类和类模块。你介意再详细一点吗?也许可以用一个例子或伪代码等等?非常感谢。是的,去掉Module和Classmodule。但最重要的是,摆脱Sub AutoOpen()
。我知道,这需要重新编写应用程序的工作方式。通过将代码保存在工作表中,您可以进行调用,如Set Sheet9.wdApp=Word.Application
。祝你好运。itsLex非常感谢你的解决方案。您在工作表中隐藏classmodule代码的巧妙想法很有魅力!虽然我确实删除了模块和类模块,但我必须恢复模块,因为我需要一些公共变量和sub才能正常工作。我还从这个练习中了解到,即使在公开声明时,工作表甚至工作簿本身也无法“看到”彼此的代码。再次感谢你!编辑以包含项目的完整代码。如果有人有空余时间,请随时测试。谢谢。已编辑以包含项目的完整代码。如果有人有空余时间,请随时测试。非常感谢。
'Module1'
'-------'
Option Explicit
Public wdAppClass As New wdAppClass
Public wdDoc As Word.Document
Public button As Object
Public row As Integer
Public column As Integer
Public Sub AutoOpen()
Set wdAppClass.wdApp = Word.Application
End Sub
Sub Button_Click()
Set wdAppClass.wdApp = Word.Application
Set button = ActiveSheet.Buttons(Application.Caller)
With button.TopLeftCell
row = .row
column = .column
End With
Set wdAppClass.wdApp = CreateObject("Word.Application")
Set wdDoc = wdAppClass.wdApp.Documents.Add(ThisWorkbook.Path & "\Sales Call Report.dotm")
With wdDoc
.Fields(3).Code.Text = " Quote " & """" & ActiveSheet.Range("A" & row & "").Text & """" & " "
.Fields(4).Code.Text = " Quote " & """" & ActiveSheet.Range("B" & row & "").Text & """" & " "
.Fields(5).Code.Text = " Quote " & """" & ActiveSheet.Range("C" & row & "").Text & """" & " "
.Fields(6).Code.Text = " Quote " & """" & ActiveSheet.Range("D" & row & "").Text & """" & " "
.Fields(7).Code.Text = " Quote " & """" & ActiveSheet.Range("E" & row & "").Text & """" & " "
.Fields(8).Code.Text = " Quote " & """" & ActiveSheet.Range("H" & row & "").Text & """" & " "
.Fields(9).Code.Text = " Quote " & """" & ActiveSheet.Range("J" & row & "").Text & """" & " "
.Shapes(1).TextFrame.TextRange.Text = ActiveSheet.Range("F" & row & "").Text
.Shapes(2).TextFrame.TextRange.Text = ActiveSheet.Range("K" & row & "").Text
'.Shapes(3).TextFrame.TextRange.Text = ActiveSheet.Range("M" & row & "").Text
End With
wdAppClass.wdApp.Selection.WholeStory
wdAppClass.wdApp.Selection.Fields.Update
wdAppClass.wdApp.Selection.Collapse
wdAppClass.wdApp.Visible = True
wdAppClass.wdApp.ActiveWindow.WindowState = wdWindowStateMaximize
wdAppClass.wdApp.ActiveWindow.SetFocus
wdAppClass.wdApp.Activate
End Sub
Sub Set_Reminder()
Dim olApp As Outlook.Application
Dim olAppt As Outlook.AppointmentItem
If button Is Nothing Then
Set button = ActiveSheet.Buttons(Application.Caller)
End If
With button.TopLeftCell
row = .row
column = .column
End With
On Error Resume Next
Set olApp = GetObject("", "Outlook.Application")
On Error GoTo 0
If olApp Is Nothing Then
On Error Resume Next
Set olApp = CreateObject("Outlook.Application")
On Error GoTo 0
If olApp Is Nothing Then
MsgBox "Outlook is not available!"
Exit Sub
End If
End If
Set olAppt = olApp.CreateItem(olAppointmentItem)
With olAppt
.Start = ThisWorkbook.ActiveSheet.Range("M" & row & "").Value & Chr(32) & Time()
.Duration = 15
.Subject = "Call " & ThisWorkbook.ActiveSheet.Range("D" & row & "").Value
.Location = ThisWorkbook.ActiveSheet.Range("A" & row & "").Value & Chr(44) & Chr(32) & ThisWorkbook.ActiveSheet.Range("C" & row & "").Value
.Save
.Display
End With
Set olApp = Nothing
Set olAppt = Nothing
Set button = Nothing
End Sub
'wdAppClass'
'----------'
Option Explicit
Public WithEvents wdApp As Word.Application
Private Sub wdApp_DocumentBeforeClose(ByVal Doc As Document, Cancel As Boolean)
Dim datecheck As Boolean
ThisWorkbook.ActiveSheet.Range("F" & row & "").Value = wdDoc.Shapes(1).TextFrame.TextRange.Text
ThisWorkbook.ActiveSheet.Range("K" & row & "").Value = wdDoc.Shapes(2).TextFrame.TextRange.Text
datecheck = IsDate(wdDoc.Shapes(3).TextFrame.TextRange.Text)
If datecheck = True Then
ThisWorkbook.ActiveSheet.Range("M" & row & "").Value = wdDoc.Shapes(3).TextFrame.TextRange.Text
Set_Reminder
End If
wdAppClass.wdApp.Quit
wdApp.Quit
wdDoc.Close
Set wdAppClass = Nothing
Set wdAppClass.wdApp = Nothing
Set wdApp = Nothing
Set wdDoc = Nothing
Set button = Nothing
End Sub