2012-12-26 34 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