0

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

尝试跟随:

  1. TimeSheetCollection 是 TimeSheet 类型的集合
  2. 首先,我调用子例程 ReadWeeklyTimeSheets(),它设置 TimeSheetCollection 对象,读取今天的邮件项,并根据从邮件项正文中获得的值设置每个 TimeSheet 中的属性。为了清楚起见,我添加了 TimeSheet 类的缩短版本。
  3. 接下来,调用名为 ExportTimeSheetsToDatabase() 的子例程。在 Debug.print 语句中,我收到有关 Item.MondayStart 和 Item.MondayEnd 属性的错误消息。如果我在周二到周五包括所有其他属性,他们都会抱怨相同的错误消息。

我不明白为什么我会收到错误!在子例程 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

 __________________________
4

1 回答 1

1

好的。所以我进入了 Class Module 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

为了防止在分配值时出现另一个“对象未设置”错误消息,我不得不再次使用 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 语句中收到错误消息 Object Not Set on Item.MondayStart 和 Item.MondayEnd。其他属性保存它们的值,如 Item.EmployeeID、Item.StartDate 和 Item.EndDate。但它们不是对象。它们只是原始数据类型。我希望你能看到问题,因为我在这棵树上看不到森林。

艾伦

于 2012-12-27T22:47:00.203 回答