Lotus Domino V7.0 在 Lotus Domino Designer 中引入了新的 Web 服务设计元素。因此在Lotus Domino应用开发中使用Web 服务变得更加容易。其中Lotus Domino 负责处理所有的 WSDL 创建和 SOAP 操作,我们所要做的事情就是在 Web 服务设计元素中编写代码,设计Web 服务。Lotus Domino 就可以发布 WSDL 文件、将引入的 SOAP 请求转换为类上的方法调用以及返回方法的结果(如果有的话)作为 SOAP 响应。Lotus Domino Web 服务可以用lotus script,java两种语言编写。而调用Web 服务的方法却有很多。
一、设计Web 服务。

 

 

点新建Web 服务。设计自己的Web 服务。

 

 Web Service Properties 框中的 Basics 附签
对 Basic 附签上的字段说明如下:
Name(必需的):Web 服务的名称,是客户机访问 WSDL 文件或服务的方法时所使用的名称。
Alias:除 Name 之外的另一名称,用户使用该名称可以访问服务。
Comment:有关 Web 服务的信息数据的字段(通常,该字段的信息不超过一句话;有关 Web 服务的较长描述或信息应写在代码的注释中)。
Warn if the WSDL interface is modified:该选项警告您对代码所做的更改是否修改了由 Web 服务产生的 WSDL 文件。这对于确保 WSDL 文件的一致很有用,但是应该意识到,如果选中了该选项,则您将无法保存带有已修改的 WSDL 文件的服务。
PortType class(必需的):用作 Web 服务接口的类的名称。换句话说,它就是 Web 服务代码中带有用户可访问的 public 方法的类。
框中的第二个附签是 Security 附签(参见图 4)。
对 Security 附签上的字段说明如下:
Run as web user:该选项使 Web 服务代码能够在调用 Web 服务的用户的安全性上下文中运行(默认情况下,它将在 Lotus Domino Designer 中最后签名 Web 服务的那个 ID 的安全性上下文中运行)。
Run on behalf of:该字段允许指定用户,如果想让 Web 服务代码运行在特定用户的安全性上下文中,而不是 Lotus Domino Designer 中最后签名 Web 服务的那个 ID 的安全性上下文中。
Allow remote debugging:该选项允许远程调试 Web 服务(有关远程调试的信息,请参阅 Lotus Domino Designer 帮助主题 “Using the Remote Debugger”)。
Profile this web service:该选项将在 Web 服务运行时使其生成分析信息(有关分析的信息,请参阅 Lotus Domino Designer 帮助主题 “Profiling agents and Web services”)。
Set runtime security level:设置为 1,允许大多数 LotusScript 和 Java 操作正确运行;对于读/写文件、创建 COM 对象或执行网络操作等,根据需要,设置为 2 或 3(有关更多信息,请参阅 Lotus Domino Designer 帮助主题 “Restricted LotusScript and Java agent operations”)。
Default access for this web service:该选项允许控制哪些用户可以访问 Web 服务,并超出了使用数据库 ACL 所能进行的控制(如果 Anonymous 用户无法访问 Web 服务,则当用户尝试进行连接时,将收到错误 401 Access Denied 或 404 Not Found)。
Allow Public Access users to use this web service:该选项使得仅拥有数据库 ACL 中 “Read Public Documents” 访问权的用户可以使用该 Web 服务,当不想为大量用户授予完全的 Reader 访问权限(或更高级别)时,这点很有用。
框中的第三个附签是 Options 附签(参见图 5)。
对 Options 附签上的字段说明如下:
Programming model:可用选项是 RPC 或 Message(大多数情况下使用 RPC)。
SOAP message format:在该字段中,为此 Web 服务选择 SOAP 消息格式,Lotus Domino V7.0 中的默认格式是 RPC/encoded。
Include operation name in SOAP action:该选项要求操作名称存在于外来请求的 SOAP 动作标头中(很少需要)。
Port type name:默认情况下,该字段值与 Basics 附签上 PortType class 字段的值相同(尽管您可以使用任何想用的名称)。生成 WSDL 文件时使用该值。
Service element name:默认情况下,该字段值是 PortType 名称加上单词 Service(尽管您可以使用任何想用的名称)。生成 WSDL 文件时使用该值。
Service port name:默认情况下,该字段值是 Domino(尽管您可以使用任何想用的名称)。生成 WSDL 文件时使用该值。

 

 
可以选择是用lotus script 或JAVA语言编辑你的Web 服务。以下是lotus script编写的一个简单的例子。
%INCLUDE "lsxsd.lss"
Class saveworkflow
    Sub NEW
       
    End Sub
    Function saveworkflowxml(xmlfilename As String,xmltext As String) As String
        On Error Goto errhandle
        Dim outputStream As NotesStream
        Dim session As New NotesSession
        Set outputStream = session.CreateStream
       
        Dim outputFile As String
        outputFile=Curdir$()+"datadominohtmlworkflow"+xmlfilename
        If outputStream.Open(outputFile) Then
            Call outputStream.WriteText(xmltext, EOL_CRLF)
            Call outputStream.Close
        End If
        saveworkflowxml="1"
        Exit Function
errhandle: 
        Msgbox Str(Err)+"行号:"+Str(Erl)+"错误信息saveworkflow:saveworkflowxml"+Error$   
        Resume Next
    End Function
   
   
End Class
一、Web 服务的调用。
1、 lotus script代理中调用webservice。在window平台上我们可以使用MSSOAP toolkit来调用。可以下载MSSOAP toolkit3.0,并在服务器上安装MSSOAP toolkit3.0。在代理中的代码如下:
Sub Initialize
    On Error Goto errhandle
    Dim ss As New NotesSession
    Dim doc As NotesDocument
    Set doc=ss.DocumentContext
    Dim client As Variant
    Dim xmlfilename As String
    Dim xmltext As String
    xmlfilename=doc.xmlfilename(0)
    xmltext=doc.xmltext(0)
    Set Client =CreateObject("MSSOAP.SoapClient30")
    Call Client.mssoapinit ("http://server/mis/flow.nsf/saveworkflow?WSDL")
    Dim result As String
    If Not Client Is Nothing Then
        result = Client.saveworkflowxml(xmlfilename,xmltext)
       
           
    Else
        result="no web"
    End If 
   
    Exit Sub
errhandle: 
    Msgbox Str(Err)+"行号:"+Str(Erl)+"错误信息saveworkflowxml:"+Error$   
    Resume Next
   
End Sub
2、 javascript中调用 webservice。
var xmlfilename=document.all.xmlfilename.value
var xmltext=document.all.xmltext.value
                        var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                        var soapMessage, soapData, URL;
                        // Set the soap message
                        soapMessage = "<?xml version="1.0" encoding="utf-8"?>";
                        soapMessage += "<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance""
                        + " xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">";
                        soapMessage += "<soap:Body>";
                        // Set the data for soap body ---- begin ------
                        soapData = "<saveworkflowxml xmlns="http://tempuri.org/">";
                        soapData += "    <xmlfilename>" + xmlfilename + "</xmlfilename>";
 soapData += "    <xmltext>" + xmltext + "</xmltext>";
                        soapData += "</saveworkflowxml>";
                        // Set the data for soap body ---- end ------
                        soapMessage = soapMessage + soapData + "</soap:Body>";
                        soapMessage = soapMessage + "</soap:Envelope>";
var urlstr="http://server/mis/flow.nsf/saveworkflow?openwebservice"
 
                        xmlhttp.Open("POST",urlstr, false);
                        xmlhttp.SetRequestHeader ("Content-Type","text/xml; charset=utf-8");
                        xmlhttp.SetRequestHeader ("SOAPAction","http://tempuri.org/onlineandmsg");
                        xmlhttp.send(soapMessage);
                        var x =   xmlhttp.responseXML;
3、 FLASH 中调用webservice。
import mx.services.WebService;
//定义WebService的路径;
var ws_url:String = "http://server/mis/flow.nsf/saveworkflow?WSDL";
//定义WebService对象;
var ws:WebService = new WebService(ws_url);
//调用WebService方法;
var callObject = ws.SAVEWORKFLOWXML(_parent.workflowxml,_global.workxml.toString());
//设置返回结果对象;
callObject.onResult = function(result){
    trace(result);
      
}
//如果调用错误返回信息(这个是可选的);
callObject.onFault = function(fault){
    trace("fault:"+fault.faultstring);
}
 
4、 java 代理中调用webservice,首先在代理工程中引入相关的包。
import lotus.domino.*;
import java.io.*;
import java.util.*;
import java.net.*;
import org.w3c.dom.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.*;
import org.apache.soap.encoding.*;
import org.apache.soap.encoding.soapenc.*;
import org.apache.soap.rpc.*;
import org.apache.soap.transport.http.SOAPHTTPConnection;
public class JavaAgent extends AgentBase {
 
    public void NotesMain() {
 
        try {
            Session session = getSession();
            AgentContext agentContext = session.getAgentContext();
     Document doc = agentContext.getDocumentContext();
String xmlfilename=doc.getItemValueString("xmlfilename")
String xmltext=doc.getItemValueString("xmltext")
            // (Your code goes here)
        URL url = new URL ("http://server/mis/flow.nsf/saveworkflow?WSDL");
     SOAPMappingRegistry smr = new SOAPMappingRegistry ();
     StringDeserializer sd = new StringDeserializer ();
     smr.mapTypes (Constants.NS_URI_SOAP_ENC, new QName ("", "Result"), null, null, sd);
 
     // 创建传输路径和参数
     SOAPHTTPConnection st = new SOAPHTTPConnection();
 
     // 创建调用
     Call call = new Call ();
     call.setSOAPTransport(st);
     call.setSOAPMappingRegistry (smr);
 
     call.setTargetObjectURI ("http://tempuri.org/message/");
      call.setMethodName("saveworkflowxml");
     call.setEncodingStyleURI ("http://schemas.xmlsoap.org/soap/encoding/");
 
     Vector params = new Vector();
    params.addElement(new Parameter("xmlfilename", String.class, xmlfilename, null));
 params.addElement(new Parameter("xmltext", String.class,xmltext, null));
     call.setParams(params);
 
     Response resp = null;
 
     try {
       resp = call.invoke (url,"");
     }
     catch (SOAPException e) {
     System.err.println("Caught SOAPException (" + e.getFaultCode () + "): " + e.getMessage ());
     return;
     }
 
     // 检查返回值
     if (resp != null && !resp.generatedFault()) {
     Parameter ret = resp.getReturnValue();
     Object value = ret.getValue();
 
     System.out.println ("Answer--> " + value);
     }
     else {
         Fault fault = resp.getFault ();
         System.err.println ("Generated fault: ");
         System.out.println (" Fault Code = " + fault.getFaultCode());
         System.out.println (" Fault String = " + fault.getFaultString());
     }
 
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
posted @ 2008-12-02 20:31 hannover 阅读(827) 评论(2) 编辑

在lotus domino程序开发中,有时会遇到 flash 与表单内容交互的情况。下面举一个例子说明如何解决这一问题。

</form><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="1000" height="600" id="workflowd" align="center">
<param name="allowScriptAccess" value="always" />
<param name="FlashVars" value="<计算的值>" />
<param name="movie" value="/workflow/workflowd.swf" /><param name="quality" value="high" /><param name="bgcolor" value="#ffffff" /><embed src="/workflow/workflowd.swf" quality="high" bgcolor="#ffffff" width="1000" height="600" name="workflowd" align="center" allowScriptAccess="sameDomain"  FlashVars="<计算的值>" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>

1、表单域值传到flash变量中。上面的代码,其中“计算的值>"”的计算公式为“"workflowname="+workflowxml+"”上面的代码,为名为workflowd的flash 传递了一个变量workflowname,它的值为workflowxml的值。workflowxml为表单上的一个域。

2、flash调用表单上的javascript.函数

flash为的调用代码为

import flash.external.ExternalInterface;
ExternalInterface.call("sayname", "小王");

javascript的函数为:

function sayname(name)

{

window.alert(name)

}

当然还有其他的调用方法,不再列举。


posted @ 2008-12-02 20:23 hannover 阅读(154) 评论(0) 编辑

用lotusscript动态刷新登录页表单设计
1、到服务器上查找是否有domcfg.nsf库,如果没有,直接把自己设计的domcfg.nsf库考到服务器上,如果有,执行2
2、从服务器的domcfg.nsf库中查找登录页,如果有,先将“$$LoginUserForm”表单导成dxl,然后将form节点下属的name节点的nodevalue值改成“$$LoginUserForm”+时间,然后再把dxl文件导到domcfg.nsf库中(该操作是保存原有的登录页表单)。
3、将自己设计的库中的“$$LoginUserForm”表单导成dxl,然后再导入到服务器的domcfg.nsf库中。

另:
    如果想直接修改某个表单的设计也是同样的道理。因为domino的数据库设计、表单、视图等等都是标准的xml文件,所以如果要修改表单设计,可以先把表单导成dxl文件(xml格式),然后,直接对dxl中具体的node作修改,然后重新导入dxl文件即可实现对表单设计的动态修改。

Option Public
Option Compare Nocase

Sub Initialize
 On Error Goto errhandle
 Dim session As notessession
 Dim db1 As notesdatabase
 Dim db2 As notesdatabase
 Dim nc As notesnotecollection
 Dim nc2 As notesnotecollection
 Dim stream As notesstream
 Dim exporter As NotesDXLExporter
 Dim importer As notesdxlimporter
 Dim importer0 As notesdxlimporter
 Dim form As NotesForm
 Dim nid As String
 
 Dim file1 As String
 Dim file2 As String
 Dim file3 As String
 Dim outputFile As String
 
 Dim timeStr As String
 
 Dim inputStream As NotesStream, outputStream As NotesStream
 Dim domParser As NotesDOMParser
 Dim docNode As NotesDOMDocumentNode
 Dim docRootNode As NotesDOMNode
 
 file1 = ""
 file2 = ""
 file3 = ""
 flag = False
 timeStr = Replace(Replace(Replace(Cstr(Now),"-",""),":","")," ","")
 
 Set session = New notessession
 Set db1 = session.currentdatabase
 '先判断当前服务器是否有登录库
 Set db2 = New NotesDatabase(db1.Server, "domcfg.nsf")
 '如果没有登录库
 If Not db2.IsOpen Then
  Set db2 = db1.CreateFromTemplate(db1.Server,"domcfg.nsf", True)
 Else
  Set form = db2.GetForm("$$LoginUserForm")
  '如果存在登录页,首先备份登录页''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  If Not form Is Nothing Then
   Set nc = db2.createnotecollection(False)
   Call nc.buildcollection
   Set nc2 = db2.createnotecollection(False)
   nc2.SelectForms = True
   Call nc2.BuildCollection
   nid = nc2.GetFirstNoteId 
   '查找登录页表单
   Forall f In db2.Forms
    If Not f.IsSubForm Then
     If f.name = "$$LoginUserForm" Then
      nc.Add(nid)
      Exit Forall
     End If
     nid = nc2.GetNextNoteId(nid)
    End If
   End Forall
   '将表单导成dxl文件,并存在临时文件夹中
   Set stream = session.CreateStream
   file2 = "c:templogin_back_" & timeStr & "1.dxl"
   Call stream.Open(file2)
   Set exporter=session.createDXLexporter(nc, stream)
   Call exporter.process
   Call stream.close
   '删除原有登录页
   Call form.Remove
   '读取刚才的dxl文件(xml格式的文件),修改登录页名称
   file3 = "c:templogin_back_" & timeStr & "2.dxl"
   Set session = New NotesSession
   Set outputStream =session.CreateStream
   outputStream.Open(file3)
   Set inputStream = session.CreateStream
   inputStream.Open (file2)
   If inputStream.Bytes > 0 Then
    Set domParser=session.CreateDOMParser(inputStream)
    Call domParser.Process
    Set docNode = domParser.Document
    Set docRootNode = docNode.DocumentElement
    If Not docRootNode.IsNull Then
     '修改文件中form节点的下属节点name的nodevalue的值
     Call ChangeNode(docRootNode,timeStr)
     Call domParser.setoutput(outputStream)
     Call domParser.Serialize
    End If
   End If
   '导入备份登录页
   Set importer0=session.createdxlimporter(outputStream, db2)
   importer0.designimportoption = 2
   Call importer0.process
   Set importer0 = Nothing
   Call outputStream.Truncate
   Call inputStream.Truncate
   Call outputStream.Close
   Call inputStream.Close
  End If
  
  '导入登录页'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  Set nc = db1.createnotecollection(False)
  Call nc.buildcollection
  Set nc2 = db1.createnotecollection(False)
  nc2.SelectForms = True
  Call nc2.BuildCollection
  nid = nc2.GetFirstNoteId
  '取得当前库的登录页表单
  Forall f In db1.Forms
   If Not f.IsSubForm Then
    If f.name = "$$LoginUserForm" Then
     nc.Add(nid)
     Exit Forall
    End If
    nid = nc2.GetNextNoteId(nid)
   End If
  End Forall
  '导成dxl文件,并存在临时文件夹中
  Set stream = session.CreateStream
  file1 = "c:templogin_" & timeStr & ".dxl"
  Call stream.Open(file1)
  '把dxl导入到domcfg库中
  Set exporter=session.createDXLexporter(nc, stream)
  Set importer=session.createdxlimporter(stream, db2)
  importer.designimportoption = 2
  Call exporter.process
  Call importer.process
  Call stream.Truncate
  Call stream.close
 End If
 
 Exit Sub
errhandle:
 Msgbox Cstr(Erl) & "  " & Error
End Sub

'修改form节点的name属性值
Sub ChangeNode(childNode2 As NotesDOMNode, str1 As String )
 On Error Goto errhandle
 Dim docNameMap As NotesDOMNamedNodeMap
 Dim childNode3 As NotesDOMNode
 Dim tempNode As NotesDOMNode
 Dim i As Integer
 
 While Not childNode2.IsNull
  If childNode2.NodeType <> 3 Then
   If childNode2.HasChildNodes Then
    Set childNode3 = childNode2.FirstChild
    While Not childNode3.IsNull
     Call ChangeNode(childNode3,str1)
     If Not childNode3.IsNull Then
      Set childNode3 = childNode3.NextSibling
     End If
    Wend
   End If
  End If
  Set docNameMap = childNode2.Attributes
  For i =1 To docNameMap.NumberOfEntries
   Set tempNode = docNameMap.GetItem(i)
   If tempNode.NodeValue = "$$LoginUserForm" Then
    tempNode.NodeValue="$$LoginUserForm_" & str1
    Exit Sub
   End If
  Next
  Set childNode2 = childNode2.NextSibling
 Wend
 Exit Sub
errhandle:
 Msgbox "ChangeNode:" & Cstr(Erl) & "," & Error$
End Sub

posted @ 2008-12-02 20:21 hannover 阅读(352) 评论(0) 编辑

看到好多人要求找怎样导入Excel, 做了一个导入Excel到Notes的通用ScriptLibrary, 很方便哦,

Excel文件的要求:Excel的第一行一定要和Notes Form中FieldName一样.

用法实例:

Call ImportExcel("")        ' 会给出当前数据的所有Form给用户选择一个

或者

Call ImportExcel(Formname)

 

创建一个Script Library:

Function ImportExcel(FormName As String)
 Dim session As New NotesSession
 Dim uiws As New NotesUIWorkspace
 Dim form As NotesForm
 Dim db As NotesDatabase
 Dim doc As NotesDocument
 Dim item As NotesItem
 Dim row As Integer
 Dim xlFilename As String
 Dim xlsApp As Variant
 Dim xlsWorkBook As Variant
 Dim xlsSheet As Variant
 Dim rows As Long
 Dim cols As Integer
 Dim x As Integer
 Dim itemName As String
 Dim flag As Integer
 Dim formAlias As String
 Dim sortEval As String
 Dim sortedList As Variant
 Dim indexLo As Long
 Dim indexHi As Long
 Dim t As Integer
 Dim askme As Integer
 
 
 On Error Goto ErrorHandler
' ====== 1. Set form name, not select from form list ======
 
 Set db = session.CurrentDatabase
 
 fn= uiws.Prompt(1, "Reminder- Excel Worksheet Setup", "Make sure that the first row of your worksheet contains the EXACT Notes document field names from your form.")
 
'Get Excel file name
 fn =uiws.OpenFileDialog(False, "Select the Excel File to Import", "Excel files | *.xls", "c:My Documents")
 xlFilename = Cstr(fn(0)) ' This is the name of the Excel file that will be imported
 
 If formname="" Then
  'Get list of form names
  x=0
  
  Print "Preparing List of Database Forms ..."
  
  Forall f In db.Forms
   Redim Preserve formlist(x)
   formlist(x)=f.name
   x=x+1
   Print "Preparing List of Database Forms ..."& Cstr(x)
  End Forall
  
'Sort the form names for the dialog box
  indexLo= Lbound(formlist)
  indexHi= Ubound(formlist)
  Call QuickSort(formlist , indexLo, indexHi)
  
'Choose the form to use for import
  formname = uiws.Prompt(4, "Choose Import Form", "Please select which form is to be used for this input.", formlist(0), formlist)
  If formname= "" Then End
 End If
 
'Get the form object so that we can check field names
 Set form= db.GetForm(formname)
 
'If the form has an alias, use it to select the form
 If Not Isempty(form.Aliases) Then
  Forall a In form.Aliases
   formname=a
  End Forall 'a In form.Aliases
 End If 'Not Isempty(form.Aliases)
 
'Next we connect to Excel and open the file. Then start pulling over the records.
 Print "Connecting to Excel..."
 
' Create the excel object
 Set xlsApp = CreateObject("Excel.Application")
 
'Open the file
 Print "Opening the file : " & xlfilename
 xlsApp.Workbooks.Open xlfilename
 Set xlsWorkBook = xlsApp.ActiveWorkbook
 Set xlsSheet = xlsWorkBook.ActiveSheet
 xlsApp.Visible = False ' Do not show Excel to user
 xlsSheet.Cells.SpecialCells(11).Activate
 rows = xlsApp.ActiveWindow.ActiveCell.Row ' Number of rows to process
 cols = xlsApp.ActiveWindow.ActiveCell.Column ' Number of columns to process
 
'Make sure we start at row 0
 row = 0
 Print "Starting import from Excel file..."
 
 Do While True
  row = row + 1
  
'Check to make sure we did not run out of rows
  If row= rows+1 Then Goto Done
  
'field definitions for notes come from first row (row, column)
  If row=1 Then
   Redim misFD(0)
   t=0
   For i=1 To cols
    Redim Preserve fd(i)
'the replace function used here removes spaces from the field definitions in the first row
    fd(i)= Replace(xlsSheet.Cells( row, i ).Value, " ", "")
    
    flag=0
    
    Forall f In form.Fields
     If Lcase(fd(i)) = Lcase(f) Then flag=1
    End Forall 'f In form.Fields
    
    If flag=1 Then
     Goto Skip
    End If ' flag=1
    
    If Not flag=1 Then
     misFD(t)=fd(i)
     t=t+1
     Redim Preserve misFD(t)
    End If 'flag=1
    
Skip:
   Next 'For i=1 To cols
   
   If t>0 Then Redim Preserve misFD(t-1)
   If misFD(0)<>"" Then
    msg="Below Field(s) does not appear in the form you have chosen, Are you sure continue?"+Chr(10)+Chr(10)
    For i=0 To Ubound(misFD)
     msg=msg+misFD(i)+Chr(10)
    Next
    askme=uiws.Prompt(2,"Please Notice",msg)
    If askme<>1 Then
     Goto ErrorHandler
    End If
   End If
   
  End If 'row=1
  
  
  
'Import each row into a new document
  If Not row = 1 Then
   
'Create a new doc
   Set doc = db.CreateDocument
   doc.Form = FormName
   doc.HidDeleted=0
   For i= 1 To cols
    Set item = doc.ReplaceItemValue( fd(i), xlsSheet.Cells( row, i ).Value )
   Next ' i= 1 To cols
   
'Save the new doc
   Call doc.Save( True, True )
   
  End If 'Not row = 1 Then
  
  Print "Processing document number "& Cstr(row) & " of " & Cstr(rows)
  
  Loop 'Do while true
  
Done:
  
  Print "Disconnecting from Excel..."
'Close the Excel file without saving (we made no changes)
  xlsWorkbook.Close False
'Close Excel
  xlsApp.Quit
'Free the memory that we'd used
  Set xlsApp = Nothing
  
'Clear the status line
  Print " "
  
  
ErrorHandler:
  If Err = 184 Then
   Msgbox "No file chosen. Exiting Import."
   Print "No file chosen. Exiting Import."
   Resume ErrorOut
  End If ' err=184
  
  If Err = 6 Then
   Messagebox "Make sure that you do not have more than 65,536 rows of data to import." ,MB_OK+MB_ICONINFORMATION,"Error! "
   Print "Too many rows in Excel document. Exiting Import. Disconnecting from Excel..."
'Close the Excel file without saving (we made no changes)
   xlsWorkbook.Close False
'Close Excel
   xlsApp.Quit
'Free the memory that we'd used
   Set xlsApp = Nothing
   Resume ErrorOut
  End If ' err=184
  
  If (Err) And (Not Err = 184) And (Not Err = 6) Then
   
   Msgbox "Lotus Notes Error # " & Err &". Please contact your Notes administrator for help. Exiting Import."
   Print "Error # "& Err
   
   If Not xlsWorkbook Is Nothing Then
    xlsWorkbook.Close False
   End If ' Not xlsWorkbook Is Nothing
   
   If Not xlsApp Is Nothing Then
    xlsApp.Quit False
   End If 'Not xlsApp Is Nothing
   
   Resume ErrorOut
   
  End If '(Err) And (Not Err = 184) And (Not Err = 6)
  
ErrorOut:
End Function

Function QuickSort( anArray As Variant, indexLo As Long, indexHi As Long) As Variant
 
 Dim lo As Long
 Dim hi As Long
 Dim midValue As String
 Dim tmpValue As String
 
 lo = indexLo
 hi = indexHi
 If ( indexHi > indexLo) Then
'get the middle element
  midValue = anArray( (indexLo + indexHi) /2)
  While ( lo <= hi )
'find first element greater than middle
   While (lo < indexHi) And (anArray(lo) < midValue )
    lo = lo+1
   Wend
'find first element smaller than middle
   While ( hi > indexLo ) And ( anArray(hi) > midValue )
    hi = hi - 1
   Wend
'if the indexes have not crossed, swap
   If ( lo <= hi ) Then
    tmpValue = anArray(lo)
    anArray(lo) = anArray(hi)
    anArray(hi) = tmpValue
    lo = lo+1
    hi = hi -1
   End If
  Wend
' If the right index has not reached the left side of array, sort it again
  If( indexLo < hi ) Then
   Call QuickSort( anArray, indexLo, hi )
  End If
'If the left index has not reached the right side of array, sort it again
  If( lo < indexHi ) Then
   Call QuickSort( anArray, lo, indexHi )
  End If
 End If
 
 QuickSort = anArray
 
End Function

posted @ 2008-12-02 20:16 hannover 阅读(244) 评论(0) 编辑

OpenOffice.org周一(9/10)宣布IBM正式加入OpenOffice.org开放源码社群。IBM将捐赠Lotus Notes的部份程序代码给OpenOffice.org社群。事实上,IBM最近的Lotus 8就曾采用OpenOffice中的开放源码,只是IBM直到现在才捐赠程序代码,正式成为OpenOffice.org的一员。IBM之所以这么晚参与该社群主要的原因在于OpenOffice.org与IBM竞争对手升阳(SUN)的密切关系,不过双方最近因共同支持ODF开放文件格式而携手,共同抵抗微软的OOXML。OpenOffice.org说明了IBM过去一直以非正式的方式支持着OpenOffice.org,现在则是看到了市场对于ODF的强烈需求。IBM Lotus部门总经理Mike Rhodin表示,他们特别高兴可以与该社群合作共同加速办公室生产力市场的革新,双方的关系除了能改善IBM提供创新价值的产品及服务给客户的能力外,也将让支持ODF的应用程序及解决方案愈来愈普及。

支持ODF标准的著名专利律师Andrew Updegrove也在部落格评论此事,指出此讯息的重要性在于采用ODF的软件具备符合一般使用者及企业用户需求的能力,ODF近来有许多引人注目的成长,包括美国麻州的采用、成为ISO标准,以及微软的OOXML在ISO第一轮的投票失利等。此外,Google也在近日宣布要在Google Pack中提供支持ODF的StarOffice。

此外,他也认为使用者需要有其它可与微软Office竞争的产品,而ODF产品则是由许多私有程序及开放程序代码聚集而成,没有一个单一产品可以提供如此多的功能,而且还拥有全球支持的服务网络。

自从SUN自2000年建立OpenOffice.org项目后,该产品的下载数已接近1亿次,这是一个采用ODF文件格式及开放源码的免费办公室软件计划,包括企业及开发人员都可加入该社群并捐赠程序,目前主要的捐赠者仍为SUN。

posted @ 2008-12-02 20:13 hannover 阅读(71) 评论(0) 编辑
Lotus Notes/Domino是一种基于Internet/Intranet技术为构架的群件系统,是构造企业信息网主要工具之一。信息检索技术作为 LotusNotes/Domino的一个主要技术,为用户提供了包括全文检索、按关键字查询、视图和文件夹等多种方式, 本文结合在实际开发中的经验体会,对Notes应用中文档查询进行讨论。
文档的查询
---- 在LotusNotes中,信息是以文档的形式保存在数据库中的,一个文档相当于关系型数据库中的一个记录。 也就是说,在NOTES应用中,对信息的查询就是对文档的查询,对文档的查询主要有以下几种方式:视图、文件夹、全文检索。下面我们来一一探讨他们的特点。
---- 1. 视图
---- 视图是 LotusNotes中文档的主要浏览窗口,每一视图都包含符合一定条件的文档。当一个视图的选择条件给定以后,通过该视图所看到的文档就是符合条件的文档,如某一视图的选择条件为:Select form="请假单"; 则打开该视图后,我们所看到的文档都是请假单。视图除了有选择条件外,还可以按不同的特性将文档进行分类和排序,使得我们可以及其快捷地导航到要查找的文档。对于简单的查询,可以不编写任何程序,而通过把视图按合理的方式进行分类和排序就可以了。 Notes视图设计是应用程序设计过程中较快的一步,如果数据库第一次就设计正确,拥有在正确文档中可用的全部必需的字段,那么设计视图应是一个容易的过程,且对用户来说是直观的,可打印输出屏幕上显示的视图。
---- 2. 文件夹 文件夹也是文档的浏览窗口之一,但是和视图不同的是,文件夹没有选择条件,它里面的文档是通过Putinfolder来放进的,必须通过RemoveFromFolder来将其中的文档移开。
---- 3. 全文检索
---- 全文检索是 LotusNotes提供的基于数据库全文索引的搜索工具,它能根据给定的检索关键字在整个数据库中搜索,并把搜索结果显示在该视图的顶端。
---- 4. 按关键字查询
---- 好的查询设计应是对用户的查询给于准确快速的响应,准确,灵活地显示用户所需的数据。为满足用户多条件的组合查询,开发人员一般为用户设计一种"按关键字查询"方式,需要编写程序使用户可以输入一个或多个查询条件进行组合条件查询,找满足条件的文档。但是由于NOTES无法直接显示结果,一般的解决方法是:将查询结果存放到文件夹中,最后,打开文件夹显示查询结果。
文件夹方式存在的缺陷及解决方法
---- 由于LotusNotes的文档是可以共享的,文件夹也可以共享,也就是说,你可以用这个文件夹来存放你的检索结果,我也可以用这个文件夹来存放我的查询结果,而且LotusNotes应该保证互相不冲突。然而遗憾的是,LotusNotes不作这个保证,导致的结果是大家互相影响,产生访问冲突。为了解决这一问题我们提出两种方法:
---- 1、建立私有文件夹
---- 所谓私有文件夹,是指文件夹属于一人私有,其他人看不见这个文件夹。可以通过创建一个"启动后私有"文件夹,每个用户使用该文件夹后,系统立即根据这个启动后私有文件夹创建一个新的属于该用户的文件夹。这样,每个用户都有一个结构完全相同而且互相不干扰的文件夹。这种解决方法保证冲突不会产生,但系统为每个用户保存一个文件夹,会导致系统维护上的困难。如果系统的用户太多,情况会更坏。如果用户注销,它的私有文件夹不会自动删除。
---- 2、改进的视图方法
---- 视图一般是大家共享的,我们可以通过改进视图的选择条件,将视图作为我们存储查询结果的地方,就能避免文件夹方式产生的问题。我们提出解决问题的思路是:把满足某一用户查询条件的文档作选择标记,创建一个共享视图,用视图选择公式来显示该用户的查询结果,显示或打印完成后,删除选择标记。具体实现方法如下:
---- (1) 在要查询的数据库文档表单上创建一个可编辑多值的隐含域"SelectedUserName"用于存放查询该文档的用户名。
---- (2) 创建一个共享视图vwSelect,视图公式为:
---- SELECT Form = "frmFormName" &
---- @Contains(SelectedUserName;@UserName)
---- 用于显示该用户查到的文档
---- (3) 创建一个显示视图的导航器"nvgQueryResult",其初始视图为vwSelect。
---- (4) 用Sript语言,利用FTSearch函数进行组合条件查询,查找满足条件的文档。
编程实现
---- (1) 查询显示
---- 功能:完成按关键字条件查询,显示查询结果.
Dim session As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim view As NotesView
Set db = session.CurrentDatabase
itemvalues=item1.values
Condition=itemvalues(0)
For i=Lbound(itemvalues)+1 to
Ubound(itemvalues)
Condition=Condition+itemvalues(i)
'记载用户输入的全部查询条件
Next
Count=view.FTSearch(Condition,0)
'完成全文查找
If count〈〉0 Then
Messagebox"本数据库中共有:"+Str(Count) +
"个记录满足条件!",0+64,"提示信息"
For j=1 To count
Set doc=dc.getnthdocument(j)
Set item = doc.GetFirstItem( "SelectedUserName" )
Call item.AppendToTextList( session.UserName )
'在域SelectedUserName中
Call doc.Save( True, True )'追加用户名
Next
ServerName = session.GetEnvironmentString
("ServerName")
DirName = session.GetEnvironmentString
("DirectionName")
DatabaseName=DirName+"DBName.nsf"
'打开导航器调用视图,即显示查询结果
Call workspace.OpenDatabase ( ServerName,
DatabaseName,
"nvgQueryResult" )
Else
Messagebox "没有满足条件的记录!
",0 +48,"提示信息:"
End If
end
(2) 退出显示
功能:清除用户的选择标记
Dim session As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim view As NotesView
Set db = session.CurrentDatabase
' ViewName = session.GetEnvironmentString(
"envViewNa")
Set view = db.GetView(vwSelect)
Set doc = view.GetFirstDocument
UserName=session.UserName
'取现用户名到变量:UserName
While Not (doc Is Nothing )
TempValue=doc.SelectedUserName
'清除文档域"SelectedUserName"中
doc.SelectedUserName=""
'自己的用户名;
Call doc.save(True,False)
'同时保留其他用户的用户名.
Set item=doc.getfirstitem(
"SelectedUserName")
Forall x In TempValue
If x〈〉 UserName Then
Call item.AppendToTextList(x )
Call doc.save(True,False)
End If
End Forall
Set doc = view.GetFirstDocument
Wend
end

主要技术要点:
---- 以上应用设计主要运用了以下技术要点来保证显示结果的准确性和数据的共享性.
---- (1) 要查询的数据库文档表单上创建的可编辑多值的隐含域"SelectedUserName" . 域是构成表单的重要元素,对一个NOTES数据库来说,外部数据的录入要通过域, 库内存放数据显示也要依靠域。我们这里创建域"SelectedUserName"的作用是:存放查询该文档的用户名作为选择标志。
选择标志的确定:
---- 使用用户名作为选择标志主要因为在Notes中用户名是唯一的,不同的用户有不同的用户名,不会存在两个相同的用户名。这样,该域记住了有哪几个不同用户查询选择了此文档。为用视图显示文档做准备.
域的主要属性是:
---- 可编辑:数据可以通过按钮执行Formulas或Script来产生。
---- 隐含的:只作存储,没有显示作用。显示文档时不显示该域的数据准许多值,准许用户存入多个值,保证该域记录下选择该文档所有的用户名。因为在共享数据状态下,同一个文档同时可被多个用户查询选择,你必须记住所有选择该文档的用户名。这一点对于多用户下显示数据十分重要。
---- (2) 视图及视图选择公式:
---- 我们设计了一个共享视图vwSelect,视图公式为:
---- SELECT @Contains(SelectedUserName;@UserName)
---- 视图功能:显示所有域SelectedUserName中含有当前的用户名的文档。
---- @UserName:返回当前的用户名。
---- @Contains(SelectedUserName;@UserName):
---- 用于判断是否文档域SelectedUserName中含有当前的用户名; 因为在查询时,那些满足条件文档的域"SelectedUserName"中已被加入了用户名作为选择标志,所以该视图选择显示那些域SELECTEDUSERNAME中包含用户名的文档。
---- 在视图的设计时,使用"打开后废弃索引"选项。
小结
---- 综上所述,LousNotes为查询应用程序开发提供了灵活快速的环境,本文所述的几种方式都能实现对数据文档的查询检索,但是,它们的实现方法和满足的目的要求不尽相同。尽管还有不足之处需要完善, 但是仍然说明了一些能结合到你的应用程序中去的Notes技术,同时,我们必须清醒地认识到它与传统关系型数据库应用程序开发系统有很大的差别,查询设计有其独特的方式,一个应用程序能很快地被设计出来并且达到可用状态。试图将传统的应用程序开发技术映射到Notes环境中的开发人员,将很难获得Notes应用程序的优点。 

posted @ 2008-12-02 20:07 hannover 阅读(275) 评论(1) 编辑
LOTUS公司发布的群件产品-LOTUS NOTES是办公系统软件的成功应用案例之一,它凝结了企业级电子邮件、分布式文档数据库与快速应用开发等三位一体的强大技术,完全集成了INTERNET技术,提供给用户完整的,以网络为中心的应用技术平台,是目前最优秀的办公系统开发、运行平台。通过几年来的应用,在颇受其益的同时,也发现了其本身的一些缺陷。本文所述的服务器平台为WINDOWS NT,网络环境为TCP/IP,以此为例,将个人的一点薄见写出来与同行共勉。
1 客户端的安装
1.1 安装好WINDOWS 95/98后,增加MICROSOFT 网络用户,确定客户机和服务器之间能够以TCP/IP协议正常通信。 
1.2 在WINDOWS95/98的工作目录下(如c:windows)建立hosts文件,在里边说明notes服务器的IP地址和名字,举例如下(下边的hosts文件列出了3个notes服务器):
111.1.1.100 notesserver1
111.1.1.101 notesserver2
111.1.1.102 notesserver3
如果定义了NOTES SERVER的域名(如nserver.unit.com),就可以通过域名(nserver)访问服务器,无须建立hosts文件。
1.3 从系统管理员那里申请到合法用户的ID文件,将其保存到软盘或其他可搜索的介质上备用。
1.4 将notes的安装盘插入,运行CD盘上win32installinstall.exe 文件,开始安装,对一般用户来说,要选择“定制功能(C)-手动安装,选择想要安装的功能”一项,然后往下进行,依次选择“notes工作站”,“个人数据文件”,“附件阅览器”三项后,开始拷贝文件,并完成安装工作。
1.5 下边是配置notes工作站的过程:运行notes,选择协议TCP/IP和指定的NOTES服务器(如:nserver),选择从文件中读取用户标识符,从软盘上或其他可搜索介质上获取ID文件,即配置完毕,然后打开“文件”中的“数据库”选项,将应用图标加入就行了。至此,客户端安装完毕,可以投入使用了。
2 用户密码的设定和清除
客户端的用户一般都有进入系统的密码,如果不想设置密码,可选择“文件”中的“工具”,再选中“用户标识符”,然后键入密码进入系统,再按“清除口令”按钮,输入原密码,按“确定”后,口令就被清除了。当然,用上述方法可以重新设置口令。
3 引出文件的操作
NOTES数据库存放数据的格式有别于其他数据库,如ORACLE、SQL SERVER等数据库,数据是按行、列整齐存放的,而引出NOTES库里的数据时,看上去就有点乱。但这种操作频繁应用到。例如,我们将库里的数据引出,到Excel里边重排后打印正规报表文件时,选择引出的格式就有些学问,一般选择TABULAR TEXT格式最好,它带有字段间隔,层次比较分明。还可以用Lotus Script编制,做数据的引出(或引入)工作。
4 用户ID的问题
用户ID是有期限的,如果到了规定期限后,就会失效,用户无法继续使用,需要到管理员那里重新申请一个ID,然后再装入系统。
5 安装过程中必需的条件之一
在WINDOWS95/98系统下,根目录上的文件autoexec.bat和config.sys文件显得没什么作用,但是在安装notes时,必须安装autoexec.bat文件,并指出windows 95/98的工作路径,如:c:windows,否则,notes系统不能安装。
6 安装时的“无效的TCP/IP Server”信息
如果出现“无效的TCP/IP Server”信息,往往是因为网络不通引起的,安装客户端的同时,必须保证客户端和服务器畅通。
7 为什么Lotus Domino卸载后再次安装新的服务器时安装不上? 
因为windows95/98提供的卸载工具不能完全把Notes卸载干净,上一次服务器的一些配置信息并未删除,如果第二次安装的服务器配置与第一次不同,你还需要把windows 目录下的Notes.ini,以及NotesData文件夹下的server.id 和cert.id文件删除掉方可。
8 为什么启动Lotus notes 4.6的个人Web浏览器访问intranet有时不能成功? 
因为在notes4.6与4.5不同,其增强了对Web的支持,几乎不用做任何设置就可以正常上网。如果出现个人Web浏览器不能访问Web页面,大部分情况是由于用户上次退出Notes时标识符选择了server.id,从而再次启动Notes的 Web浏览器后出现权限不够的提示信息,只要此时选择工具,切换标识符,选择合适的用户标识符,问题即可解决。 
9 如何备份、恢复一个Notes服务器?
有时候,当一个Notes服务器因种种原因崩溃后,系统管理员需要重新生成该服务器,使得新生成的服务器和崩溃掉的服务器发挥同样作用。NOTE4.5中并没有提供一个实用工具实现服务器备份和恢复功能,所以系统管理员只能手工备份和恢复服务器。解决该问题的方法是:平时系统管理员手工备份服务器上的重要系统文件和应用数据库文件,重新生成该服务器时,利用备份的系统文件生成一个和原来一样的新服务器,然后重新安装应用系统,就可以实现服务器的恢复。系统管理员平时需要备份的系统文件包括:组织验证者标识符文件Cert.id、组织单元验证者标识符文件、服务器标识符文件Server.id、系统的公用通讯录文件names.nsf、系统管理员的用户标识符文件user.id、各个用户的标识符文件和邮箱文件、desktop.dsk、cache.dsk文件。以上这些文件通常都位于notesdata文件夹中。当第一次启动重新安装的服务器时,在“服务器设置”窗口中单击“高级选项”,出现“高级选项”窗口,在该窗口中,选掉“生成组织验证者标识符”、“生成服务器标识符”、“生成系统管理员用户标识符”,然后按“确定”按钮,关闭该窗口,继续服务器的设置过程。在接下来的设置过程中,系统会询问组织验证者标识符文件名、服务器标识符文件名和系统管理员用户标识符文件名,分别选择原服务器的组织验证者标识符文件、服务器标识符文件和系统管理员用户标识符的备份即可。当服务器设置完成后,用原服务器的公用通讯录文件、desktop.dsk、cache.dsk覆盖掉新服务器的同名文件,拷贝原服务器各个用户的邮箱文件的备份至新服务器相应的同名目录中,最后再拷贝原服务器上的应用系统文件的备份至新服务器相应的同名目录中。重新启动服务器即可。 
10 何通过软盘实现用户邮箱数据库文件的复制?
通过电话线远程安装设置Notes客户机效率很低,通常至少需要半个小时,主要原因在于在安装设置Notes客户机的过程中,系统需要通过电话线在本地客户机上建立该用户邮箱文件复本,这一过程很耗时且容易失败。实际上,可以先在其他Notes客户机上建立远程用户邮箱文件的复本,当然这个Notes客户机最好通过局域网和服务器相连,然后把该复本直接拷贝到远程Notes客户机上即可。 
11 如何实现NOTES客户机启动后,自动打开某一数据库?
启动Notes客户机,选择“文件”——“工具”——“用户惯用选项”菜单命令,打开“用户惯用选项”窗口,单击“启动选项”按钮,选择启动NOTES后需要自动打开的文档数据库名,单击“确定”按钮即可. 
12 如何实现Notes客户机启动时进行场所选择?
启动Notes客户机,选择“文件”——“工具”——“用户惯用选项”菜单命令,打开“用户惯用选项”窗口,选择窗口左边的“基本”图标,在“启动选项”中选中“提示选择场所”。这样,当Notes客户机启动时,会出现一个对话框,要求用户选择“场所”。 
13 如何快速删除Notes文档?
在NOTES中删除文档时,系统并不把文档马上删掉,通常先打上删除标记,在用户退出客户端时询问用户是否将文档永久删除,用户可以选择是否真的删除。这类似于win95中的回收站,可防止文档的误删除,但同时也给用户带来了不便,为了快速删除文档,可在打上标记后按F9键刷新,或者直接用剪切功能将文档直接删除。
14 如何同时访问多个通讯录地址?
如果你有多个通讯录数据库(names1.nsf,names2.nsf,names3.nsf),需要在发送邮件时可以同时选择不同通讯录中的用户,只需要修改notes.ini即可。
Names=names1.nsf,names2.nsf,names3.nsf
注:如果修改服务器上的notes.ini就可以供所有人选择使用,如果修改工作站的notes.ini仅能本地数据库使用。
15 安装Notes过程中必需的条件之一
在Windows 95/98系统下,根目录上的文件autoexec.bat和config.sys文件显得没什么作用,但是在安装Notes时,必须安装autoexec.bat文件,并指出Windows 95/98的工作路径,如:c:windows,否则,Notes系统不能安装。
16 关于QNC.EXE错误信息及其解决办法
在notes运行过程中,有时出现有下列提示的错误信息而退到DOS状态:
Aapplication error occurred in the program Unknown crash information will be saved to the file NOTES.RIP in C: otesdata Please report this crash to the vendor of the faulting application
解决的方法是:在c: otes目录下,运行qnc -u命令,再启动机器,以后就不会出现以上错误信息。其实这是 Notes的内存保护性措施,及时删除了Notes的文件也会显示,并显示找不到文件。因此需要修改注册表,把键名删除或其键值改掉即可。
[HKEY_LOCAL_MACHINESoftwareMicrosoftWindows NTCurrentVersionAeDebug]
"Debugger"="c:notesqnc.exe -p %ld -e %ld -g" 
如果不喜欢它可以在DOS下(或WINDOWS的“运行”中)键入qnc –u,系统提示:
使其不再运行。以后就不会出现以上错误信息。 如果你觉得还有必要的话可以再用qnc -i装载它。
17 将隐藏的数据库设计恢复
步骤如下:
17.1 新建一个空白数据库new.nsf,具有设计权限。
17.2 在Lotus Domino Designer中假装修改设计,使其在左边工具栏中留下快捷设计按钮。
17.3 退出所有Lotus Domino/Notes程序,在资源管理器中将new.nsf删除或重新命名,再将隐藏的数据库名称命名为new.nsf.
17.4 进入Lotus Domino Designer,发现new.nsf的快捷设计按钮还存在,进入即可修改new.nsf。但此时的new.nsf是已经隐藏设计的数据库文件了。
17.5 这个方法仅能恢复自己隐藏的设计,如果要恢复别人隐藏的设计需要注册同名同姓的ID,并且组织名称也要相同。
18 如何防止用户删除文档?
为了防止用户删除特定的文档,我们可以使用QueryDocumentDelete。
例如, 在文档中设定一个状态域 UnProcessed, 以下代码可以完成这个功能:
Sub Querydocumentdelete(Source As Notesuidatabase, Continue As Variant)
Dim coll As NotesDocumentCollection
Set coll = Source.Documents
Dim doc As NotesDocument
Set doc = coll.getFirstDocument()
While Not doc Is Nothing
If doc.UnProcessed(0) <> "" Then
Msgbox "You are not allowed to delete Unprocessed documents"
Continue = False
Exit Sub
End If
Set doc = coll.getNextDocument(doc)
Wend
Continue = True
Exit Sub
End Sub
19 如何判断RTF域为空?
假设有一个RTF域body ,是不可以用body=""来判断为空的,可以用以下程序来判断其是否为空。
首先定义:
Const lsERR_LSXUI_UNKNOWN_PROP = 4400 
Const lsERR_LSXUI_INVALID_ARGS = 4401 
Const lsERR_LSXUI_NO_WORKSPACE_WND = 4402 
Const lsERR_LSXUI_NO_DATABASE_WND = 4403 
Const lsERR_LSXUI_LSBE_DB_CREATE = 4404 
Const lsERR_LSXUI_NO_DOCUMENT_WND = 4405 
Const lsERR_LSXUI_LSBE_DOC_CREATE = 4406 
Const lsERR_LSXUI_DOC_CMD_NOT_AVAILABLE = 4407 
Const lsERR_LSXUI_FIELD_CMD_NOT_AVAILABLE = 4408 
Const lsERR_LSXUI_CMD_NOT_AVAILABLE = 4409 
Const lsERR_LSXUI_DOC_OBJ_NOT_VALID = 4410 
Const lsERR_LSXUI_DOC_SAVE_CANCELLED = 4411 
Const lsERR_LSXUI_NOTES_ERROR = 4412 
Const lsERR_LSXUI_INVALID_LSX = 4413 
Const lsERR_LSXUI_INVALID_STR_ARG = 4414 
Const lsERR_LSXUI_INVALID_NULL_ARG = 4415 
Const lsERR_LSXUI_NO_NOTE = 4416 
Const lsERR_LSXUI_MODALEDIT_DIALOGUP = 4417 
Const lsERR_LSXUI_QUERY_OPEN = 4418 
Const lsERR_LSXUI_INVALID_OBJ_ARG = 4419 
然后,在你的脚本中添加下面的程序
On Error Goto label1 
Dim ws As New notesuiworkspace
Dim uidoc As notesuidocument
Set uidoc=ws.currentdocument
Call uidoc.gotofield("body")
Call uidoc.selectall
Call uidoc.deselectall
Exit Sub
label1:
Messagebox("RTF IS NULL!")
Exit Sub
20 安装时的问题
若在某台安装了KILL杀病毒软件的机器上安装NOTES时,有时会出现“不能改变文件属性”的出错提示而退出,此时只要将驻留的KILL监控程序关掉,即可以顺利过关。 
posted @ 2008-12-02 20:02 hannover 阅读(352) 评论(0) 编辑