0

ExportTimeSheetsToDatabase() という名前のサブルーチンで Object Not Set エラー メッセージが表示されます。

フォローしてみてください:

  1. TimeSheetCollection は TimeSheet 型のコレクションです
  2. まず、TimeSheetCollection オブジェクトを設定するサブルーチン ReadWeeklyTimeSheets() を呼び出し、今日のメールアイテムを読み取り、メールアイテムの本文から取得した値から、各タイムシートのプロパティを設定します。わかりやすくするために、TimeSheet クラスの短縮バージョンを追加しました。
  3. 次に、ExportTimeSheetsToDatabase() という名前のサブルーチンが呼び出されます。Item.MondayStart プロパティと Item.MondayEnd プロパティでエラー メッセージが表示されるのは、ここの Debug.print ステートメントです。火曜日から金曜日までの他のすべてのプロパティを含めると、すべて同じエラー メッセージが表示されます。

エラーが発生する理由がまったくわかりません。サブルーチン 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 ステートメントで Item.MondayStart と Item.MondayEnd に Object Not Set というエラー メッセージが表示されます。他のプロパティは、Item.EmployeeID、Item.StartDate、Item.EndDate などの値を保持しています。しかし、それらはオブジェクトではありません。それらは単なるプリミティブ データ型です。私はあなたが問題を理解できることを願っています。なぜなら、私はこの木の上に森を見ることができないからです。

アラン

于 2012-12-27T22:47:00.203 に答える