Adding numbering to documents in Xpages

前提是你 提交于 2019-12-07 00:26:36

Here is the code that you will need based on some of the comments to the question.

function simplegetSequentialNumber(){
    synchronized(applicationScope){
        var newSeqNum:Int = 0;
        if (applicationScope.containsKey("seqNumber")){
            newSeqNum = applicationScope.get("seqNumber") + 1;
            applicationScope.put("seqNumber",  newSeqNum);
            var seqView:NotesView = database.getView("vw_SequentialNumberStore");
            var seqNumberDoc:NotesDocument = seqView.getFirstDocument();
            seqNumberDoc.replaceItemValue("seqNumber",applicationScope.get("seqNumber"));
            seqNumberDoc.save(true,true);
        } else {
            var seqView:NotesView = database.getView("vw_SequentialNumberStore");
            try {
                var seqNumberDoc:NotesDocument = seqView.getFirstDocument();
                applicationScope.put("seqNumber",seqNumberDoc.getItemValueInteger("seqNumber") + 1);
                seqNumberDoc.replaceItemValue("seqNumber",applicationScope.get("seqNumber"));
                seqNumberDoc.save(true,true);
                newSeqNum = applicationScope.get("seqNumber");
            } catch(e) {
                var seqNumberDoc:NotesDocument = database.createDocument();
                seqNumberDoc.replaceItemValue("Form","cPanel");
                seqNumberDoc.replaceItemValue("seqNumber",1);
                applicationScope.put("seqNumber", 1);
                seqNumberDoc.save(true,true);
                newSeqNum = 1;
            }
        }
    }
    var seqNNNN:String = ("0000" + newSeqNum.toString()).slice(-4);
    return seqNNNN;
}

As you can see it first gets the next sequential number in a synchronized block, adds one to it and then puts the number back into the applicationScope.

Then it converts it to the string, adds the additional 4 zeros and then the right 4 characters from it. This returns a string and needs to be stored in a text field. You cannot store it in a number field because Notes will automatically drop the leading zeros from the value.

You can test this function by adding it to a server side javascript library and then including it in a simple page that runs a repeat control to repeat a computed field that just calls the function. Here is my test page.

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
    <xp:this.resources>
        <xp:script src="/seqNum.jss" clientSide="false" />
    </xp:this.resources>
    <xp:repeat id="repeat1" rows="30" value="#{javascript:30}">
        <xp:text escape="true" id="computedField1"
            value="#{javascript:simplegetSequentialNumber();}" />
        <xp:br id="br1" />
    </xp:repeat>
</xp:view>

As long as you are on a single server it is quite straight forward. The very moment you have a cluster or replicating databases it gets as complicated as it can be. For the single server case:

create a function nextNumber() that uses the synchronized keyword in SSJS. You cache the last number in memory and only read it from a profile document when starting. You can do that in Java or SSJS. Matt has an article explaining cache and synchonized: http://mattwhite.me/blog/2009/9/14/on-synchronization-in-xpages.html

I have created something similar for an order number generator. Look at storing the last used numberId in a central document and then getting/updating the numberId in a 'synchronized' thread.

Declan Lynch has blogged about the method: http://www.qtzar.com/blogs/qtzar.nsf/Blog.xsp?entry=in00zx5i0r9c

Newbs

We have used a similar approach to the others described here with the addition of a specified numbering server in the numbering control document. I implemented it into a java bean recently to improve both performance and conflict avoidance (and to learn how those things work).

If the user making the request is not on the numbering server they get a temporary number which is very ugly, but most likely unique in that it includes the time in milliseconds. An agent running on the numbering server detects these temporary numbers and issues the official number. We even have an option to send the requester an email with the official number when it is issued.

For a variety of reasons I cannot open source this feature, but you have enough here that you can try it.

We do document numbers by accessing a sequence number document that we create to store the next number in. Here is the ssjs function I use to access it. The sequence document has a Tag field and a NextNumber field. Tag usually looks like "USA-2011-", so final number looks like: "USA-2012-00001"

function getDocumentNumber(tag:String){
    var doc:NotesDocument = document1;
    if(doc.getItemValueString("DocumentNumber")=="-"){
        var seqView:NotesView = database.getView("(Sequence Number)");
        var seqNumberDoc:NotesDocument=seqView.getDocumentByKey(tag);
        var seqnum = seqNumberDoc.getItemValueInteger("NextNumber");
        var seqNNNN = @Right("00000" + @Text(seqnum),5);
        var docNumber:String = tag + seqNNNN;
        seqNumberDoc.replaceItemValue("NextNumber",seqNumberDoc.getItemValueInteger("NextNumber") + 1);
        seqNumberDoc.save(true,true);
        return docNumber;
    }
}

Call the function from the the querySaveDocument event or some other appropriate event.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!