【第0099期2006/4/10】

本週主題

最新消息

 
  • ND7相關紅皮書.

詳細資訊請參閱以下網址:

Security Considerations in Notes and Domino 7: Making Great Security Easier to Implement

Lotus Notes and Domino 7 Enterprise Upgrade Best Practices

Lotus Domino 7 Application Development

Understanding Lotus Notes 7.0.1 Smart Upgrade

Domino 7 Server Consolidation and Performance Tuning - Best Practices to Get the Most Out of Your Domino Infrastructure

 

  • 一通科技與IBM合辦的Lotus 技術論壇研討會課程

此系列為提供給技術人員的一天課程

一人一機,有安裝與實作及經驗分享

歡迎大家報名!!

課程費用:免費

2006/04/12 QuickPlace 7 Training

2006/04/14 Sametime 7 Training

2006/04/19 WSE 2.5 Training

詳細資訊請參閱以下網址:

http://www.atc.com.tw

Top

文章分享

 

 

本文經作者同意刊登於智頡分享報,若在未經作者同意,擅自擷取文章中內容作為營利用途者,經查證屬實均視為侵權行為,作者保留法律追訴權。特此聲明!!


Lotus Notes程式設計隨筆(二)

作者 李建壹 Louis Lee(小路哥)

 

距離上一篇隨筆又過了10天,時間過的可真是飛快,所以不趕緊再寫這一篇,可能就真的又要中斷了,呵呵。

七、Notes應用系統

在進入開發元件的正題之前,我們先來聊聊什麼是Notes應用系統。通常Notes應用系統也稱為Notes應用程式、Notes AP…等等。儘管這些名詞都不同,但其實都是指使用Domino Designer這個設計介面所開發出來的系統,像是請假系統、加班申報系統、請採購系統、文具申購系統、ISO文件管理系統,甚至是ECN系統、NBR系統等等都屬之。我想稍微列出這些系統名稱,應該就可以稍微明瞭Notes不是只能用來當作電子郵件系統了吧。

一般初學者在還沒開始真正瞭解Notes應用系統時,通常會認為一個資料庫就是一支Notes應用系統。其實不盡然如此,絕大部分的Notes應用系統都是由一個以上的資料庫所組成。

舉例來說好了,就Louis的經驗,建議剛導入Notes而且要開始開發系統時,第一優先開發的應該是人員組織資料庫,這個資料庫主要在儲存企業人員組織資訊,像是部門文件與人員文件。為什麼要先開發建置這資料庫呢??因為使用者在許多系統的表單中,都有申請人的姓名、部門、工號等等基本資訊欄位,而這些欄位值強烈建議不要讓使用者輸入,而是由程式去人員組織資料庫中自動搜尋並帶出的(通常是利用@UserName取得的Notes名稱來當作關鍵值)。所以,拿請假系統來說好了,既然請假系統會跨資料庫到人員組織資料庫取值,這就算是由兩個資料庫來組成一個請假系統了。

當然,上述的例子是比較小型的例子,若要說又大型又比較有名的例子就屬Lotus Workflow了,因為其每一支系統都至少要有三個資料庫所組成-應用程式資料庫、人員組織資料庫、程序定義資料庫、設計儲存資料庫(選擇性)。

所以總結來說,一支Notes應用系統可以由一個或一個以上的Notes資料庫所組成。

註:若您對人員組織資料庫沒有什麼觀念的話,可以參考DominoClub網站的SnowMan專欄中的簡易員工資料庫。雖然SnowMan兄謙虛的說那是「簡易」員工資料庫,不過其實該有的基本元件都已經有了,可說是麻雀雖小五臟俱全。各位只要依據各公司自己的需求再添加欄位就可以很完整了。網址如下:

http://www.domino.idv.tw/bbs/bbs2002.nsf/($All)/CE248B5215DFAEC148256FC0005D9CDB?OpenDocument

八、欄位-ItemField

應該會有朋友覺得奇怪,為何Louis不是先介紹文件或是套表,反而是先介紹欄位呢??其實我在下筆時也有考慮過這問題,之後一方面認為如果先講文件與套表,可能要花比較多的時間與篇幅寫;另一方面覺得欄位是最基礎的觀念,而且在說明欄位觀念時也會稍微補充套表與文件的觀念,所以決定先說明欄位。

ItemField的中文翻譯通常都是「欄位」,所以常被搞混,但兩者其實是完全不同的。嚴格來說,Item是要透過文件屬性方塊才可以看到的後端欄位;Field則是在套表上才能看到的前端欄位。以下是針對兩者的特性期之間的關連性加以說明: 

Top

(一)Item

Notes資料在儲存上最基本的容器就是item。它可以儲存文字、數字、日期時間、附加檔案等等資料。也由於是儲存容器,所以要在文件儲存後才會產生,若文件還沒儲存是不會有Item存在的,您可以試著開啟一份新文件,然後打開文件屬性方塊看看就知道了。所以簡而言之,文件其實就是由item所組成的。Item本身也有其屬性,例如儲存在item中的資料長度、資料類型等等。而這些也可以從文件屬性方塊看到。

(二)Field

至於Field,簡單來說,在新文件上是要讓使用者輸入資料;而在已存在的文件上,則是用來顯示及編輯已儲存於Item中的資料,所以稱之為前端欄位,也就是說Field是用來與使用者互動的一個設計元件。既然是與使用者互動的設計元件,那就一定有某些方法可以達成此目的,就是透過field的程式,像是預設值公式、轉譯公式、驗證公式、數個事件都可以讓程式設計師撰寫程式以達到上述的互動目的。

(三)ItemField的連結

既然item是後端欄位,field是前端欄位,那就一定有方法將兩者連結起來。舉例來說,在一般狀況下,若在套表上有一個名為X1field,當文件儲存時,在此欄位中的數值就會儲存到名為X1item中。再假設一種狀況,假設套表上有一個名為X1field,在文件中另有一個名為Y1item,若要將Y1的數值顯示在X1 field的話,只要在X1 field的預設值公式或是計算公式填入Y1這個item名稱即可。

(四)LotusScriptItemField

因為這種前後端結構的觀念,所以在LotusScript中的NotesDocument類別下提供幾個方法來操作處理item,像是GetFirstItemGetItemValue…等等。如果程式設計師想要進一步處理item,則可以使用NotesItem的類別。這類後端的類別與方法通常是用來處理item中的數值。

至於操作處理Field的相關方法則被放在NotesUIDocument前端類別中,像是FieldGetTextFieldSetText等等。這類前端的類別與方法通常是用來與使用者達到互動。

九、套表

就官方的定義而言,套表是用來顯示動態資訊的。既然是顯示動態資訊,就表示其中的資訊是要讓使用者可以看的到,更深入一點,就是讓使用者可以透過套表來跟資料庫中的資料作互動。所以套表在Notes中真的佔有很重要的地位,而且應用層面甚廣,例如,單純顯示文件中的資訊、讓使用者輸入資料以建立文件、編輯文件中的資料以更新資訊、在套表事件或是其他元件加入程式以運算處理文件中的資料…等等。在ND6中則可以直接查詢RDB中的資料。ND7開始更可以和DB2資料庫做資料交易。

但是,回到原點,沒有任何其他設計元件存在的空套表是沒有實質意義的。所以當套表中存在field、按鈕、動作按鈕、小節、焦點資訊、有程式的事件…等等設計元件,才能發揮出套表的功效。相對於文件是許多item的容器,套表則是許多設計元件的容器。例如在Web上可以在套表中嵌入視界來美化視界在Web上的呈現。

再回到套表最主要的功能-建立與編輯文件。就建立新文件而言,當使用者在各field中輸入數值並儲存以後就會產生一份文件,而field中的數值則會儲存到該文件中的各item中。另一方面,當使用者利用套表開啟已經存在的文件時,套表的field通常就是用來顯示或編輯item的數值。

Top

十、文件

其實在上述中差不多已經把欄位、套表、文件的關係解釋的差不多了。所以在這兒我們就只稍做補充。

由於Item無法自行存在,而是必須存在於文件中,所以換言之,Notes文件可以說是包含一個以上Item的集合,這可說是一個抽象的觀念。其實有些人會認為視界有顯示出來或是套表可以打開的才算是文件,但其實不然,因為文件也有可能是「隱藏」在資料庫中而不顯示的。這就是常有人會看到工作區的資料庫顯示有未閱讀文件,但又在視界中找不到的原因。

另外,也有些人會認為文件跟套表是一體的,事實上也不然,套表與文件是分開的,就如同先前曾經提到,套表是為了讓使用者可以新增、編輯、顯示文件的。但也有例外,如果在套表屬性中有勾選文件與套表一起儲存的屬性時,文件與套表就會儲存在一起,但通常不建議如此做。因為把套表中的所有設計元件與文件合併儲存在一起,就會讓文件的體積變大,進而佔用硬碟空間。就像是本來只有55公斤的Louis穿上幾件衣服後,可能就增加到57公斤了。

另外,在Notes中還有一種特殊文件,就是設計文件,也就是開發者開發出來的設計元件,像是套表、視界…等等,也是以文件型態存在的,這些文件統稱為Design Notes,不過當然也可以稱為Design Document。在Domino Designer的設計元件清單中,使用滑鼠右鍵單擊任一元件,都可以看到該設計元件的文件屬性。順帶一提,在早期Notes文件並不稱為Document,而是稱為note,所以才有Lotus Notes這名字出現。

但是把話說回來,因為Notes文件的資料並無法像關聯式資料庫可以利用key值把各資料做互相關聯,所以產生一些資料處理上的不便。不過這類問題通常還是可以經由技術上來解決的。而且也因為如此,Notes才能成為各種關聯式資料庫的整合介面,不是嗎 ^_^

待續

李建壹 Louis Lee(小路哥)

2006/3/18

~最近天氣多變化,各位記得要照顧好身子骨別感冒囉~

 

 

Top

IBM最新文章訊息

 

 

訊息通知:

 

 

由於目前IBM台灣的developerWorks網站已經提供相當多的中文技術文章,故智頡分享報暫時已經不需要幫各位會員翻譯相關原文文章,故從本期電子報開始改成提供IBM最新文章訊息的相關連結,但是後續如有智頡分享自行撰寫的文章也會繼續分享給各位會員,不便之處,敬請見諒。


Lotus Notes and Domino Designer 7.0 Beta 3 中的新功能

 

本文將描述 Lotus Notes and Domino Designer 7.0 中引入的新功能。請閱讀本文,瞭解我們盡一切可能針對 Lotus Notes 用戶端、Domino Designer、Domino Web Access 和 Domino Access for Microsoft Outlook 進行的擴展和改進。

 

Lotus Domino 7.0 Beta 3 中的新功能

 
Lotus Notes/Domino 7.0 中引入的最重要的新功能可能會涉及 Domino 伺服器。本文將研究 Lotus Domino 7.0 中提供的主要新功能,其中包括更好的效能、更輕鬆的管理,以及與 Web 標準和 DB2、WebSphere Application Server 和 WebSphere Portal 等其他 IBM/Lotus 技術的更緊密整合。

另一篇文章 中,我們描述了 Lotus Notes and Domino Designer 7.0 中引入的新功能。在這一篇文章中,我們將介紹 Domino 7.0 伺服器的一些改進,其中包括:

  • 改進的效能和可伸縮性。
  • 管理和 TCO 方面的提高,包括 Domino Domain Monitoring、改進後的策略管理、自動的使用者端安裝和升級,以及其他功能。
  • 與行業標準以及包括 DB2 在內的其他 IBM/Lotus 產品進行整合。
  • 訊息傳遞和反垃圾郵件保護。
  • 安全性。
  • 目錄。

 

Lotus Notes/Domino 7 Web Services

 

Web Services 是 Lotus Notes/Domino 7 的新特性。本文介紹新 Web Services 設計元素,展示如何在 Domino Designer 中建立這種設計元素,並描述了如何用 LotusScript 和 Java 程式碼範例來實作 Web Services。

Web 服務是可以透過在 Internet 上發送訊息來呼叫的遠端操作的檔案。Web 服務供應商發佈用於查詢和使用的 Web 服務,而 Web 服務使用者呼叫來自這些服務的操作。Web 服務供應商提供了定義服務介面的 WSDL(Web Services Description Language,Web 服務描述語言)文件。WSDL 文件是 XML 格式的。介面的底層由供應商實作,但大多數供應商將介面映射為支援的程式設計語言的程序呼叫。來自使用者的入站請求傳遞給底層程式碼,然後結果回傳給使用者。

 

技巧:在 Lotus Notes 中驗證 Rich text 領域

 

該技巧描述了三種在 Lotus Notes 中驗證 Rich text 輸入的快速方法。第一種方法驗證的文件領域中,任何文件(包括單個空格字元)都是可接受的輸入。第二種方法驗證的領域中,要求至少有一個非空格文件。第三種方法驗證的領域中,可以不包含文件,但是可能包含附件、嵌入式物件或者連結。本文假設您具有使用 Domino Designer 和 LotusScript 開發應用程式的經驗。

 

 

Top

Lotus Notes 技術分享

 

如何在Web上允許關鍵字欄位輸入新值呢?

 

本期智頡分享報將為您介紹如何在Web上讓關鍵字欄位可以輸入新值,本次之範例乃根據

http://www.dhtmlgoodies.com 網站上之範例修改成Notes可以套用的,做法如下:

1.請先由以下網址下載三個圖片檔案,然後請將之放置於資料庫中的影像資源內.

http://www.wmmate.com/mail_img/select_arrow.gif

http://www.wmmate.com/mail_img/select_arrow_down.gif

http://www.wmmate.com/mail_img/select_arrow_over.gif

 

2.在資料庫中建立一新網頁,網頁名稱為editableselect.js

網頁中貼上如下之JavaScript程式:

:以下程式中有三個Notes的計算文字,三個計算文字之公式皆為:

"/"+@ReplaceSubstring(@Subset(@DbName;-1);"\\";"/")+"/"

 

/****************************************************************************************************

                (C) www.dhtmlgoodies.com, September 2005

                This is a script from www.dhtmlgoodies.com. You will find this and a lot of other scripts at our website.

               

                Terms of use:

                You are free to use this script as long as the copyright message is kept intact. However, you may not

                redistribute, sell or repost it without our permission.

               

                Thank you!

               

                www.dhtmlgoodies.com

                Alf Magne Kalleland

               

**************************************************************************************************/          

                // Path to arrow images

                var arrowImage = '<計算文字>select_arrow.gif';                // Regular arrow

                var arrowImageOver = '<計算文字>select_arrow_over.gif';         // Mouse over

                var arrowImageDown = '<計算文字>select_arrow_down.gif';       // Mouse down

                var selectBoxIds = 0;

                var currentlyOpenedOptionBox = false;

                var editableSelect_activeArrow = false;

                function selectBox_switchImageUrl()

                {

                                if(this.src.indexOf(arrowImage)>=0){

                                                this.src = this.src.replace(arrowImage,arrowImageOver);

                                }else{

                                                this.src = this.src.replace(arrowImageOver,arrowImage);

                                }

                }

               

                function selectBox_showOptions()

                {

                                if(editableSelect_activeArrow && editableSelect_activeArrow!=this){

                                                editableSelect_activeArrow.src = arrowImage;                                    

                                }

                                editableSelect_activeArrow = this;

                                var optionDiv = document.getElementById('selectBoxOptions' + this.id.replace(/[^\d]/g,''));

                                if(optionDiv.style.display=='block'){

                                                optionDiv.style.display='none';

                                                this.src = arrowImageOver;  

                                }else{                                     

                                                optionDiv.style.display='block';

                                                this.src = arrowImageDown;

                                                if(currentlyOpenedOptionBox && currentlyOpenedOptionBox!=optionDiv)currentlyOpenedOptionBox.style.display='none';

                                                currentlyOpenedOptionBox= optionDiv;

                                }

                }

               

                function selectOptionValue()

                {

                                var parentNode = this.parentNode.parentNode;

                                var textInput = parentNode.getElementsByTagName('INPUT')[0];

                                textInput.value = this.innerHTML;

                                this.parentNode.style.display='none';   

                                document.getElementById('arrowSelectBox' + parentNode.id.replace(/[^\d]/g,'')).src = arrowImageOver;

                }

                var activeOption;

                function highlightSelectBoxOption()

                {

                                if(this.style.backgroundColor=='#316AC5'){

                                                this.style.backgroundColor='';

                                                this.style.color='';

                                }else{

                                                this.style.backgroundColor='#316AC5';

                                                this.style.color='#FFF';

                              }               

                               

                                if(activeOption){

                                                activeOption.style.backgroundColor='';

                                                activeOption.style.color='';

                                }

                                activeOption = this;

                               

                }

               

                function createEditableSelect(dest)

                {

                                dest.className='selectBoxInput';        

                                var div = document.createElement('DIV');

                                div.style.styleFloat = 'left';

                                div.style.width = dest.offsetWidth + 16 + 'px';

                                div.style.position = 'relative';

                                div.id = 'selectBox' + selectBoxIds;

                                var parent = dest.parentNode;

                                parent.insertBefore(div,dest);

                                div.appendChild(dest);

                                div.className='selectBox';

                                div.style.zIndex = 10000 - selectBoxIds;

                                var img = document.createElement('IMG');

                                img.src = arrowImage;

                                img.className = 'selectBoxArrow';                  

                                img.onmouseover = selectBox_switchImageUrl;

                                img.onmouseout = selectBox_switchImageUrl;

                                img.onclick = selectBox_showOptions;

                                img.id = 'arrowSelectBox' + selectBoxIds;

                                div.appendChild(img);                          

                                var optionDiv = document.createElement('DIV');

                                optionDiv.id = 'selectBoxOptions' + selectBoxIds;

                                optionDiv.className='selectBoxOptionContainer';

                                optionDiv.style.width = div.offsetWidth-2 + 'px';

                                div.appendChild(optionDiv);                

                                if(dest.getAttribute('selectBoxOptions')){

                                                var options = dest.getAttribute('selectBoxOptions').split(';');

                                                var optionsTotalHeight = 0;

                                                var optionArray = new Array();

                                                for(var no=0;no<options.length;no++){

                                                                var anOption = document.createElement('DIV');

                                                                anOption.innerHTML = options[no];

                                                                anOption.className='selectBoxAnOption';

                                                                anOption.onclick = selectOptionValue;

                                                                anOption.style.width = optionDiv.style.width.replace('px','') - 2 + 'px';

                                                                anOption.onmouseover = highlightSelectBoxOption;

                                                                optionDiv.appendChild(anOption);        

                                                                optionsTotalHeight = optionsTotalHeight + anOption.offsetHeight;

                                                                optionArray.push(anOption);

                                                }

                                                if(optionsTotalHeight > optionDiv.offsetHeight){

                                                                for(var no=0;no<optionArray.length;no++){

                                                                                optionArray[no].style.width = optionDiv.style.width.replace('px','') - 22 + 'px';

                                                                }

                                                }

                                                optionDiv.style.display='none';

                                                optionDiv.style.visibility='visible';

                                }

                                selectBoxIds = selectBoxIds + 1;

           }

 

3.請將該網頁的將網頁內容視為HTML”屬性勾選起來.

 

4. 建立一名為”EditableSelect”的套表,套表的最上方貼上如下之程式,並將之標記當成HTML文字:

:以下程式中有一個Notes的計算文字,該計算文字之公式為:

"/"+@ReplaceSubstring(@Subset(@DbName;-1);"\\";"/")+"/"+"editableselect.js"

<style type="text/css">

                body{

                                background-repeat:no-repeat;

                                padding-top:85px; 

                                font-family: Trebuchet MS, Lucida Sans Unicode, Arial, sans-serif;

                                font-size:0.9em;

                                line-height:130%;

                }

                .selectBoxArrow{

                                margin-top:1px;

                                float:left;

                                position:absolute;

                                right:1px;

                }             

                .selectBoxInput{

                                border:0px;

                                padding-left:1px;

                                height:16px;

                                position:absolute;

                                top:0px;

                                left:0px;

                }

                .selectBox{

                                border:1px solid #7f9db9;

                                height:20px;

                }

                .selectBoxOptionContainer{

                                position:absolute;

                                border:1px solid #7f9db9;

                                height:100px;

                                background-color:#FFF;

                                left:-1px;

                                top:20px;

                                visibility:hidden;

                                overflow:auto;

                }

                .selectBoxAnOption{

                                font-family:arial;

                                font-size:12px;

                                cursor:default;

                                margin:1px;

                                overflow:hidden;

                                white-space:nowrap;

                }

                </style>

<script src="<已計算完值>"></script>

5.在該套表上建立一欄位,欄位名稱為Keyword,請勿將該欄位類型設定成對話清單型欄位,而只要設定成一般文字欄位即可.然後在該欄位的HTML屬性中輸入如下之公式,公式中的Item值即為選項清單,故您可將之修改成您要的選項清單.

6. 最後請在套表的最下方插入如下之程式,並將之標記當成HTML文字:

<script language="javascript">

createEditableSelect(document.forms[0].Keyword);

</script>

7. 同一套表如有多個關鍵字選項時,請按照步驟5的方式建立另一關鍵字欄位(Keyword2為例),然後將步驟6的程式修改成如下即可:

<script language="javascript">

createEditableSelect(document.forms[0].Keyword);

createEditableSelect(document.forms[0].Keyword2);

</script> 

8. 使用畫面如下:

 

:如有需要可至智頡科技網站(http://www.wmmate.com)下載範例資料庫。  

Top

近期電子報內容預告

後續陸續會發行相關技術的電子報

內容預告如下:

Lotus Notes系統整合&應用介紹

  內容相當豐富敬請期待...

Top


註:如不想繼續收到本公司之電子報或是要介紹朋友訂閱電子報請至本公司網站線上設定/訂閱


智頡科技股份有限公司

Copyright 1999-2006     版權所有 轉載必究

TEL:03-5326262       FAX:03-5344873        Email:support@wmmate.com