我遇到的问题是用户ID文件无法访问某些消息,我想跳过这些文件而不是代理崩溃。收到的错误消息如下:
如果发生这种情况,使用视图方法我可以暂时删除文档并重新运行代理,但如果有办法跳过文档,那将是一个很大的帮助。
感谢帮助人员。
好的,我已将代码修改为我几乎感到满意的程度。
Sub Initialize
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
End Sub
错误处理效果不佳;
On Error Resume nextDocument 显示为错误。 我试图压制所有似乎试图剥离加密的错误警告,但我认为它们的消息正在被破坏。
答案 0 :(得分:3)
在容器数据库中创建代理并让该代理访问所有“目标”数据库中的文档并相应地修改它们没有问题 - 无需将该代理复制到所有数据库。
仅限制:如果数据库位于另一台服务器上,则必须在目标服务器的服务器安全性选项卡上输入服务器,并将容器数据库作为可信服务器。
AND:如果您的代理程序运行的时间超过了服务器上代理程序允许的最长运行时间,那么它将过早被终止。
无需在目标数据库中创建视图,您可以使用NotesDatabase.Search()来获取数据库中的相应文档...
答案 1 :(得分: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
这样的事情。顺便说一下,您可以将列表创建为任何数据类型。我只选择布尔值,因为它是一种小数据类型,它使代码更容易阅读。 IsElement()函数只检查元素是否存在,它不使用您设置的值。
您可以将上面的代码包装在一个函数中,并为每个数据库调用一次。
附加答案,基于原始问题中的其他信息:
这应该不难,只需在代码中添加错误处理。
开始循环播放文档之前:
On Error Goto errHandler
在循环中获取下一个文档之前:
nextDocument:
在代码的最后:
Exit Sub
errHandler:
Resume nextDocument
End Sub
试试。
答案 2 :(得分:1)
您可以通过从其他数据库复制视图来创建视图。假设您在数据库中使用代理创建了一个“加密”视图。
然后添加一段代码以获取此视图的句柄作为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,并重新标记理查德 - 如果您打算多次运行代码 - 比如加密文档可能会再次创建或重新加密,而是去查看
我的方法有点老式(createView的早期可用性),如果您需要的不仅仅是选择公式,那么效果很好,因此您可以预先构建一个复杂的视图以供重复使用。
性能方面:无论您选择使用createView创建视图还是从其他数据库复制或执行dbSearch,在构建视图或执行dbSearch时都会出现一定的减速。 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多个数据库的迁移(一次性)时,速度或实现细节不应该那么重要。