Lotus 脚本文件已创建 属性 奇怪的行为
Lotus script document created property strange behavior
我目前正在使用 domino desginer 8.5.2,我遇到了一个与 notesdocument Created 属性.
有关的奇怪事情
我正在尝试在 lotusscript 中创建一个代理,它根据文档的创建日期选择一些文档。
我有以下测试代码,其中 doc 是特定 NotesDatabase 中的 NotesDocument:
If doc.Created < DateNumber(1951,1,1) Then
Print "old"
End If
问题是数据库中没有早于 2010 年的文档,但上面的代码为某些文档打印 "old"(例如 5k 中的 10 个),但是当我进入调试会话并检查时文档在变量 window 中创建 属性 这是正常日期,例如 2012.02.03. 或 smth.
另一个有趣的注意事项是,如果我尝试将创建日期写入 csv 文件,它是一个无意义的日期,例如 1896.06.20. 但是当我在调试时再次检查 属性 它是完全正常的.
您以前遇到过这个问题吗?还是我比较日期的方式不对?
----EDIT1------------
我把问题简单化了,如果误导了我真的很抱歉我只能谦虚地请你保持想法,因为解决这个问题至关重要。
有问题的代理不处理它自己的文档,它在服务器上打开多个数据库(很多人的邮件数据库)并根据多种条件处理文档(电子邮件)。我们实际做的是这样的:
strFileName = "D:\temp\log.csv"
Set nStream = session.CreateStream()
nStream.Open(strFileName)
nStream.Truncate
Dim deleteCutoffDate As New NotesDateTime("Today")
Dim moveCutoffDate As New NotesDateTime("Today")
Dim tmp As Integer
tmp = settingsDto.GetDeleteOlderThanMonths()
Call deleteCutoffDate.Adjustmonth((-1)*tmp, True)
searchForm$ = {Form = "Memo" }
Set doccol = db.Search(searchForm, Nothing, 0) 'db is an opened NotesDatabase
Set doc = doccol.GetFirstDocument
While Not doc Is Nothing
Dim nextDoc As NotesDocument
Set nextDoc = doccol.Getnextdocument(doc)
'Earlier condition we tried
'If doc.Created < deleteCutOffDate.Lslocaltime
' deleteCutoffDate is today - 3 years
If (Fix( doc.Created ) < Fix( CDat(deleteCutoffDate.Dateonly))) Then
'Suggested solution to check dates
Dim longTemp As Long
longTemp = Fix( CDat(deleteCutoffDate.Dateonly)) 'should be 36,647 (#days from Dec 30, 1899 to May 1, 2000)
longTemp = Fix( doc.Created ) 'check this number makes sense (see last line)!
'This is only for logging, testing.
Dim temp As String
temp = Format( doc.Created, "yyyy-mm-dd")+";"+doc.Noteid+";"
Call nStream.WriteText(temp,EOL_PLATFORM)
'******* Processing logic goes here **********
End If
Set doc = nextDoc
Wend
Call nStream.Close()
到目前为止我看到的问题和症状:
有些文件(总是一样的)有奇怪的创建日期。假设我们有 3 个文档 A、B、C。
当我将文档 A 的 Created 属性 写入 csv 时,它说 1899-12-30 当我检查调试器时 doc.Created 是 2015-01-06 这是正确的日期但是 Fix( doc.Created ) 为 0。这没有意义。这应该不会通过 if 条件并根据 Fix beeing 0 写入 csv 但确实如此。
文档 B 在 csv 中的日期是 1899,调试器说是 2015-10-25,Fix(doc.Created) 报告了正确的数字但是这个文档不应该通过 If 条件,因为 if 只允许通过早于3年,从今天开始。因此,如果我 运行 在 15-02-07 之前创建的 '18-02-07 文档上的脚本应该通过条件。
文件C的日期是4916-04-18,其他同上
这些问题出现在多个(但总是在同一个)文档中。但这些不是特殊文件或任何东西,它们是简单的电子邮件
我注意到的另一件事是,如果我连续多次 运行 脚本(没有调试或干扰),有时 CSV 会报告正确的日期!对我来说,这暗示了某种参考问题,但此时我不确定世界是如何运作的。
注意这里没有涉及其他处理逻辑,If条件里面所有操作文档的逻辑都被注释掉了。测试数据库已经恢复到原来的状态
如果您有任何想法,请不要犹豫,我已经在这个问题上停留了好几天了。
谢谢
看起来你正在尝试做的事情应该可以正常工作。我认为创建日期来自文档通用 ID 的一部分,因此如果以编程方式设置它,则可能会看到创建日期看起来很旧的文档。
我建议您尝试以下操作,看看您是否能找出问题所在
dim longTemp as long
dateTemp = cdat( "May 1, 2000" )
longTemp = Fix( dateTemp ) 'should be 36,647 (#days from Dec 30, 1899 to May 1, 2000)
longTemp = Fix( doc.Created ) 'check this number makes sense (see last line)!
If doc.Created < dateTemp then
print "old"
end if
重新将 doc.created 写入 csv 文件,我建议在写入前将其格式化为文本,因此
format( doc.created, "yyyy-mm-dd") 'or your preferred date format
我放弃了。是时候下注并提出解决方法了!这些可能有用吗?
解决方法 1:公式
代替 if 块,在 doccol
的搜索公式中构建日期条件。无论如何,这可能更快。
strFileName = "D:\temp\log.csv"
Set nStream = session.CreateStream()
nStream.Open(strFileName)
nStream.Truncate
Dim deleteCutoffDate As New NotesDateTime("Today")
Dim moveCutoffDate As New NotesDateTime("Today")
Dim tmp As Integer
tmp = settingsDto.GetDeleteOlderThanMonths()
Call deleteCutoffDate.Adjustmonth((-1)*tmp, True)
searchForm$ = {Form = "Memo" & @Created < [} + deleteCutoffDate.LocalTime + {]} '<--- removed if block and put criteria checking here
Set doccol = db.Search(searchForm, Nothing, 0) 'db is an opened NotesDatabase
Set doc = doccol.GetFirstDocument
While Not doc Is Nothing
Dim nextDoc As NotesDocument
Set nextDoc = doccol.Getnextdocument(doc)
'Earlier condition we tried
'If doc.Created < deleteCutOffDate.Lslocaltime
' deleteCutoffDate is today - 3 years
'Suggested solution to check dates
Dim longTemp As Long
longTemp = Fix( CDat(deleteCutoffDate.Dateonly)) 'should be 36,647 (#days from Dec 30, 1899 to May 1, 2000)
longTemp = Fix( doc.Created ) 'check this number makes sense (see last line)!
'This is only for logging, testing.
Dim temp As String
temp = Format( doc.Created, "yyyy-mm-dd")+";"+doc.Noteid+";"
Call nStream.WriteText(temp,EOL_PLATFORM)
'******* Processing logic goes here **********
Set doc = nextDoc
Wend
Call nStream.Close()
解决方法 2:通过 NotesDateTime 过滤?
也许这行得通?
strFileName = "D:\temp\log.csv"
Set nStream = session.CreateStream()
nStream.Open(strFileName)
nStream.Truncate
Dim deleteCutoffDate As New NotesDateTime("Today")
Dim moveCutoffDate As New NotesDateTime("Today")
Dim createdDate As NotesDateTime '<----
Dim tmp As Integer
tmp = settingsDto.GetDeleteOlderThanMonths()
Call deleteCutoffDate.Adjustmonth((-1)*tmp, True)
Call deleteCutoffDate.SetAnyTime '<----
searchForm$ = {Form = "Memo" }
Set doccol = db.Search(searchForm, Nothing, 0) 'db is an opened NotesDatabase
Set doc = doccol.GetFirstDocument
While Not doc Is Nothing
Dim nextDoc As NotesDocument
Set nextDoc = doccol.Getnextdocument(doc)
'Earlier condition we tried
'If doc.Created < deleteCutOffDate.Lslocaltime
' deleteCutoffDate is today - 3 years
'Your current condition
'If (Fix( doc.Created ) < Fix( CDat(deleteCutoffDate.Dateonly))) Then
Set createdDate = New NotesDateTime(doc.Created) '<----
Call createdDate.SetAnyTime '<----
If createdDate.TimeDifference(deleteCutoffDate) < 0 Then '<----
'Suggested solution to check dates
Dim longTemp As Long
longTemp = Fix( CDat(deleteCutoffDate.Dateonly)) 'should be 36,647 (#days from Dec 30, 1899 to May 1, 2000)
longTemp = Fix( doc.Created ) 'check this number makes sense (see last line)!
'This is only for logging, testing.
Dim temp As String
temp = Format( doc.Created, "yyyy-mm-dd")+";"+doc.Noteid+";"
Call nStream.WriteText(temp,EOL_PLATFORM)
'******* Processing logic goes here **********
End If
Set doc = nextDoc
Wend
Call nStream.Close()
解决方法 3:健全过滤器
添加一个函数,在 LotusScript 失败时检查并使用 @Formulas,因为虽然速度较慢,但希望它能起作用
Function fdtSaneDocCreated(doc As NotesDocument) As Variant 'Dateonly
Const ciMinDate = 40179 'CLng(CDat("1/1/2010"))
Const ciMaxDate = 51136 'CLng(CDat("1/1/2040"))
fdtSaneDocCreated = doc.Created
If fdtSaneDocCreated < ciMinDate Or fdtSaneDocCreated > ciMaxDate Then
'This is slower, but AT LEAST IT WORKS! (... hopefully)
Dim array As Variant
array = Evaluate({@Created}, doc)
fdtSaneDocCreated = array(0)
If fdtSaneDocCreated < ciMinDate Or fdtSaneDocCreated > ciMaxDate Then
Error 1, "This workaround doesn't work for " + doc.NotesURL
End If
End If
End Function
然后更改您的代码,将 doc.Created
替换为 fdtSaneDocCreated(doc)
抱歉让我沉默了很久,我真的需要赶上这个项目。
首先感谢大家对这个话题的贡献,你们所有的回答都为图片添加了拼图。
所以问题是 doc.Created 报告了错误的日期。根据您的帖子,我将以下文档标记为红色。
http://www-01.ibm.com/support/docview.wss?uid=swg21111786
根据上面的 link,文档创建日期由 OID 确定。
此 link 解释了 OID 的工作原理及其外观。
我用 NotesPeek 和宾果检查了 OID! OID 应该包含有效日期,但它完全是乱码,如 9856.06.20。有时日期部分只是丢失了,这就是我看到 1899 的原因。
此问题的结束点如下link,确认此奇怪行为是 Notes 8.5.1 的错误
我目前正在使用 domino desginer 8.5.2,我遇到了一个与 notesdocument Created 属性.
有关的奇怪事情我正在尝试在 lotusscript 中创建一个代理,它根据文档的创建日期选择一些文档。
我有以下测试代码,其中 doc 是特定 NotesDatabase 中的 NotesDocument:
If doc.Created < DateNumber(1951,1,1) Then
Print "old"
End If
问题是数据库中没有早于 2010 年的文档,但上面的代码为某些文档打印 "old"(例如 5k 中的 10 个),但是当我进入调试会话并检查时文档在变量 window 中创建 属性 这是正常日期,例如 2012.02.03. 或 smth.
另一个有趣的注意事项是,如果我尝试将创建日期写入 csv 文件,它是一个无意义的日期,例如 1896.06.20. 但是当我在调试时再次检查 属性 它是完全正常的.
您以前遇到过这个问题吗?还是我比较日期的方式不对?
----EDIT1------------
我把问题简单化了,如果误导了我真的很抱歉我只能谦虚地请你保持想法,因为解决这个问题至关重要。
有问题的代理不处理它自己的文档,它在服务器上打开多个数据库(很多人的邮件数据库)并根据多种条件处理文档(电子邮件)。我们实际做的是这样的:
strFileName = "D:\temp\log.csv"
Set nStream = session.CreateStream()
nStream.Open(strFileName)
nStream.Truncate
Dim deleteCutoffDate As New NotesDateTime("Today")
Dim moveCutoffDate As New NotesDateTime("Today")
Dim tmp As Integer
tmp = settingsDto.GetDeleteOlderThanMonths()
Call deleteCutoffDate.Adjustmonth((-1)*tmp, True)
searchForm$ = {Form = "Memo" }
Set doccol = db.Search(searchForm, Nothing, 0) 'db is an opened NotesDatabase
Set doc = doccol.GetFirstDocument
While Not doc Is Nothing
Dim nextDoc As NotesDocument
Set nextDoc = doccol.Getnextdocument(doc)
'Earlier condition we tried
'If doc.Created < deleteCutOffDate.Lslocaltime
' deleteCutoffDate is today - 3 years
If (Fix( doc.Created ) < Fix( CDat(deleteCutoffDate.Dateonly))) Then
'Suggested solution to check dates
Dim longTemp As Long
longTemp = Fix( CDat(deleteCutoffDate.Dateonly)) 'should be 36,647 (#days from Dec 30, 1899 to May 1, 2000)
longTemp = Fix( doc.Created ) 'check this number makes sense (see last line)!
'This is only for logging, testing.
Dim temp As String
temp = Format( doc.Created, "yyyy-mm-dd")+";"+doc.Noteid+";"
Call nStream.WriteText(temp,EOL_PLATFORM)
'******* Processing logic goes here **********
End If
Set doc = nextDoc
Wend
Call nStream.Close()
到目前为止我看到的问题和症状:
有些文件(总是一样的)有奇怪的创建日期。假设我们有 3 个文档 A、B、C。
当我将文档 A 的 Created 属性 写入 csv 时,它说 1899-12-30 当我检查调试器时 doc.Created 是 2015-01-06 这是正确的日期但是 Fix( doc.Created ) 为 0。这没有意义。这应该不会通过 if 条件并根据 Fix beeing 0 写入 csv 但确实如此。
文档 B 在 csv 中的日期是 1899,调试器说是 2015-10-25,Fix(doc.Created) 报告了正确的数字但是这个文档不应该通过 If 条件,因为 if 只允许通过早于3年,从今天开始。因此,如果我 运行 在 15-02-07 之前创建的 '18-02-07 文档上的脚本应该通过条件。
文件C的日期是4916-04-18,其他同上
这些问题出现在多个(但总是在同一个)文档中。但这些不是特殊文件或任何东西,它们是简单的电子邮件
我注意到的另一件事是,如果我连续多次 运行 脚本(没有调试或干扰),有时 CSV 会报告正确的日期!对我来说,这暗示了某种参考问题,但此时我不确定世界是如何运作的。
注意这里没有涉及其他处理逻辑,If条件里面所有操作文档的逻辑都被注释掉了。测试数据库已经恢复到原来的状态
如果您有任何想法,请不要犹豫,我已经在这个问题上停留了好几天了。
谢谢
看起来你正在尝试做的事情应该可以正常工作。我认为创建日期来自文档通用 ID 的一部分,因此如果以编程方式设置它,则可能会看到创建日期看起来很旧的文档。
我建议您尝试以下操作,看看您是否能找出问题所在
dim longTemp as long
dateTemp = cdat( "May 1, 2000" )
longTemp = Fix( dateTemp ) 'should be 36,647 (#days from Dec 30, 1899 to May 1, 2000)
longTemp = Fix( doc.Created ) 'check this number makes sense (see last line)!
If doc.Created < dateTemp then
print "old"
end if
重新将 doc.created 写入 csv 文件,我建议在写入前将其格式化为文本,因此
format( doc.created, "yyyy-mm-dd") 'or your preferred date format
我放弃了。是时候下注并提出解决方法了!这些可能有用吗?
解决方法 1:公式
代替 if 块,在 doccol
的搜索公式中构建日期条件。无论如何,这可能更快。
strFileName = "D:\temp\log.csv"
Set nStream = session.CreateStream()
nStream.Open(strFileName)
nStream.Truncate
Dim deleteCutoffDate As New NotesDateTime("Today")
Dim moveCutoffDate As New NotesDateTime("Today")
Dim tmp As Integer
tmp = settingsDto.GetDeleteOlderThanMonths()
Call deleteCutoffDate.Adjustmonth((-1)*tmp, True)
searchForm$ = {Form = "Memo" & @Created < [} + deleteCutoffDate.LocalTime + {]} '<--- removed if block and put criteria checking here
Set doccol = db.Search(searchForm, Nothing, 0) 'db is an opened NotesDatabase
Set doc = doccol.GetFirstDocument
While Not doc Is Nothing
Dim nextDoc As NotesDocument
Set nextDoc = doccol.Getnextdocument(doc)
'Earlier condition we tried
'If doc.Created < deleteCutOffDate.Lslocaltime
' deleteCutoffDate is today - 3 years
'Suggested solution to check dates
Dim longTemp As Long
longTemp = Fix( CDat(deleteCutoffDate.Dateonly)) 'should be 36,647 (#days from Dec 30, 1899 to May 1, 2000)
longTemp = Fix( doc.Created ) 'check this number makes sense (see last line)!
'This is only for logging, testing.
Dim temp As String
temp = Format( doc.Created, "yyyy-mm-dd")+";"+doc.Noteid+";"
Call nStream.WriteText(temp,EOL_PLATFORM)
'******* Processing logic goes here **********
Set doc = nextDoc
Wend
Call nStream.Close()
解决方法 2:通过 NotesDateTime 过滤?
也许这行得通?
strFileName = "D:\temp\log.csv"
Set nStream = session.CreateStream()
nStream.Open(strFileName)
nStream.Truncate
Dim deleteCutoffDate As New NotesDateTime("Today")
Dim moveCutoffDate As New NotesDateTime("Today")
Dim createdDate As NotesDateTime '<----
Dim tmp As Integer
tmp = settingsDto.GetDeleteOlderThanMonths()
Call deleteCutoffDate.Adjustmonth((-1)*tmp, True)
Call deleteCutoffDate.SetAnyTime '<----
searchForm$ = {Form = "Memo" }
Set doccol = db.Search(searchForm, Nothing, 0) 'db is an opened NotesDatabase
Set doc = doccol.GetFirstDocument
While Not doc Is Nothing
Dim nextDoc As NotesDocument
Set nextDoc = doccol.Getnextdocument(doc)
'Earlier condition we tried
'If doc.Created < deleteCutOffDate.Lslocaltime
' deleteCutoffDate is today - 3 years
'Your current condition
'If (Fix( doc.Created ) < Fix( CDat(deleteCutoffDate.Dateonly))) Then
Set createdDate = New NotesDateTime(doc.Created) '<----
Call createdDate.SetAnyTime '<----
If createdDate.TimeDifference(deleteCutoffDate) < 0 Then '<----
'Suggested solution to check dates
Dim longTemp As Long
longTemp = Fix( CDat(deleteCutoffDate.Dateonly)) 'should be 36,647 (#days from Dec 30, 1899 to May 1, 2000)
longTemp = Fix( doc.Created ) 'check this number makes sense (see last line)!
'This is only for logging, testing.
Dim temp As String
temp = Format( doc.Created, "yyyy-mm-dd")+";"+doc.Noteid+";"
Call nStream.WriteText(temp,EOL_PLATFORM)
'******* Processing logic goes here **********
End If
Set doc = nextDoc
Wend
Call nStream.Close()
解决方法 3:健全过滤器
添加一个函数,在 LotusScript 失败时检查并使用 @Formulas,因为虽然速度较慢,但希望它能起作用
Function fdtSaneDocCreated(doc As NotesDocument) As Variant 'Dateonly
Const ciMinDate = 40179 'CLng(CDat("1/1/2010"))
Const ciMaxDate = 51136 'CLng(CDat("1/1/2040"))
fdtSaneDocCreated = doc.Created
If fdtSaneDocCreated < ciMinDate Or fdtSaneDocCreated > ciMaxDate Then
'This is slower, but AT LEAST IT WORKS! (... hopefully)
Dim array As Variant
array = Evaluate({@Created}, doc)
fdtSaneDocCreated = array(0)
If fdtSaneDocCreated < ciMinDate Or fdtSaneDocCreated > ciMaxDate Then
Error 1, "This workaround doesn't work for " + doc.NotesURL
End If
End If
End Function
然后更改您的代码,将 doc.Created
替换为 fdtSaneDocCreated(doc)
抱歉让我沉默了很久,我真的需要赶上这个项目。
首先感谢大家对这个话题的贡献,你们所有的回答都为图片添加了拼图。
所以问题是 doc.Created 报告了错误的日期。根据您的帖子,我将以下文档标记为红色。
http://www-01.ibm.com/support/docview.wss?uid=swg21111786
根据上面的 link,文档创建日期由 OID 确定。
此 link 解释了 OID 的工作原理及其外观。
我用 NotesPeek 和宾果检查了 OID! OID 应该包含有效日期,但它完全是乱码,如 9856.06.20。有时日期部分只是丢失了,这就是我看到 1899 的原因。
此问题的结束点如下link,确认此奇怪行为是 Notes 8.5.1 的错误