【问题标题】:Lotus script document created property strange behaviorLotus 脚本文档创建的属性奇怪行为
【发布时间】:2018-02-05 12:33:34
【问题描述】:

我目前正在使用 domino desginer 8.5.2,遇到了一个与 notesdocument Created 属性相关的奇怪事情。

我正在尝试在 lotusscript 中创建一个代理,它根据创建日期选择一些文档。

我有以下测试代码,其中 doc 是特定 NotesDatabase 中的 NotesDocument:

If doc.Created < DateNumber(1951,1,1) Then
    Print "old"
End If

问题是数据库中没有早于 2010 年的文档,但上面的代码为某些文档打印“旧”(例如 5k 中的 10 个),但是当我进入调试会话并检查文档的 Created 属性时在“变量”窗口中,这是一个正常的日期,例如 2012. 02. 03. 或 smth。

另一个有趣的注意事项是,如果我尝试将 Created 日期写入 csv 文件,这是一个无意义的日期,例如 1896. 06. 20. 但是当我在调试时检查属性时又是完全正常的。

您以前遇到过这个问题吗?还是我比较日期的方式有误?

----EDIT1------------

我把问题简单化了,如果有误导性,我真的很抱歉,我只能谦虚地请你保持这些想法,因为解决这个问题至关重要。

有问题的代理不处理自己的文档,它在服务器上打开多个数据库(很多 ppl 的邮件数据库)并按多个条件处理文档(电子邮件)。我们实际上做的是这样的:

    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 beeeing 0 写入 csv。

文档 B 在 csv 中的日期是 1899,调试器说 2015-10-25,Fix( doc.Created ) 报告了正确的数字但是这个文档不应该经历 If 条件,因为 if 只允许超过 3 年的文档通过从今天开始。因此,如果我在 07 年 2 月 15 日之前创建的 '18-02-07 文档上运行脚本应该通过条件。

文档 C 的日期是 4916-04-18 其他都同上
这些问题出现在多个(但总是在相同的)文档上。但这些不是特殊文件或任何东西,它们只是简单的电子邮件

我注意到的另一件事是,如果我连续多次运行脚本(没有调试或干扰),有时 CSV 会报告正确的日期!对我来说,这暗示了某种参考问题,但在这一点上,我不确定世界是如何运作的。

注意这里不涉及其他处理逻辑,If 条件中的所有操作文档的逻辑都被注释掉了。测试数据库已恢复到原始状态

如果您有任何想法,请不要犹豫,我已经被这个问题困扰了好几天了。

谢谢

【问题讨论】:

  • 这是奇怪的行为。我当然没见过。根据 IBM Docs,您正在正确比较日期。也就是说,我很久以前就放弃了 .Created 作为标准,因为如果您复制/粘贴旧文档(或者如果复制出错),新文档会获得新的 Created 日期。我更喜欢创建自己的“已创建”日期字段,这样我就可以控制它的内容和存储方式。
  • IIRC,有一个保留的字段名称——可能是“$created”,但我的记忆不是 100%——它会覆盖文档的实际 Created 属性,并将由 NotesDocument.Created 返回。我建议查看 doc 属性框,看看是否有 $created 值或其他任何看起来可能会被覆盖的东西。我怀疑有一个,并且它的值不正确或数据类型错误,
  • @Duston 谢谢,我以后会记住这一点,但这是一个相当大的项目,我无法控制文档上的哪些字段
  • @RichardSchwartz 感谢您的建议,我没有发现任何看起来可疑的字段

标签: lotus-notes lotus-domino lotusscript lotus


【解决方案1】:

看起来您正在尝试做的事情应该可以正常工作。我认为创建日期来自文档通用 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

【讨论】:

  • 我听从了你的建议,得到了一些有趣的结果。我在将文档写入文件之前格式化了 doc.Created,现在我看到创建日期为 1899-12-30,但问题仍然存在。我已将条件更改为使用“固定”数字,但结果很混乱。当我在 1899 年文档之一上的已创建道具上使用修复功能时,它显示了正确的值,它应该是 40.000 天,但在另一个“错误”文件显示 0 天。奇怪的。对于我们在 csv 中看到 1899 但在 Fix 中正确的文档,还有一个条件,例如 If Fix (doc.Created)
  • 这是一个令人费解的问题。您可以粘贴其中一个“坏”文档的 UniversalID。创建日期嵌入在 unid 的最右侧,因此我们应该检查一件事是否可行。
  • 如果事实证明通用 id 没问题,那么 Richard 上面关于文档上的 '$Created' 字段的建议值得仔细检查,如果你在 doc 属性中看不到它然后查看调试器中的文档项,或者使用 NotesPeek。我要做的另一件事是将坏文档复制到另一个测试数据库,看看是否有问题,你可以尝试a)复制和粘贴,b)notesDocument.CopyToDatabase(yourTestNotesDatabase)第二个应该保留一部分统一的
【解决方案2】:

我放弃了。是时候下注并提出解决方法了!这些都行吗?

解决方法 1:公式

doccol 的搜索公式中构建日期条件,而不是 if 块。无论如何,这可能会更快。

    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) 来更改您的代码

【讨论】:

    【解决方案3】:

    很抱歉,我真的需要赶上这个项目。

    首先感谢大家为本主题的贡献,您的所有答案都为图片添加了拼图。

    所以问题是 doc.Created 报告了错误的日期。根据您的帖子,我将以下文档标记为红色。

    http://www-01.ibm.com/support/docview.wss?uid=swg21111786

    根据上面的链接一个文档的创建日期是由OID决定的。

    所以有这样的: http://www-12.lotus.com/ldd/doc/domino_notes/9.0/api90ug.nsf/85255d56004d2bfd85255b1800631684/00d000c1005800c985255e0e00726863?OpenDocument

    此链接解释了 OID 的工作原理及其外观。

    我用 NotesPeek 和宾果游戏检查了 OID! OID 应该包含一个有效的日期,但它完全是胡言乱语,例如 9856.06.20。有时只是缺少日期部分,这就是我看到 1899 的原因。

    此问题的结束点是以下链接,该链接确认此奇怪行为是 Notes 8.5.1 的错误

    https://www-01.ibm.com/support/docview.wss?uid=swg1LO47325

    【讨论】:

      猜你喜欢
      • 2018-06-13
      • 1970-01-01
      • 2017-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-15
      • 2012-02-27
      相关资源
      最近更新 更多