【问题标题】:Creating a view and agent in multiple databases在多个数据库中创建视图和代理
【发布时间】:2014-01-05 01:04:24
【问题描述】:

我遇到的问题是用户 ID 文件无法访问某些消息,我想跳过这些文件而不是代理崩溃。收到的错误信息如下:

如果发生这种情况,使用查看方法我可以暂时删除文档并重新运行代理,但如果有一种方法可以跳过文档,那将是一个很大的帮助。

感谢各位的帮助。

好的,我已将代码修改到我几乎可以接受的程度。

子初始化

Dim s As New notessession
Dim db As notesdatabase 
Dim view As notesview
Dim doc As notesdocument
Dim nextdoc As notesdocument


Set db = s.currentdatabase
If view Is Nothing Then
    Set view = db.CreateView("Encrypted",{Encrypt="1"})
End If  
Set doc = view.getfirstdocument

On Error Goto ErrorHandler

While Not doc Is Nothing        
nextDocument:
    Set nextdoc = view.getnextdocument(doc)
            'The below loop is mandatory to ensure that all $File entries are unecrypted
    Forall i In doc.items
        If i.isencrypted Then
            i.isencrypted=False 
        End If 
    End Forall

        'Must have at least 1 field encrypted in order to call Encrypt method
    Dim temp As New NotesItem(doc,"tempjunk","temp")
    temp.IsEncrypted=True
    Call doc.encrypt
    Call doc.save(True, False)
        'This portion can now remove the fields relative to encrypting the
        'single token encrypted field.
    Call doc.removeitem("$Seal")
    Call doc.removeitem("$SealData")
    Call doc.removeitem("SecretEncryptionKeys")
    Call doc.removeitem("Encrypt")
    Call doc.removeItem("tempjunk")
    Call doc.save(True, False)
    Set doc = nextdoc 
Wend
Exit Sub

ErrorHandler:
On Error Resume nextDocument
Exit Sub

结束子

错误处理不太好;

On Error Resume nextDocument 显示为错误。 我已经尝试抑制所有似乎试图剥离加密的错误警告,但我认为它们的消息正文因此被破坏。

【问题讨论】:

  • 我猜 Karl-Henry 的例子并不理想。它应该说“on error goto errhandler”并且在 err handler 块中“resume nextdocument”(而不是“on error resume nextdocument”)
  • 你是对的,我在下面更新了我的代码。

标签: view lotus-notes lotus-domino lotusscript agent


【解决方案1】:

如果您必须处理每个数据库中的所有(或几乎所有)文档,您可以使用 db.AllDocuments。它比使用带有 @All 公式的 db.Search() 更有效。

如果您想排除某些文档,可能基于表单名称,我会构建一个要排除的表单列表,然后使用 IsElement 对照该列表检查正在处理的每个文档。

Dim exclude List As Boolean
exclude("FormA")=True
exclude("FormB")=True

Set col = db.AllDocuments
Set doc = col.GetFirstDocument()
Do Until doc Is Nothing
    formname = doc.GetItemValue("Form")(0)
    If IsElement(exclude(formname))=False Then
        Call RemoveEncryption(doc)  '*** Your function to remove encryption
    End If
    Set doc = col.GetNextDocument(doc)
Loop

类似的东西。顺便说一句,您可以将列表创建为任何数据类型。我只是选择 Boolean,因为它是一种小型数据类型,并且它使代码更易于阅读。 IsElement() 函数只是检查元素是否存在,它不使用您设置的值。

您可以将上面的代码包装在一个函数中,并在每个数据库中调用一次。

附加答案,基于原始问题中的附加信息:

这应该不难,只需在代码中添加错误处理即可。

在开始循环遍历文档之前:

On Error Goto errHandler

在循环中获取下一个文档之前:

nextDocument:

在您的代码末尾:

    Exit Sub
    errHandler:
    Resume nextDocument
End Sub

试试看。

【讨论】:

  • 谢谢卡尔-亨利。我喜欢这种方法,因为它不需要创建视图,我已经修改了我的代码,仍然只在单个实例上运行,因为有一个问题导致代理失败,我需要修复,希望你能提供帮助。
  • 您遇到了什么问题?
  • 我认为,如果我可以让错误处理/文档跳过工作,那么解决方案就足够了,遇到建议的错误处理的一些问题,谷歌搜索这个和我能找到的提供相同类型语法,因此我只能推测这是我的脚本中不正确的处理位置,上面发布。再次感谢您的帮助。
【解决方案2】:

您可以通过从另一个数据库复制视图来创建视图。假设您使用代理在您的数据库中创建了一个“加密”视图。

然后添加一段代码以获取此视图的句柄作为 NotesDocument:

Dim dbThis As NotesDatabase 
Dim viewTemplate As NotesView
Dim docView As NotesDocument

Set dbThis = s.currentDatabase
Set viewTemplate = dbThis.getView("Encrypted")
Set docView = dbThis.Getdocumentbyunid(viewTemplate.Universalid)

在代理循环中,测试是否存在加密视图,如果不存在则复制“视图模板”:

Set view = db.getview("Encrypted")
If view Is Nothing Then
    Call docView.Copytodatabase(db)
    Set view = db.getview("Encrypted")
End If

最后,如果您坚持,可能会使用类似的过程将代理复制到所有数据库,但对我来说,在一个数据库中运行代理的想法听起来更好。

已编辑:鉴于完全公开 - 当然您可以创建一个视图(我猜这是最初的问题)。

If view Is Nothing Then
   Set view = db.Createview("Encrypted", {Encrypt="1"})
End If

或者执行 Torsten 建议的一次性 dbSearch,对 Richard 进行很好的重新标记 - 如果您打算多次运行代码 - 比如说是否可能再次创建或重新加密加密文档,而不是去查看.

我的方法有点过时(早于 createView 的可用性),如果您需要的不仅仅是选择公式,那么效果很好,因此您可以预先构建一个复杂的视图以供重复使用。

性能方面:无论您选择使用 createView 创建视图还是从其他数据库复制或执行 dbSearch 的任何方法,在构建视图或执行 dbSearch 时都会出现一定的减速。 Karl-Henry 的方法将避免这种搜索/视图构建,但如果加密文档不多,则会相对较慢。

无论您选择哪种方法 - 这里有一个提高性能的小技巧。让你的循环像这样在你去的时候释放内存;例如,假设 Karl-Henry 的方法:

Dim doc1 as NotesDocument
Set doc = col.GetFirstDocument()
Do Until doc Is Nothing
    Set doc1 = col.GetNextDocument(doc)
    formname = doc.GetItemValue("Form")(0)
    If IsElement(exclude(formname))=False Then
        Call RemoveEncryption(doc)  '*** Your function to remove encryption
    End If
    ' releasing memory when processing thousands of documents improves performance and avoids crashes
    Delete doc
    Set doc = doc1
Loop

再一次,当您谈论 20 多个数据库的迁移(所以一次)时,速度或实施细节不应该那么关键。

【讨论】:

  • 我想知道,如果我有一个可以在许多数据库上运行的代理,是否可以使用选择标准 'Encrypt="1"' 通过代理创建一个视图?
  • 我更新了我的帖子,以反映这一点(并且可能提供更多想法)
  • 再次感谢,这些信息很有帮助。您说得对,这里的速度并不是一个重要因素,我的目标更多是自动化(不会同时退出错误和多个数据库)。我将有其他用户要迁移,因此会有大量 nsfs 需要处理。
【解决方案3】:

在容器数据库中创建代理并让该代理访问所有“目标”数据库中的文档并相应地修改它们是没有问题的 - 无需将该代理复制到所有数据库。

唯一限制:如果数据库在另一台服务器上,那么在目标服务器的服务器安全选项卡上,您必须输入具有容器数据库的服务器作为受信任的服务器。

并且:如果您的代理运行时间超过服务器上代理允许的最大运行时间,那么它将被提前终止。

不需要在目标数据库中创建视图,可以使用NotesDatabase.Search()获取数据库中对应的文档...

【讨论】:

  • 同意。需要注意的是,如果这个代理是如果数据库很大并且代理必须运行不止一次,那么从长远来看,拥有视图会更有效。但是代理可以做到这一点。它可以尝试打开视图,如果找不到视图,它可以构建它,然后返回并重新尝试打开它。
  • 谢谢大家的回复。我很感激。我目前遵循这条路线的原因是我已经离线提供了数据库,并且只有一个 Notes 客户端可以在其上运行该进程。请使用我尝试创建的代码查看我修改后的问题。仅使用笔记客户端可能是不可能的..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-21
  • 2011-01-09
  • 2019-03-12
  • 1970-01-01
  • 1970-01-01
  • 2019-10-26
  • 1970-01-01
相关资源
最近更新 更多