对象变量未设置错误 - 但它是

时间:2012-12-26 17:01:47

标签: vba outlook-vba

我在名为ExportTimeSheetsToDatabase()的子例程中收到Object Not Set Error消息。

尝试跟随:

  1. TimeSheetCollection是TimeSheet类型的集合
  2. 首先,我调用子程序ReadWeeklyTimeSheets(),它设置TimeSheetCollection对象,读取今天的邮件项目,并从我们在每个TimeSheet中设置属性的mailitem主体获取的值。为清晰起见,我添加了缩短版的TimeSheet类。
  3. 接下来,调用名为ExportTimeSheetsToDatabase()的子例程。在Debug.print语句中,我在Item.MondayStart和Item.MondayEnd属性上收到错误消息。如果我要在周二到周五包括所有其他属性,他们都会抱怨相同的错误消息。
  4. 我不明白为什么我得到错误!在子程序ReadWeeklyTimeSheets()中,我正在进行调用:tsheet.MondayStart = MonStart

    在类TimeSheet中,pMonStart的属性设置为:

    Public Property Let MondayStart(Value As TimeFrame)
      Set pMonStart = Value
    End Property
    

    所以我知道它正在被设定。为什么它在ExportTimeSheetsToDatabase()子例程中我收到此错误?您将在子例程ReadWeeklyTimeSheets()中注意到我执行调用tsheet.ToString的Debug.print语句。这样就可以打印出tsheet中的所有属性。当我在ExportTimeSheetsToDatabase()子例程中调用Debug.print时,我正在访问集合中的同一个TimeSheet对象。

    请指教,

    艾伦

    'Global variable
    Public TimeSheetCollection As Collection
    ...
    Sub ReadWeeklyTimeSheets()
      Dim tsheet As TimeSheet
      Dim kvPairs As Collection
      ...
      Set TimeSheetCollection = New Collection
      Dim DefaultTF As TimeFrame
      'set the default TimeFrame
      Set DefaultTF = New TimeFrame
      DefaultTF.Initialize = "00:00"
      ...
      For Each oitem In ItemsToProcess
        If TypeName(oitem) = "MailItem" Then
         Set myMailItem = oitem
         Debug.Print "Subject: " & myMailItem.Subject
         If CheckSubject(myMailItem.Subject, TimeSheetSubjectTitle) Then
           Set kvPairs = GetTimeSheetKeyValuePairs(myMailItem.body)
           'Iterate over the Collection and load up
           'an instance of TimeSheet object
           Set tsheet = New TimeSheet
           For Each Item In kvPairs
    
             If LCase(Item.Key) = LCase("EmployeeID") Then
               tsheet.EmployeeID = Item.Value
             ElseIf LCase(Item.Key) = LCase("StartDate(DD/MM/YYYY)") Then
                tsheet.StartDate = CDate(Item.Value)
             ElseIf LCase(Item.Key) = LCase("EndDate(DD/MM/YYYY)") Then
                tsheet.EndDate = CDate(Item.Value)
             ElseIf LCase(Item.Key) = LCase("MonStart") Then
                If Item.Value <> "" Then
                  Set MonStart = New TimeFrame
                  MonStart.Initialize = Item.Value
                  tsheet.MondayStart = MonStart  '<<<Calling this sets the object in the TimeSheet
                Else
                  tsheet.MondayStart = DefaultTF
                End If
             ElseIf LCase(Item.Key) = LCase("MonEnd") Then
                 If Item.Value <> "" Then
                 Set MonEnd = New TimeFrame
                 MonEnd.Initialize = Item.Value
                 tsheet.MondayEnd = MonEnd  '<<<Calling this sets the object in the TimeSheet
             Else
                 tsheet.MondayEnd = DefaultTF
             End If
           ElseIf ... 'And so on thru to Friday
    
           End If
          Next Item
    
          'Add each Time Sheet object to the TimeSheetCollection
          TimeSheetCollection.Add tsheet
    
          Debug.Print tsheet.ToString  '<<<The TimeSheet object prints everything just fine
        End If
       End If
     Next oitem     
    End Sub
    
    _______________________________
    
    Sub ExportTimeSheetsToDatabase()
      Dim Item As TimeSheet
      Dim strInsertQuery As String
    
      'Iterate over the collection to obtain each TimeSheet object
      'and insert the data from each as a new record into the database
      For Each Item In TimeSheetCollection
       'THIS DEBUG STATEMENT IS WHERE I GET THE ERROR OBJECT NOT SET
       'ON Item.MondayStart and Item.MondayEnd
       Debug.Print Item.EmployeeID & ", " & Item.StartDate & ", " & Item.EndDate & "," & Item.MondayStart & "," & Item.MondayEnd & ", Toal Hours: " & Item.TotalWeeklyHours
      Next Item
    
     End Sub
    _______________________________
    'CLASS MODULE TIMESHEET
    Private pEmployeeID As Integer
    Private pStartDate As Date
    Private pEndDate As Date
    Private pMonStart As TimeFrame
    Private pMonEnd As TimeFrame
    Private pMonBreak As Double
    Private pTuesStart As TimeFrame
    Private pTuesEnd As TimeFrame
    Private pTuesBreak As Double
    Private pWedStart As TimeFrame
    Private pWedEnd As TimeFrame
    Private pWedBreak As Double
    Private pThursStart As TimeFrame
    Private pThursEnd As TimeFrame
    Private pThursBreak As Double
    Private pFriStart As TimeFrame
    Private pFriEnd As TimeFrame
    Private pFriBreak As Double
    Public Property Get EmployeeID() As Integer
       EmployeeID = pEmployeeID
    End Property
    Public Property Let EmployeeID(Value As Integer)
       If Value > 0 Then
           pEmployeeID = Value
       Else
         MsgBox "Employee ID " & Value & " is an incorrect value." & vbCrLf & "Employee ID must be a positive integer"
       End If
    
    End Property
    Public Property Get StartDate() As Date
     StartDate = pStartDate
    End Property
    Public Property Let StartDate(Value As Date)
     pStartDate = Value
    End Property
    Public Property Get EndDate() As Date
     EndDate = pEndDate
    End Property
    Public Property Let EndDate(Value As Date)
     pEndDate = Value
    End Property
    Public Property Get MondayStart() As TimeFrame
     MondayStart = pMonStart
    End Property
    Public Property Let MondayStart(Value As TimeFrame)
      Set pMonStart = Value
    End Property
    Public Property Get MondayEnd() As TimeFrame
     MondayEnd = pMonStart
    End Property
    Public Property Let MondayEnd(Value As TimeFrame)
     Set pMonEnd = Value
    End Property
    Public Property Get MondayBreak() As Double
      MondayBreak = pMonBreak
    End Property
    
    ...
    
    Public Property Get ToString() As String
       ToString = "EmployeeID = " & CStr(pEmployeeID) & vbCrLf & _
               "StartDate = " & CStr(pStartDate) & vbCrLf & _
               "EndDate = " & CStr(pEndDate) & vbCrLf & _
               "MondayStart = " & pMonStart.ToString & vbCrLf & _
               "MondayEnd = " & pMonEnd.ToString & vbCrLf & _
               "MondayBreak = " & CStr(pMonBreak) & vbCrLf & _
               "TuesdayStart = " & pTuesStart.ToString & vbCrLf & _
               "TuesdayEnd = " & pTuesEnd.ToString & vbCrLf & _
               "TuesdayBreak = " & CStr(pTuesBreak) & vbCrLf & _
               "WednesdayStart = " & pWedStart.ToString & vbCrLf & _
               "WednesdayEnd = " & pWedEnd.ToString & vbCrLf & _
               "WednesdayBreak = " & CStr(pWedBreak) & vbCrLf & _
               "ThursdayStart = " & pThursStart.ToString & vbCrLf & _
               "ThursdayEnd = " & pThursEnd.ToString & vbCrLf & _
               "ThursdayBreak = " & CStr(pThursBreak) & vbCrLf & _
               "FridayStart = " & pFriStart.ToString & vbCrLf & _
               "FridayEnd = " & pFriEnd.ToString & vbCrLf & _
               "FridayBreak = " & CStr(pFriBreak)
    End Property
    
     __________________________
    

1 个答案:

答案 0 :(得分:1)

行。所以我进入了类模块TimeSheet并将所有Let属性更改为Set,如下所示:

Public Property Set MondayStart(ByRef Value As TimeFrame)
  Set pMonStart = Value
End Property

Public Property Set MondayEnd(ByRef Value As TimeFrame)
  Set pMonEnd = Value
End Property

Public Property Set TuesdayStart(ByRef Value As TimeFrame)
  Set pTuesStart = Value
End Property

Public Property Set TuesdayEnd(ByRef Value As TimeFrame)
  Set pTuesEnd = Value
End Property

 ... 'and so on

为了防止在分配值时出现另一个“Object Not Set”错误消息,我不得不再次使用Set关键字:

 Set MonStart = New TimeFrame
 MonStart.Initialize = Item.Value
 Set tsheet.MondayStart = MonStart  '<<<Had to use Set here too. Is that normal???

这是正常的吗?我觉得我们在属性声明中使用Set关键字和属性的主体似乎是多余的,然后在为属性赋值时也必须使用它!

设置完所有属性后,我调用子例程ExportTimeSheetsToDatabase(),我仍然在Debug.println语句的Item.MondayStart和Item.MondayEnd上收到错误消息Object Not Set。其他属性保存其值,如Item.EmployeeID,Item.StartDate和Item.EndDate。但那时它们不是对象。它们只是原始数据类型。我希望你能看到这个问题,因为我看不到森林中的树木。

艾伦