2012-12-26 32 views
0

我在名为ExportTimeSheetsToDatabase()的子例程中收到对象未设置错误消息。对象变量未设置错误 - 但它是

尝试沿遵循:

  1. 的TimeSheetCollection是类型的TimeSheet
  2. 首先我调用子程序ReadWeeklyTimeSheets(),其设置TimeSheetCollection对象的集合,读取在今天mailitems,并从这些值中获得的从mailitem的主体中,我们在每个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 

__________________________ 
+0

该代码看起来很健全。你确定你没有意外地在你的集合中获得除时间表对象之外的东西吗?如果您在ExportTimeSheeteToDatabase中插入断点并检查TimeSheetsCollection对象,您确定它是一个集合并且它是否包含项目? –

回答

1

确定。于是我走进了类模块的TimeSheet和改变了所有的设属性来设置,比如:

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 MonStart = New TimeFrame 
MonStart.Initialize = Item.Value 
Set tsheet.MondayStart = MonStart '<<<Had to use Set here too. Is that normal??? 

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

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

Alan

+0

嗨阿兰,是的,这是正常的VBA(Visual C++太可能),复杂数据类型使用赋值设定关键字。 – Pynner