zoukankan      html  css  js  c++  java
  • lotus notes 开发常用方法

    标题   lotus notes 开发常用方法  
    一、关于AppendItemValue

    试试下面这个简单的例子:

    Dim ws As New notesuiworkspace

    Dim uidoc As notesuidocument

    Dim doc As notesdocument

    Set uidoc=ws.currentdocument

    Set doc=uidoc.document

    For i=1 To 10

    Call doc.appenditemvalue("myitem",i)

    Next

    Call doc.save(True,True )


    这个程序用以对当前文档增加10个ITEM,名字都叫myitem,但值从1到10不等。结果如何?用调试方式进行观察,发现:确实增加了10个ITEM,名字都叫myitem,但值却都是1!这与NOTES中的帮助不符。帮助里宣称:

    If the document already has an item called itemName$, AppendItemVa

    lue does not replace it.

    Instead, it creates another item of the same name, and gives it th

    e value you specify.

    ^^^^^^^^^^^^^^^^^^^^

    从4.6到5.0结果都一样。

     

    二、区分NOTES的前台类与后台类

    由于两者的使用范围不一,在写程序时应注意这一点,尤其写代理时。如果在后台服务器运行的代理里加一句:

    Dim ws As New notesuiworkspace

    代理运行日志报错:Unkown Error.

     

    三、关于NOTES与OLE的共享域

    NOTES提供了一个很好的功能:共享域。NOTES用共享域来与OLE应用程序交换彼此信息。但除非确有必要与OLE应用程序共享信息,建议在设计表单时,选上:禁止共享域。 笔者曾在一个表单中创建了一个作者域AUTHOR,又在它的RTF域中嵌入MS-WORD文档:

    CALL UIDOC.CREATOBJECT("MYDOC","WORD.DOCUMENT.8","")

    似乎一切都正常。但当我变更了NOTES的作者域AUTHOR(因笔者试图通过作者域的改变来控制NOTES文档的修改进而达到流程控制的目的),因为流程的需要,我把它变成了两个值,在NOTES中显示为:

    user1/co1/server1,user2/co1/server2

    然后对RTF域中所嵌入的WORD文档进行了修改,然后退出,保存。结果问题出现了,NOTES报错:你不是文档的作者,不能保存! 什么原因?当时我明明是用user1/co1/server1进行修改的!后来,仔细调试,把AUTHOR的隐藏属性去掉,仔细观察,发现只要激活了RTF域中嵌入的WORD文档,在RTF域中退出来时AUTHOR的值竟变成了:

    user1/co1/server1/co1/server2!

    原来,WORD也有一个作者域,名字也叫AUTHOR(似乎是不能改变的)WORD的AUTHOR与NOTES的AUTHOR相互影响(怎么影响?我也不知道),于是变出了上面的这个怪东西!解决办法,当然,就是把NOTES表单“禁止域交换”了!(OLE应用程序有太多的域,想弄清这些域的名字,似乎不太可能。所以“禁止域交换”应是解决这类问题的最好办法了,窃以为)

     

    四、使用NOTES整合OA应用、OFFICE弥补NOTES不足


    Sub Entering(Source As Field)

    Dim curws As New notesuiworkspace

    Dim uidoc As notesuidocument

    Set uidoc=curws.currentdocument

    lnflag=uidoc.fieldgettext("docadd")

    If lnflag=0 Then

    Call uidoc.fieldsettext("docadd","1")

    Call uidoc.createobject("worddoc","word.document.8","")

    End If

    Exit Sub

    End Sub

    当提交后,须记录并显示编辑者对WORD文档的所有修改,故而要将WORD文档改成修订状态。在提交按钮中,写如下程序:

    Sub Click(Source As Button)

    Dim ws As New notesuiworkspace

    Dim uidoc As notesuidocument

    Set uidoc=ws.currentdocument

    Dim curdoc As notesdocument

    Set curdoc=uidoc.document

    Dim worddoc As notesembeddedobject

    Dim wordapp As Variant

     

    Call ws.editdocument(True)

    lnflag=uidoc.fieldgettext("docadd")

    If lnflag="1" Then

    Set worddoc=curdoc.embeddedobjects(0)

    Set wordapp=worddoc.activate(False)

    Call worddoc.doverb("编辑(&E)")

    wordapp.application.visible=False

    wordapp.application.activedocument.trackrevisions=True

    wordapp.application.activedocument.showrevisions=True

    Call wordapp.application.activedocument.save

    Call wordapp.application.exit

    End If

    Call uidoc.save

    Call ws.editdocument(False)

    End Sub

    上述修改WORD文档为修订状态的那段程序,其实可以改为:

    Set wordapp=uidoc.GetObject("worddoc")

    wordapp.application.visible=False

    wordapp.application.activedocument.trackrevisions=True

    wordapp.application.activedocument.showrevisions=True

    Call wordapp.application.activedocument.save

    即通过UIDOC的GetObject方法进行访问。

    但通过OLE对象访问时,应注意拼写的正确性,尤其是能过指明OLE对象名称(而不是文件名称)来创建时,更应注意OLE对象名称的拼写正确

    性。否则,错误难以预料。例如,在RTF域的Entering事件中将创建对象语句按如下修改:

    把: Call uidoc.createobject("worddoc","word.document.8","")

    改为: Call uidoc.createobject("worddoc","word.document","")

    OLE对象还是可以创建,一切似乎都很正常。但是当执行提交时,若通过EmbeddedObject的访问文档,则在Set wordapp=worddoc.activate

    (False)时出错:不能储存对象。

    若通过UIDOC的GetObject方法进行访问,则在

    wordapp.application.activedocument.trackrevisions=True时出错:没有激活文档。

     

    五、使用APPENDTOTEXTLIST

    APPENDTOTEXTLIST增加文本列表项。使用方法如下:

    Dim rtitem as notesitem

    dim uidoc as notesuidocument

    dim ws as notesuiworkspace

    dim curdoc as notesdocument

    set uidoc=ws.currentdocument

    set curdoc=uidoc.document

    set rtitem=curdoc.getfirstitem("authors")

    lcreader=curdoc.getitemvalue("readers")

     

    for i=0 to ubound(lcreader)

    call rtitem.appendtotextlist(lcreader(i))

    next

    上例把多值域READERS的值逐个追加到另一个多值域AUTHORS中。要实现这种目的,还有一种办法,即:通过NOTESDOCUMENT的GETITEMVALUE方法


    分别把两个域的值放到两个数组中,再合并两个数组到一个新的数组中,通过调用NOTESDOCUMENT的REPLACEITEMVALUE方法把新数组的值赋给

    AUTHORS。但显然这种方法,编程量要大得多。 也许有人会说,为什么不用字符串的相加,再通NOTESUIDOCUMENT的FIELD SETTEXT把相加后的字


    符串赋给相应的域?按NOTES的说明及其相应的帮助来说,这应该是可以的(当然,两个字符串之间的分隔符应用设计域时指定的分隔符分

    开)。但实际上,这种方法极不可靠!尤其是两个域的值均为姓名时,实在无法保证这样运算产生的结果是怎样的。NOTES对姓名域有自己的处


    理办法,但它怎样将前台显示的姓名转换成后台的姓名?只怕没人能搞得清楚。本人有试过这种方法。当只有一两个值时,这种运算一般不会

    错;但当值多时(我试的时候有7个左右),有时一切正常,有时出现的错误不可思议:NOTES居然把整个字符串当做一个值!它竟然根本没有理


    会域的多值分隔符!还要注意一点,不须通过NOTESDOCUMENT的SAVE方法,上例所做的变更依然有效。NOTESITEM的变量应是指向相应文档的指针


    (我猜的)。

     

    六、NOTES的ODBC支持缺陷

     

    A NOTES无法支持后台数据库(如ORACLE)的预储程序Stored Procedure,即使新版的6.2也是如此。尽管帮助自称有提供运行后台数据库SP的函数(resultset.execprocedure),但其实并不起作用。

     

    B 如果在一个odbc connection中有多句SQL的话,会出错:too many cursor。尽管你的sql语句根本不含cursor。Lotus自称在4.6及以后版本中,这个bug已解决,不过,答案也确是如此

     

    七、NOTES的数组

    A 定义数组

    有两种方式:DIM和REDIM。

    DIM定义的是固定个数、数据类型的数组;而REDIM则不同,它可以定义不同类型的数据,也可以定义个数并非固定的数据。比较下面几个例子。 都合法的例子:

    Dim myarray(5,2) as string Redim myarray(5,2) as string

    前者错误而后者合法的例子:

    n=10 n=10

    Dim myarray(n) as string Redim myarray(n,2) as string

    另外REDIM还可以定义未定类型的数组,如:Redim myarray(10)

     

    B 数组个数

    在以DIM或REDIM定义数组时指定的下标,表示的是访问该数组时所容许的最大下标,却不是该数组的个数。实际上,一维数组个数总是等于(最


    大下标+1),访问时是通过下标从0开始逐个访问的。

    比如:Dim myarray(5) As String定义的数组元素有6个,分别是:myarray (0)、

    myarray(1)、myarray(2)、myarray(3)、myarray(4)、myarray(5)。

    再如:Redim thisarray(2,5) As String 实际上定义了一个(2+1)*(5+1)=1 8的二维数组。

    既然如此,那么,可不可义定义一个只有一个元素的数组呢?答案是:不可以。

    如前所说,Redim thisarray(1)定义的数组实际上有(1+1)个数组元素,但类似于: Redim thisarray(0)的语法,NOTES又认为是错误的。所以,

    不能定义一个只有一个数组元素的数组。其实,以上说的只是其默认状况。其实,定义数组可以通过定义下标的起止从而达到定义数组的个数甚

    至下标的起止编号的。比如:Redim thisarray(1980 to1990)就 定义了一个含有11个元素的数组,下标从1980到1990。

     

    C 关于UBOUND函数

    UBOUND返回的是一维数组的最大下标,而不是元素个数。比如:Dim Myarray(5) As Integer,那么UBOUND(Myarray)返回的值是5,而不是6。

    UBOUND也可以应用于二维数组。应用于二维数组时,它返回的是第一个下标的最大值。

    比如:Dim Myarray(6,3) As Integer,

    那么UBOUND(Myarray)返回的值是6,而不是7,更不是18(6*3=18)。

    若要返回第二个下标的最大值,则使用:UBOUND(Myarray,2)。

    与UBOUND相对应的是另外一个函数:LBOUND,它返回数组的最小下标。与UBOUND类似,LBOUND(Myarray,2)则返回数组MYARRAY的第二个下标的最

    小值。所以,准确地说,一维数组Myarray的元素个数为:UBOUND(Myarray)-LBOUND(Myarray)+1,而二维数组的元素个数则为:

    (UBOUND(Myarray)-LBOUND(Myarray)+1)*(UBOUND(Myarray,2)-LBOUND(Myarray,2)+1)

    多维数组依此类推。

     

    D 返回数组的函数

    可以定义一个函数,使其返回数组。宣告函数时只要宣告它返回Variant型即可

    。如下例:

    Function db_string(Byval fdname As String) As Variant

    fdnum=Len(fdname)

    Redim lcarray(fdnum,2) As String

    lcarray(0,0)="thisstr"

    lcarray(0,1)=","

    lcarray(0,2)=","

    ......

    db_string=lcarray '使函数返回数组lcarray的值

    End Function

    在调用函数时,以如下方式调用:

    thisstring="AAAAAAAA"

    Dim Thisarray As Variant

    thisarray=Db_string(thisstring)

    print thisarray(0,0)

     

     

    八、

    NOTES的ODBC:(LS:DO)

    A 使用LotusScript编写ODBC程序时需要掌握的几个类:ODBCConnection、ODBCQ

    uery、与

    ODBCResultSet。通常做法为:

    Set con = New ODBCConnection

    Dim dbqry As New ODBCQuery

    Dim dbresult As New ODBCResultSet

    ret=con.ConnectTo(DBSOURCENAME,DBUSERNAME,DBPASS)

    If con.isconnected=False Then

    ret1=Msgbox("数据库无法连接,请洽系统管理员",48,"提示信息")

    odbc_insert=-2

    Exit Function

    End If

     

    dbqry.sql="select * from THISTABLE where THISTABLE.ID=THISID"

    Set dbqry.Connection = con

    Set dbresult.query=dbqry

    dbresult.execute

    %REM

    通过dbresult访问关系数据库:取值、更新数据库

    %END REM

    status=dbresult.close(db_commit)

    ret=con.disconnect

     

    B 通过ODBCResultSet更新数据(插入、删除、修改),可以有两种方式。一种方式如上例,对ODBCQry.SQL赋为查询语句,然后能过

    ODBCResultSet类的ADDROW、UPDATEROW、DELETEROW 及SETVALUE等方法更新关系型数据库。如下例,对THISTABLE增加一笔记录,并赋字符串型

    字段field1的值为test:

    Set con = New ODBCConnection

    Dim dbqry As New ODBCQuery

    Dim dbresult As New ODBCResultSet

    ret=con.ConnectTo(DBSOURCENAME,DBUSERNAME,DBPASS)

    If con.isconnected=False Then

    ret1=Msgbox("数据库无法连接,请洽系统管理员",48,"提示信息")

    odbc_insert=-2

    Exit Function

    End If

     

    dbqry.sql="select * from THISTABLE where 1=0"

    Set dbqry.Connection = con

    Set dbresult.query=dbqry

    dbresult.execute

    Call dbresult.addrow

    Call dbresult.setvalue("field1","test")

    Call dbresult.updaterow

     

    status=dbresult.close(db_commit)

    ret=con.disconnect

    由于updaterow方法只有对只含一笔记录的ODBCResultSet才有效(多笔时会报错),故而在SQL中的条件中只有一个永远不成立的条件:1=0,以


    保证在执行addrow之后在updaterow 之前ODBCResultSet中只有一笔。 另外一种方式是直接用SQL语句更新数据库。它的好处在于一次可以更新

    多笔,而且比较灵活,坏处则在于必须考虑DOMINO与后台关系数据库之间的数据类型的转换。如下例,可以达到与上例一样的效果。

    Set con = New ODBCConnection

    Dim dbqry As New ODBCQuery

    Dim dbresult As New ODBCResultSet

    ret=con.ConnectTo(DBSOURCENAME,DBUSERNAME,DBPASS)

    If con.isconnected=False Then

    ret1=Msgbox("数据库无法连接,请洽系统管理员",48,"提示信息")

    odbc_insert=-2

    Exit Function

    End If

     

    dbqry.sql="insert into THISTABLE (THISID) values ('test')"

    Set dbqry.Connection = con

    Set dbresult.query=dbqry

    dbresult.execute

    status=dbresult.close(db_commit)

    ret=con.disconnect

     

    C 关于类型转换

    通过ODBCResultSet更新数据时通常要进行类型转换。通过上述的方式一中的方法更新数据 库可以不用类型转换即可更新数据库,条件是:


    NOTES表单中的相应域值不能为空(因为在 NOTES中任何域值若为空,则其数据类型总是string,值为空字符串)。如何实现?将方式 一的例子


    中的

    Call dbresult.setvalue("field1","test")改造如下:

    ltmp=Doc.GetItemValue("doc_field1")

    Call dbresult.setvalue("field1",ltmp(0))

    其中,doc_field1为关系数据库字段field1对应的NOTES域名。如此改造,即可通过域名更 改相应的后台关系数据库了。 通过上述方式二更新


    数据库,则要进行类型转换。可以通过前台NOTES的域的 数据类型来 判断生成可以正确执行的SQL语句,例如:字符型,则在生成时在其值的前


    后加单引号;数值型,则不必。但如何取得数据类型呢?通过NotesItem的Type属性访问可返回NotesDocument的条目的数据类型,例如:字符型

    时,返回1280;数值型时,返回768;日期时间型,返回 1024,等等。但当相应的域值为空时NotesItem.Type永远返回1280(即字符型),而不管


    实 际该域值类型为数值还是日期。 还有一种方法进行类型转换,通过后台关系数据库的数据类型生成可以正确执行的SQL语句。


    ODBCResultSet.FieldNativeDataType方法返回后台数据类型的相应字段类型,如: SQL_CHAR,SQL_INTEGER,SQL_TIMESTAMP等等。

  • 相关阅读:
    ndarray转PIL
    215. 数组中的第K个最大元素
    pytorch的分布式
    剑指 Offer 06. 从尾到头打印链表
    最长公共子序列
    剑指 Offer 57
    剑指 Offer 59
    剑指 Offer 48. 最长不含重复字符的子字符串
    Python线程池
    Python 常用内置函数
  • 原文地址:https://www.cnblogs.com/hannover/p/1631744.html
Copyright © 2011-2022 走看看