| 
| 
| 一 概述 在使用 Designer開發(fā)B/S模式的應(yīng)用時(shí),JavaScript、LotusScript和Formula是我們主要用到的三種開發(fā)語言。它們在各自的位置都有著很強(qiáng)勁的優(yōu)勢。
 1. JavaScript因?yàn)橹荒苋〉脼g覽器端的數(shù)據(jù),不能訪問Notes DOM;所以,主要用在瀏覽器端的數(shù)據(jù)驗(yàn)證、信息提示等對當(dāng)前Brows窗口操作易的用性功能。
 
 2. LotusScript能訪問Notes DOM。在Notes客戶端可以取得當(dāng)前文檔的數(shù)據(jù),但是,因?yàn)槠錈o法直接在瀏覽器端工作;所以在B/S模式的應(yīng)用中LotusScript只能在服務(wù)器端工作,我們通過編寫LotusScript代理來實(shí)現(xiàn)其強(qiáng)大的文檔處理能力。
 
 3. Formula能訪問后臺數(shù)據(jù),語言簡潔,數(shù)據(jù)處理能力較弱,不能在瀏覽器端工作。Formula主要使用在元素的顯示控制以及域值的計(jì)算公式及簡單的數(shù)據(jù)處理方面。
 這三者使用的范圍和處理能力各不相同。在應(yīng)用中將其三者綜合起來使用,會使應(yīng)用的各方面功能大大增強(qiáng)。
 
 二 由JavaScript向代理(LS\FL)通信
 
 一般情況下JavaScript向代理的通信,使用url command。即如下格式:http://Host/Database/AgentName?OpenAgent&參數(shù)。這類操作可以用來解決數(shù)據(jù)查詢、文檔刪除等任務(wù)。這類操作的特點(diǎn)是可以帶參數(shù),但是取不到瀏覽器端的當(dāng)前文檔,無法對瀏覽器端的文檔進(jìn)行處理。
 那么,為什么要使用JavaScript向代理通信,并讓代理取得瀏覽器端的當(dāng)前文檔呢?先看一個(gè)例子:
 在某申請系統(tǒng)中,用戶創(chuàng)建新申請可以這樣做:打開新的申請單,填寫各項(xiàng)目后,點(diǎn)擊操作按鈕“提交申請”,就完成了操作。對設(shè)計(jì)者而言觸發(fā)“提交”操作必定運(yùn)行一個(gè)代理或一段公式(此處我們先假定提交操作運(yùn)行的是代理,后面將介紹提交操作運(yùn)行公式的情況)。在真正運(yùn)行代理的“提交”之前,系統(tǒng)一定要進(jìn)行數(shù)據(jù)合法性的驗(yàn)證。最簡單的做法是在每個(gè)域里面寫入驗(yàn)證公式,或者在代理里寫入驗(yàn)證數(shù)據(jù)合法性的代碼。但是,這類做法的共同的缺點(diǎn)是:即使數(shù)據(jù)不合法,服務(wù)器端和瀏覽器端也發(fā)生了交互,占用帶寬、影響網(wǎng)絡(luò)速度。并且,出錯提示信息只能以網(wǎng)頁形式輸出在原窗口上。這樣,就會使原窗口中的信息丟失,不方便用戶修改原來的數(shù)據(jù)。
 針對這種情況,我們想讓域的驗(yàn)證工作在瀏覽器端執(zhí)行。并且,出錯提示使用彈出窗口。JavaScript正能符合要求,但是難點(diǎn)就在:一旦驗(yàn)證通過怎樣調(diào)用代理?
 解決的辦法是:
 1. 保持“提交申請”操作按鈕和提交代理不變。在瀏覽器端預(yù)覽表單,點(diǎn)擊右鍵查看源文件,找出“提交申請”操作按鈕的onclick事件中的代碼。
 
 2. 新建一個(gè)同樣名為“提交申請”操作按鈕,將原來的“提交申請”操作按鈕隱藏。在新建的操作按鈕中寫入域驗(yàn)證信息JavaScript代碼,如果驗(yàn)證通過則執(zhí)行第一步的代碼。如果不通過則使用alert彈出窗口,提示出錯信息。
 3. 注意:每增減一次操作按鈕,都會影響原“提交申請”操作按鈕的onclick事件代碼。所以,比較好的辦法是將原來的“提交申請”操作按鈕作成共享操作。
 
 以上做法是我們在工作流模版里使用的方法。現(xiàn)在,我們有一種改進(jìn)方法:
 1。不用原來的操作按鈕,把觸發(fā)提交代理的寫在一個(gè)按鈕(button)里,給該按鈕命名(假設(shè)為“b1”,在其屬性框中找到html選項(xiàng)卡“name”欄中填為“b1”),用css將該按鈕隱藏。(同樣在tml選項(xiàng)卡中,在“style”欄填入“visibility: hidden”)
 
 2。新建一個(gè)名為“提交申請”的操作按鈕,在按鈕中寫入域驗(yàn)證信息JavaScript代碼,如果驗(yàn)證通過則執(zhí)行“ document.forms[0].b1.onclick()”(此處的b1是上一步我們假設(shè)的按鈕name)。如果不通過則使用alert彈出窗口,提示出錯信息。
 
 3。注意如果有多個(gè)這種操作在同一個(gè)表單里,那么按鈕的name必須不同。對按鈕的調(diào)用顯然也應(yīng)該根據(jù)其name。
 
 縱觀兩種用JavaScript調(diào)用代理的方法,各有特點(diǎn)。使用urlcommand比較方便易用,但缺點(diǎn)是取不到瀏覽器端的當(dāng)前文檔,代理很多強(qiáng)大的功能無法展開。使用第二種方法,實(shí)際上是JavaScript通過調(diào)用操作按鈕,間接調(diào)用了代理。這種方法功能強(qiáng)大,但是,創(chuàng)建和維護(hù)都稍顯復(fù)雜。最后指出:所謂使用JavaScript調(diào)用Formula,也就是指用JavaScript調(diào)用操作按鈕,而操作按鈕則中執(zhí)行的是各類對文檔進(jìn)行操作的Formula。即用JavaScript間接調(diào)用了Formula。
 三 由代理向JavaScript通信
 
 使用代理向JavaScript通信,可以分為用代理寫出JavaScript程序和用代理設(shè)置JavaScript參數(shù)。
 [一]用代理寫出JavaScript程序。
 我們可以使用代理中的print系統(tǒng)函數(shù),在窗口打印信息。這些信息為瀏覽器認(rèn)做HTML語句來解釋。這樣我們就可以用print函數(shù)在代理中寫JavaScript程序。
 例如以下代碼片段:
 If dc.count=0 then
 ‘dc為在前面程序里使用database.search得到的DocumentCollection
 Print "<SCRIPT LANGUAGE=JavaScript>"
 Print "alert(""沒有找到相關(guān)文檔,請和管理員聯(lián)系。"")"
 Print "location.href = ""/Web+test.nsf/Main+View?OpenView"""
 Print "</SCRIPT>"
 End if
 該段代碼執(zhí)行如下功能,判斷如果當(dāng)前搜索得到的文檔集為空,就在瀏覽器端顯示出錯信息,然后將窗口路徑指向某視圖。
 
 再看一個(gè)代碼片段:
 
 flag =curdoc.save(True,False)
 If flag Then
 Print "<OBJECT id=closes type=""application/x-oleobject""classid=""clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"">"
 Print " <param name=""Command"" value=""Close""> </object>"
 Print "<script>"
 Print "window.setTimeout(‘closes.Click()‘,1000)"
 Print "</script>"
 Print "<h4>個(gè)人選項(xiàng)保存成功。</h4>"
 End If
 該段代碼執(zhí)行如下功能,判斷如果當(dāng)前文檔保存成功,就在瀏覽器端顯示確認(rèn)信息,隨即關(guān)閉窗口。
 
 使用代理寫JavaScript程序我們可以做出許多有效、方便的功能來。比如動態(tài)的信息展播等。
 
 [二]用代理設(shè)置JavaScript參數(shù)。
 這里JavaScript是表單中寫好的,但是JavaScript的某些參數(shù)可能使用表單中某些域的值。這樣用代理設(shè)置了該域的值也就設(shè)置了JavaScript參數(shù)。
 例如:某系統(tǒng)用戶要求在申請單中的“編號”字段用戶能手動填寫,但是又要能保證:如有重復(fù)的號碼,系統(tǒng)要給與提醒。
 解決辦法就是:
 1. 使用webquaryopen事件運(yùn)行代理,使其將所有已經(jīng)編號文擋的編號值都以逗號隔開,放入文檔的某域中。
 2. 而在表單內(nèi)則寫入JavaScript代碼。將該域的值取出作參數(shù),再將該參數(shù)以逗號隔開取得字符串?dāng)?shù)組。
 3. 最后在域有效性驗(yàn)證時(shí),比較當(dāng)前的編號是否存在于數(shù)組中,若是則返回出錯,否則成功。
 
 比較以上介紹的兩種方法。第一種方法:因?yàn)镴S代碼都由代理寫出來,所以形式更靈活、功能更強(qiáng)大。但是,由于代碼是Print出來的,無法和文檔在窗口共存;所以,這種方法一般使用在信息展示方面。第二種方法:由于大部分代碼是在瀏覽器端寫好的,所以功能相對單一。因?yàn)榇硗ㄟ^修改域值影響JavaScript代碼;所以,一般用在文檔處理方面。
 四 由Formula向JavaScript通信
 
 Formula調(diào)用JavaScript。與代理調(diào)用JavaScript的第2條十分相似。但是,因?yàn)镕ormula能控制表單元素的顯示屬性。而Agent能訪問更多的數(shù)據(jù),所以Formula與Agent各有千秋。
 這里介紹一個(gè)比較有趣的例子,就是怎樣使文擋按條件自動編輯。即某些情況下文擋打開時(shí)為閱讀狀態(tài)。另一些情況,文檔打開時(shí)則為編輯狀態(tài)。顯然,設(shè)置表單的自動編輯功能是無法完成功能的。
 做法:
 1. 在表單建立JavaScript函數(shù)autoedit。
 
 2. 函數(shù)中寫入代碼取得當(dāng)前窗口路徑,將路徑最后幾個(gè)字符opendocument替換成editdocument,然后存在變量mypath中。
 3. 假設(shè)文檔是否自動編輯的判斷條件是當(dāng)前用戶在公共通訊錄里的個(gè)人文檔的“myauto”字段是否為“yes”。那么在JavaScript函數(shù)“autoedit”中寫JavaScript代碼:t=<此處為計(jì)算文本>,計(jì)算文本的公式為“@dblookup(""; "" : "names.nsf" ; "people"; @name([ cn ] ; @username) ; "myauto")”。
 4. 在JavaScript函數(shù)“autoedit”中加入代碼,判斷t是否為“yes”,若是則為將window.location置為mypath。然后將本段代碼設(shè)置為在編輯狀態(tài)下隱藏。
 5. form的onload事件中加入JavaScript代碼,調(diào)用autoload函數(shù)。
 
 注:以上文檔是我在學(xué)校里時(shí)寫的,現(xiàn)在看來有些觀點(diǎn)難免有點(diǎn)牽強(qiáng),實(shí)例也不夠生動;貼上來權(quán)作拋磚引玉。
 程序開發(fā)總結(jié)之二
 
 我如何在頁面上建立一個(gè)熱點(diǎn),讓它打開一個(gè)文檔?
 答: 在頁面上寫一段文字,然后選上這段文字,然后點(diǎn)菜單”創(chuàng)建” –熱點(diǎn)--操作熱 點(diǎn).然后選LotusScript ,舉個(gè)例子,比如打開ID 為NT00000C62的文檔:
 Sub Click(Source As Button)
 Dim uiworkspace As New notesuiworkspace
 Dim curdatabase As notesuidatabase
 Dim database As notesdatabase
 Dim doc As notesdocument
 Set curdatabase = uiworkspace.currentdatabase
 Set database = curdatabase.database
 Set doc = database.getdocumentbyid("00000C62")
 Call uiworkspace.EditDocument(True,doc,False )
 End Sub
 我如何實(shí)現(xiàn)歸檔,比如我如何把當(dāng)前視圖中所有被選中的文檔歸入文件夾 fold 中?
 答: 用Script象如下這樣實(shí)現(xiàn):
 Sub AddDocToFold(fold As String)
 Dim uiworkspace As New notesuiworkspace
 Dim uiview As notesuiview
 Dim doc As NotesDocument
 Dim docList As String
 Set uiview = uiworkspace.currentview
 For j = 1 To uiview.Documents.Count
 Set doc = uiview.Documents.GetNthDocument(j)
 Call doc.PutInFolder( fold )
 Next
 End Sub
 我如何實(shí)現(xiàn)把某文件夾視圖中的被選擇的文檔從該文件夾中清除,但卻不能刪除他們?
 答: 用Script 實(shí)現(xiàn)如下:
 Sub RemoveDocFromFold( fold As String,all As Integer)
 ‘功能:
 ‘ 把文檔從某個(gè)文件夾中移走,但并不刪除此文檔
 ‘參數(shù):
 ‘ fold: 文件夾
 ‘ all : 0表示僅移走當(dāng)前選擇的文檔,1表示移走該文件夾中所有文檔
 Dim uiworkspace As New notesuiworkspace
 Dim uiview As notesuiview
 Dim doc As NotesDocument
 Dim view As notesview
 Set uiview = uiworkspace.currentview
 Set view = uiview.view
 If all = 0 Then ‘移去所選文檔
 For j = 1 To uiview.Documents.Count
 Set doc = uiview.Documents.GetNthDocument(j)
 Call doc.RemoveFromFolder( fold )
 Next
 Else
 If all=1 Then ‘移去全部文檔
 Set doc = view.GetFirstDocument
 ‘遍列該視圖的所有文檔,獲取所有滿足條件的紀(jì)錄數(shù)
 While Not(doc Is Nothing)
 Call doc.RemoveFromFolder( fold )
 Set doc = view.GetNextDocument(doc)
 Wend
 End If
 End If
 ‘Evaluate("@Command([ViewRefreshFields])")
 End Sub
 我如何把當(dāng)前視圖中的所有的被選擇的文檔的某個(gè)域的值替換掉?
 答: 用Script 實(shí)現(xiàn)如下:
 Sub SelectedDocFieldReplace( Field As String,repval As String)
 ‘功能:
 ‘ 把所選文檔中的每個(gè) Field 域的值 改為 repval
 ‘參數(shù):
 ‘ Field 要更改的域的名稱
 ‘ repval 修改后的域值
 Dim uiworkspace As New notesuiworkspace
 Dim uiview As notesuiview
 Dim doc As NotesDocument
 Dim order_num As String
 ‘order_num = Inputbox$("請輸入批次")
 Set uiview = uiworkspace.currentview
 For j = 1 To uiview.Documents.Count
 Set doc = uiview.Documents.GetNthDocument(j)
 On Error Goto lable1
 Call doc.replaceitemvalue(Field,repval)
 Call doc.save(True,False)
 Next
 Exit Sub
 lable1:
 Msgbox("錯誤!,所選文檔沒有指定的域,這個(gè)錯誤發(fā)生在沒有給 selectedDocFieldReplace() 函數(shù)傳遞正確的參數(shù)")
 Exit Sub
 End Sub
 我如何創(chuàng)建某個(gè)程序運(yùn)行結(jié)果的日志文檔?
 答: 首先新建一個(gè)日志文檔的表單,并把該表單設(shè)置成數(shù)據(jù)庫的默認(rèn)表單,然后 就用Script創(chuàng)建文檔,并填寫該文檔中某些域的值,最后存盤,例子程序片段如下:
 ‘寫傳真日志
 Dim faxerdoc as notesdocument
 ‘faxerr_receiver,faxerr_docnum,faxerr_content是表單form_faxerr的三個(gè)域名
 ‘
 Set faxerrdoc = New NotesDocument( db )
 faxerrdoc.Form = "form_faxerr"
 Call faxerrdoc.replaceitemvalue("faxerr_receiver",Cstr(peoplecount) )
 Call faxerrdoc.replaceitemvalue("faxerr_docnum",strsucssnding )
 Call faxerrdoc.replaceitemvalue("faxerr_content",faxerrmsg )
 success = faxerrdoc.ComputeWithForm( False, False )
 If success Then
 Call faxerrdoc.Save( True, False )
 Else
 Msgbox("無法寫入傳真日志....")
 End If
 ‘Msgbox(faxerrmsg)
 Exit Sub
 我要從當(dāng)前視圖中選擇一批文檔,并讓程序從這些文檔中提取信息,在嵌入在表單中的OLE對象Word文檔中建立一張表,要求是選擇了幾篇文檔就在這張表中畫幾行,這張表的每個(gè)列的信息都中文檔中的域中提取,換句話說,就是要把被選文檔以Word文檔表格的形式表示出來,能否給我一個(gè)這方面的例子程序?
 答: 可以,下面就是這樣的一個(gè)例子:
 Sub inputgroupplan(source As notesuidocument,doccollection As notesdocumentcollection)
 ‘功能: 自動生成出團(tuán)計(jì)劃表。
 ‘ 詳細(xì)描述:
 ‘ 從 文檔集合 doccollection 中提取各個(gè)域值,并把提取的信息以一定
 ‘ 的表格形式送入當(dāng)前文檔的 body 域中的 OLE 對象--Word 文檔中.
 ‘參數(shù):
 ‘ source: 當(dāng)前文檔
 ‘ doccollection :文檔集(比如文檔的選擇集)
 
 Dim session As New NotesSession ‘當(dāng)前會話
 Dim counter As Integer ‘計(jì)數(shù)器
 Dim doccustom As NotesDocument ‘notes 文檔對象
 Dim thisdoc As Variant ‘Word 文檔對象
 Dim thisrange As Variant ‘Word 開發(fā)中的 range 對象
 Dim thispicture As Variant ‘嵌入Word 文檔的圖象對象
 Dim thistable As Variant ‘嵌入Word 文檔的表格對象
 Dim pagehead As String ‘嵌入Word 標(biāo)題
 ‘獲取嵌入文檔的句丙
 If source.EditMode Then
 Set thisdoc = source.getobject("oleobject")
 ‘插入一幅圖
 Set thispicture = thisdoc.shapes.Addpicture("c:\學(xué)習(xí)\cassiatb.jpg")
 ‘設(shè)置圖像屬性
 With thispicture.wrapformat ‘環(huán)繞方式
 .type = wdwrappicture ‘類型為picture
 .side = wdwrapright ‘文字右環(huán)繞
 End With
 ‘設(shè)置該文檔的頁面設(shè)置的左邊距為20個(gè)單位(象素)
 With thisdoc.pagesetup
 .leftmargin = 20
 .rightmargin = 20
 End With
 counter=0
 pagehead = Inputbox$("請輸入標(biāo)題")
 pagehead = Chr(10) & pagehead & Chr(10) & Chr(10) & Chr(10)
 ‘Call source.FieldSetText ( "Namelist_Group_Num", group_num )
 ‘groupstring = "Namelist" & " " & group_num & Chr(10)
 Set thisrange = thisdoc.range(1,1)
 thisrange.InsertBefore (pagehead)
 Set thisrange = thisdoc.range(2,Len(pagehead))
 With thisrange
 .bold = True ‘加粗
 .ParagraphFormat.Alignment = 1‘wdAlignParagraphCenter 行居中
 .font.size = 20 ‘字體大小為20
 End With
 Set doccustom = doccollection.GetFirstDocument
 ‘遍列文檔集的所有文檔,獲取所有滿足條件的紀(jì)錄數(shù)
 While Not(doccustom Is Nothing)
 counter=counter+1
 Set doccustom = doccollection.GetNextDocument(doccustom)
 Wend
 ‘動態(tài)分配紀(jì)錄數(shù)組
 ‘Redim record(counter,6) As String
 ‘插入一張表
 Set thisrange = thisdoc.range(Len(pagehead)+1,Len(pagehead)+1)
 Set thistable = thisdoc.tables.Add(thisrange, counter+1, 8)
 ‘thistable.autoformat(False)
 ‘寫表頭
 thistable.rows(1).cells(1).range.insertbefore("前往國家")
 thistable.rows(1).cells(2).range.insertbefore("國家數(shù)")
 thistable.rows(1).cells(3).range.insertbefore("天數(shù)")
 thistable.rows(1).cells(4).range.insertbefore("出境城市")
 thistable.rows(1).cells(5).range.insertbefore("入境城市")
 thistable.rows(1).cells(6).range.insertbefore("出發(fā)日期")
 thistable.rows(1).cells(7).range.insertbefore("同行價(jià)")
 thistable.rows(1).cells(8).range.insertbefore("市場指導(dǎo)價(jià)")
 ‘恢復(fù)計(jì)數(shù)器
 counter = 0
 ‘寫表內(nèi)容
 Set doccustom = doccollection.GetFirstDocument
 While Not(doccustom Is Nothing)
 counter = counter+1
 thistable.rows(counter+1).cells(1).range.insertbefore(doccustom.plan_country(0))
 thistable.rows(counter+1).cells(2).range.insertbefore(doccustom.plan_country_num(0))
 thistable.rows(counter+1).cells(3).range.insertbefore(doccustom.plan_day(0))
 thistable.rows(counter+1).cells(4).range.insertbefore(doccustom.plan_out_city(0))
 thistable.rows(counter+1).cells(5).range.insertbefore(doccustom.plan_in_city(0))
 thistable.rows(counter+1).cells(6).range.insertbefore(doccustom.plan_date(0))
 thistable.rows(counter+1).cells(7).range.insertbefore(doccustom.plan_whole_price(0))
 thistable.rows(counter+1).cells(8).range.insertbefore(doccustom.plan_mart_price(0))
 Set doccustom = doccollection.GetNextDocument(doccustom)
 Wend
 End If
 End Sub
 如何實(shí)現(xiàn)表單上的內(nèi)容根據(jù)用戶的輸入動態(tài)變化?
 答: 一般可以用notes的隱藏屬性功能來控制,使用當(dāng)公式為真是隱藏,然后靠公式來控制具體怎樣隱藏.比如可以在對話筐上放一個(gè)對話筐列表,里面放十個(gè)選項(xiàng),當(dāng)用戶選擇了其中的某幾個(gè)選項(xiàng)時(shí),響應(yīng)的在下面的表單部分顯示幾行.這可以畫一個(gè)表格,這個(gè)表格的屬性中設(shè)置邊框的線條粗細(xì)為零.然后對應(yīng)十個(gè)選項(xiàng)分為十行,每行填入和選項(xiàng)響應(yīng)的內(nèi)容,然后選定某一行的所有文本,編輯其隱藏屬性,選當(dāng)公式為真時(shí)隱藏,這個(gè)公式您就可以寫成當(dāng)選項(xiàng)的被選中條目中不包含本行文字時(shí)隱藏就可以了,這樣這一行就會在響應(yīng)的選項(xiàng)被選中時(shí)才會顯示.
 notes沒有應(yīng)用程序級的公共變量,那么我如果要彈出一個(gè)對話筐,并從這個(gè)對話筐中返回很多用戶輸入,我該怎么辦?
 答: 你首先要確定你要在哪個(gè)表單上彈出這個(gè)對話筐,一般的的做法是利用notes 的域值傳遞功能,即如果對話筐中的表單上的域和彈出這個(gè)對話筐的母表單的域相同,則對話筐中的值會被自動傳到母表單的相應(yīng)的域中的.你可以將放在對話筐中的表單作成子表單,同時(shí)把它放入對話筐中和母表單中,這樣你就可以接受到所有的用戶輸入了.
 在b/s下從通訊錄中選人一例在parentform母表單上建一個(gè)域reader(多值),另建一表單(childform),上建兩個(gè)對話框域rylb(通訊錄中人員的姓名),reader(用于添加或刪除人員),在母表單上建一按鈕,js代碼如下:window.open(‘/xxxy/xxx.nsf/childform?openform‘,null,‘width=450,height=200,status=no,resizable=no,top=200,left=200,scrollbars=no‘);在childform表單的js head 中寫入以下代碼,var fieldfunction AddClick(field){var fieldEntryList=document.all["rylb"]if(fieldEntryList.selectedIndex != -1){for (var i=0; i < fieldEntryList.options.length; ++i){if (fieldEntryList.options[i].selected)field.options[field.options.length] = new Option(fieldEntryList.options[i].text);}}}function RemoveClick(field){if (field.length != 0){if (field.selectedIndex != -1){for(var i=0;i<field.options.length ; ++i){if (field.options[i].selected){field.options[i] = null;--i;}}}}}在childform表單的onload中寫入以下代碼,(用于讀取原有的值)if(window.opener){readers=window.opener.document.forms[0].reader.value;var arr=readers.split(";");var field=document.all["reader"]for(i=0;i<arr.length;i++){field.options[field.options.length] = new Option(arr[i]);}}在childform表單中的rylb域中的“為選項(xiàng)使用公式”中寫入公式@Unique( @DbColumn("";"":"names.NSF";"people";1)),在HTML樣式中寫入“width=130;height=150”在childform表單中的reader域中HTML樣式中寫入“width=130;height=150”;在childform表單上建四個(gè)按鈕,“添加->”按鈕,代碼如下:AddClick(reader),“移除<-”按鈕,代碼如下:RemoveClick(reader),“確定”按鈕,代碼如下:var fieldEntryList=document.all["reader"]if (fieldEntryList.options.length=="0"){window.opener.document.forms[0].reader.value=""}else{window.opener.document.forms[0].reader.value="";for (var i=0; i < fieldEntryList.options.length; ++i){if(window.opener.document.forms[0].reader.value==""){window.opener.document.forms[0].reader.value=fieldEntryList.options[i].text}else{window.opener.document.forms[0].reader.value=window.opener.document.forms[0].reader.value+";"+fieldEntryList.options[i].text}}}alert("操作成功,請保存原文檔!")window.close()“取消”按鈕,代碼如下:window.close()這樣就可以對parentform母表單域中的值進(jìn)行添加、移除等自如地操作。
 
 
 
 Servlet在Cookie,Session和上傳文件上的應(yīng)用
 
 Servlet可以被認(rèn)為是服務(wù)端的applet,它被WEB服務(wù)器加載和執(zhí)行,前端可以顯示頁面和獲得頁面數(shù)據(jù),后臺可以操縱數(shù)據(jù)庫,能完成JavaBean的很多功能。在這里我較為詳細(xì)的說說Servlet在Cookie,Session和上傳文件上的應(yīng)用,在說明時(shí)我給出一些能編繹運(yùn)行的小例子,最后給出一個(gè)文件上傳例子以加深印象。
 我們先來看看SERVLET程序的基本構(gòu)架:
 式1:
 package test;
 import javax.servlet.*;
 import javax.servlet.http.*;
 import java.io.*;
 import java.util.*;
 public class test extends HttpServlet {
 public void init(ServletConfig config) throws ServletException {
 super.init(config);
 }
 public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 int f =1; switch(f){
 case 1:firstMothed(request,respponse);break;
 }
 }
 public void firstMothed(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 response.setContentType("text/html");
 OutputStreamWriter osw = new
 OutputStreamWriter(response.getOutputStream());
 PrintWriter out = new PrintWriter (response.getOutputStream());
 out.println("< html>");
 out.println("< head>< title>Servlet1< /title>< /head>");
 out.println("< body>你好!");
 out.println("< /body>< /html>");
 out.close();
 }
 }
 式2:
 package test;
 import javax.servlet.*;
 import javax.servlet.http.*;
 import java.io.*;
 import java.util.*;
 public class test extends HttpServlet {
 public void init(ServletConfig config) throws ServletException {
 super.init(config);
 }
 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 response.setContentType("text/html");
 OutputStreamWriter osw = new OutputStreamWriter(response.getOutputStream());
 PrintWriter out = new PrintWriter (response.getOutputStream());
 out.println("< html>");
 out.println("< head>< title>Servlet1< /title>< /head>");
 out.println("< body>你好!");
 out.println("< /body>< /html>");
 out.close();
 }
 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 response.setContentType("text/html");
 OutputStreamWriter osw = new OutputStreamWriter(response.getOutputStream());
 PrintWriter out = new PrintWriter (response.getOutputStream());
 out.println("< html>");
 out.println("< head>< title>Servlet1< /title>< /head>");
 out.println("< body>你好!");
 out.println("< /body>< /html>");
 out.close();
 }
 }
 式1適合于作總控模塊,此SERVLET作中間調(diào)度,根據(jù)不同的f值調(diào)用不同的SERVLET或方法。
 式2適合于對html的get和post有不同要求的情況。
 但這并不是絕對的,式2就完全可以代替式1,只要在doGet()方法中寫上doPost就與式1完全一樣。
 在init方法中執(zhí)行的語句,只要這個(gè)servlet被啟動了就一直有效,比如,我們在init()中new了一個(gè)對象,那么這個(gè)對象的內(nèi)存空間就永遠(yuǎn)存在,除非顯式地把這個(gè)對象賦為null,或重啟服務(wù)。
 HttpServletRequest和HttpServletResponse兩個(gè)對象實(shí)現(xiàn)http請求,它們有很多有用的方法,在下面的cookie和session管理中會細(xì)加描述。
 1, cookie管理 cookie用于在客戶端保存?zhèn)€人所特有的信息,它采取在客戶機(jī)寫臨時(shí)文件的機(jī)制。
 package test;
 import javax.servlet.*;
 import javax.servlet.http.*;
 import java.io.*;
 import java.util.*;
 public class test extends HttpServlet {
 public void init(ServletConfig config) throws ServletException {
 super.init(config);
 }
 public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 //寫cookie
 String CookieName ="js79"; //若是漢字則需編碼
 String CookieValue = "yesky";//若是漢字則需編碼
 Cookie cookie = new Cookie(CookieName,CookieValue);
 cookie.setMaxAge(age); // age = Integer.MAX_VALUE 永不過期
 cookie.setPath("/");
 //讀cookie
 String value = null;
 Cookie[] cookies = request.getCookies();
 if (cookies != null) {
 for (int i=0; i< cookies.length; i++) {
 if (cookies[i].getName().equals(CookieName))
 value = cookies[i].getValue();
 break;
 }
 }
 }
 response.setContentType("text/html");
 OutputStreamWriter osw = new OutputStreamWriter(response.getOutputStream());
 PrintWriter out = new PrintWriter (response.getOutputStream());
 out.println("< html>");
 out.println("< head>< title>test< /title>< /head>");
 out.println("cookie鍵:"+CookieName+"< br>");
 out.println("cookie值: "+value);
 out.println("< /body>< /html>");
 out.close();
 }
 }
 2,session管理
 Session在Servlet中是很有用的,它比cookie安全可靠靈活,但是管理起來有點(diǎn)麻煩,用得不好會造成服務(wù)器的開銷很大,浪費(fèi)資源。下面是一個(gè)基于Session管理一個(gè)對象的簡單例子。
 一個(gè)簡單的bean對象TestObject
 package test;
 public class TestObject extends Object {
 int id = 0; public String cur="";
 }
 package test;
 import javax.servlet.*;
 import javax.servlet.http.*;
 import java.io.*;
 import java.util.*;
 public class TestMan extends HttpServlet {
 public void init(ServletConfig config) throws ServletException {
 super.init(config);
 }
 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 int f = 1;
 if(request.getParameter("f")!=null)
 f =
 Integer.parseInt(request.getParameter("f"));
 switch(f){
 case 1: this.getResult(request,response);
 break;
 case 2:
 this.setSession(request,response);
 break;
 }
 }
 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 doGet(request,response);
 }
 public void getResult(HttpServletRequest request, HttpServletResponse response)   throws ServletException, IOException {
 TestObject testObject = null;
 testObject = getStatus(request,response);
 String html = testObject.id; doWrite( response,html);
 }
 public void setSession(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException {
 HttpSession session = request.getSession();
 TestObject testObject = null;
 testObject = getStatus(request,response);
 String tmp = null;
 tmp = request.getParameter("id");
 if(tmp != null) testObject.id = tmp;
 session.putValue("testObject ",article);
 getResult(request,response);
 }
 private TestObject getStatus(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 HttpSession session = request.getSession();
 TestObject testObject = null;
 if(session!=null){
 if(session.getValue("testObject ")!=null){
 testObject = (TestObject)session.getValue("testObject ");
 }
 else{
 testObject = new TestObject ();
 }
 }
 else{
 testObject = new TestObject ();
 }
 return testObject;
 }
 private void doWrite(HttpServletResponse response,String html) throws   ServletException, IOException {
 PrintWriter out = response.getWriter();
 out.println(html);
 out.close();
 }
 /////////////////////////////////////////////////////////
 }
 若能輕松搞定上面的例子,相信讀者對SERVLET已有了較為深刻的理解。
 下面再介紹一個(gè)上傳文件例子,其中汲及到了下載的免費(fèi)JavaBean (如有感興趣的朋友,可來函索要免費(fèi)JavaBean源代碼,Email:js79@yesky.com)
 上傳基本原理:由頁面發(fā)出一個(gè)http請求,服務(wù)端得到請求后,解析多媒體協(xié)議,讀出文件內(nèi)容,寫文件內(nèi)容到服務(wù)器,所有的這些功能都封裝到JavaBean中。
 上傳文件的必需條件:Browser端< form>表單的ENCTYPE屬性值必須為 multipart/form-data,它告訴我們傳輸?shù)臄?shù)據(jù)要用到多媒體傳輸協(xié)議,由于多媒體傳輸?shù)亩际谴罅康臄?shù)據(jù),所以規(guī)定上傳文件必須是post方法,< input>的type屬性必須是file。
 package upload;
 import javax.servlet.*;
 import javax.servlet.http.*;
 import java.io.*;
 import java.util.*;
 public class UpLoadServlet extends HttpServlet {
 public void init(ServletConfig config) throws ServletException{
 super.init(config);
 }
 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 PrintWriter out = response.getWriter();
 out.println("< HTML>< HEAD>< TITLE>UpLoad< /TITLE>"
 +"< meta http-equiv=‘Content-Type‘ content=‘text/html; charset=gb2312‘>"
 +"< /HEAD>"
 +"< body>");
 out.println("< div align=‘center‘ valign=‘top‘>"
 +"< span class=‘nava‘>請你選擇上傳的文件(請注意文件大小只能在20K之內(nèi))< /span>< BR>"
 +"< form ENCTYPE=‘multipart/form-data‘ method=post action=‘‘>"
 +"< input type=‘file‘ name=‘file‘>"
 +"< input type=‘submit‘ value=‘發(fā)送‘>"
 +"< /form>"
 +"< /div>");
 out.println("< /body>< /html>");
 out.close();
 }
 ////////
 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 PrintWriter out = response.getWriter();
 int tmpID = 1; try {
 MultipartRequest multi = new MultipartRequest(request,"/home/js79/html/", 5 * 1024 * 1024);
 }
 catch(Exception e){
 tmpID = -1; System.out.println(e);
 }
 if(tmpID == 1){
 out.println("< HTML>< HEAD>< TITLE>UpLoad< /TITLE>"
 +"< meta http-equiv=‘Content-Type‘ content=‘text/html; charset=gb2312‘>"
 +"< /HEAD>"
 +"< body>");
 out.println("上傳成功!< /body>< /html>");
 }
 else{
 out.println("< HTML>< HEAD>< TITLE>UpLoad< /TITLE>"
 +"< meta http-equiv=‘Content-Type‘ content=‘text/html; charset=gb2312‘>"
 +"< /HEAD>"
 +"< body>");
 out.println("上傳不成功!< /body>< /html>");
 }
 out.close();
 }
 }
 
 討論notes在b/s模式下如何才能達(dá)到最佳效果!
 
 
 1、要充分利用CSS樣式表,將你的域和文本盡可能放到表格單元格中,在樣式中可加入CSS,還有在HTML 首頁內(nèi)容中加入Css
 2、在B/S模式下,做到頁面的切換,要充分利用JavaScript;
 3、在B/S下,要在表單中加入相應(yīng)的html,也不是單純的加入,而且要結(jié)合notes的公式語言;
 4、需要注意的,所有的Domino設(shè)計(jì)元素以及文檔都有自己的特定的ID號,當(dāng)需要生成某些URL時(shí),Domino就使用這些特定的ID號來代表該元素;
 5、在B/S下,如果你的不同視圖具有一致的風(fēng)格,那就需要采用$$ViewTemplate for “視圖的名字”的方式;
 6、還有就是需要CGI變量。
 
 在notes里頭好多東西在http下實(shí)現(xiàn)不了,不知各位怎樣解決的?
 功程序員的七個(gè)秘密
 作者 Merrion
 
 7項(xiàng)使你成為開發(fā)者社區(qū)出色成員的技巧
 
 1.為人的需求編碼
 計(jì)算機(jī)界的一個(gè)最普遍的誤會是認(rèn)為原始碼是為計(jì)算機(jī)服務(wù)。計(jì)算機(jī)是工作在低級的二進(jìn)制代碼上,是在一系列的難以理解的1或0或者十六進(jìn)制數(shù)字之上,而不是我們敲入的結(jié)構(gòu)化高級計(jì)算機(jī)語言。
 這些語言被開發(fā)出來的目的是為了幫助我們程序員。
 在實(shí)踐中,為人的需求編碼通常意味著首先要有清楚透明的結(jié)構(gòu)和思路,其次才是效率和速度。
 2.經(jīng)常的好的注釋
 注釋是為人的需求編碼的一種極端的語言元素例子。大多數(shù)編譯器都會將注釋與可執(zhí)行程序分離開來。
 注釋的目的就是要告訴你(或者其他將來的開發(fā)著)程序的功能是什么。
 把這些寫進(jìn)注釋 - 并且避免只是簡單重新敘述代碼。
 好的注釋:
 Disable button to prevent its activation
 糟糕的注釋:
 Set cmd = False
 一個(gè)很好的檢驗(yàn)注釋的標(biāo)準(zhǔn)是:如果只有注解沒有去掉,有人能夠知道你的程序的作用嗎?
 3.良好代碼布局增加易讀性
 正如一位作家將一本書分成章和段落以幫助閱讀,因此開發(fā)者考慮代碼如何布局如何能能增強(qiáng)代碼的易讀性也是非常重要的。
 特別在任何語句結(jié)構(gòu)塊中 (如
 IF.
 .
 THEN.
 .
 .
 ELSE語句快) 和任何循環(huán)結(jié)構(gòu)(如
 WHILE.
 .
 .
 END WHILE)
 代碼應(yīng)該縮進(jìn)以便于很容易分清楚哪里是開始哪里是結(jié)束。
 4.預(yù)測并處理 那意想不到的事情
 你打開一個(gè)文件之前,確定文件為當(dāng)前文件。你將焦點(diǎn)設(shè)定為控件之前,確定控制是看得見的并且可用。設(shè)法找出在什么條件下使你的代碼失效,并在你的程序崩潰之前測試它。
 5.命名變量增強(qiáng)易讀性
 有許多策略進(jìn)行變量命名。首要原則是一致性和盡可能的能通過命名變量提供足夠的信息。如果你命名一個(gè)變量為nMonth,你提供給程序員的信息是這個(gè)變量將被設(shè)計(jì)用來存儲什么內(nèi)容。
 我自己傾向于使用匈牙利的命名風(fēng)格 - 但是無論你使用哪一種風(fēng)格,一致性是最主要的。
 6.使你的方法和過程保持簡潔
 一個(gè)方法或者過程理想狀況下應(yīng)該只做一件事情。在我的經(jīng)驗(yàn)方面,最大的誤區(qū)是,一個(gè)過程通常被設(shè)計(jì)來完成許多的不同操作。
 應(yīng)該將他們按不同的操作拆分成各個(gè)不同方法處理各自的事情,這樣各個(gè)功能可以很容易被重用,而且各個(gè)方法內(nèi)的代碼改變也很容易理解。
 7.適當(dāng)?shù)姆椒ê妥兞渴褂梅秶?br>功能和變量如果只在一個(gè)組件中使用,則在那一個(gè)組件之外不應(yīng)該是看得見的。如果變量只被設(shè)計(jì)用于一個(gè)方法或者過程,那么在那一個(gè)方法或過程之外不應(yīng)該是看得見的。
 這可以避免任何一個(gè)變量或者方法在它沒有意義的地方使用。
 
 有許多其他的提示和技巧能使你被成為比較好的程序員, 將會使你更有效率而你寫的程序也更可維護(hù), 但是這上面列出的七個(gè)秘密將會視為一個(gè)好的基礎(chǔ) - 然而使你高度地建構(gòu)在他們之上。
 
 公式秘籍
 
 訪問用戶環(huán)境
 
 用戶環(huán)境是包含數(shù)據(jù)庫的服務(wù)器或工作站,數(shù)據(jù)庫包括以下內(nèi)容: 復(fù)制公式、由新郵件到達(dá)時(shí)或定時(shí)觸發(fā)的代理、選擇公式或列公式。否則,用戶環(huán)境是用戶運(yùn)行公式的 Notes 工作站。
 用戶名可以是專有名稱也可以是非專有名稱,專有名稱可以是規(guī)范或縮寫的,使用 @Name 可更改用戶名的格式。
 以下函數(shù)返回或處理用戶環(huán)境的信息。
 函數(shù) 描述
 @UserName 返回用戶名或服務(wù)器名。
 @Name([key]; name) 更改用戶名的格式。關(guān)鍵字包含 [CN] 以從一個(gè)專有名字中解析出公共名,[Abbreviate] 縮寫規(guī)范格式的專有名字,[Canonicalize] 與上述作用相反,[ToKeyword] 將名字各部分按相反順序排序,用反斜杠分開(用于分類視圖)。
 @UserRoles 對于服務(wù)器上的數(shù)據(jù)庫,返回當(dāng)前用戶的角色列表。
 @MailDbName 返回用戶郵件數(shù)據(jù)庫的服務(wù)器名和路徑名。該 @function 計(jì)算出一個(gè)包含兩元素的列表。
 @OptimizeMailAddress(address) 從地址中刪除無用的網(wǎng)絡(luò)域。
 @Platform 返回用戶當(dāng)前運(yùn)行的平臺:Macintosh、 NetWare、 OS2V1、 OS2V2、 UNIX、 Windows/16 或 Windows/32。
 @Version 返回正在運(yùn)行的 Notes 版本(字符串)。
 @Password(string) 對字符串加密。加密后別人無法從中得到最初的字符串。
 
 
 訪問當(dāng)前數(shù)據(jù)庫和視圖
 
 可以直接訪問正在運(yùn)行公式的數(shù)據(jù)庫(便捷圖標(biāo)除外,因?yàn)樗鼪]有數(shù)據(jù)庫環(huán)境)。也可以在視圖環(huán)境中直接訪問正在運(yùn)行公式的視圖。同樣,在文檔環(huán)境中可直接訪問打開文檔的視圖。
 數(shù)據(jù)庫和視圖屬性
 下表列出返回?cái)?shù)據(jù)庫和視圖屬性的函數(shù)。
 函數(shù) 描述
 @DbManager 返回當(dāng)前對數(shù)據(jù)庫有“管理者”權(quán)限的用戶、群組和服務(wù)器。返回一個(gè)列表。
 @DbName 返回當(dāng)前 Notes 服務(wù)器和數(shù)據(jù)庫的名稱。返回二個(gè)元素的列表。
 @ViewTitle 返回當(dāng)前視圖的標(biāo)題。
 窗口標(biāo)題和列公式 @function
 許多 @function 提供了關(guān)于視圖的答復(fù)層次和其他方面的信息。在視圖中,主文檔以 1、2、3 等編號。每組答復(fù)文檔或答復(fù)的答復(fù)文檔則有第二個(gè)和第三個(gè)層次的從 1 開始的編號。缺省情況下,完整的答復(fù)文檔的編號以小數(shù)形式出現(xiàn)。例如:第三個(gè)主文檔的第二個(gè)答復(fù)文檔編號為 3.2,而它下面的第一個(gè)答復(fù)文檔編號為 3.2.1。
 這些函數(shù)僅工作于窗口標(biāo)題和列公式中,有一些會被限制。返回值都是一個(gè)字符串。
 函數(shù) 描述
 @Responses 返回當(dāng)前視圖中當(dāng)前文檔的答復(fù)文檔的編號(只限于窗口標(biāo)題公式)。
 @DocLevel 返回在當(dāng)前視圖中當(dāng)前文檔的級別。
 @DocSiblings 返回與當(dāng)前文檔同級的文檔編號(包含當(dāng)前文檔)。
 @DocNumber 返回當(dāng)前視圖中的當(dāng)前文檔或分類的編號。
 @DocNumber(sep) 同上,只是用 sep,而不是句點(diǎn)來分隔編號。
 @DocNumber("") 同上,只是僅返回編號的最右邊部分。
 @DocParentNumber 返回當(dāng)前視圖中當(dāng)前文檔或分類的父文檔或父分類的編號。
 @DocParentNumber(sep) 同上,只是用 sep,而不是句點(diǎn)分隔編號。
 @DocParentNumber("") 同上,只是僅返回編號的最右部分。
 @DocDescendants 返回后續(xù)文檔的編號。包含當(dāng)前文檔的子文檔,子文檔的子文檔。
 @DocDescendants(def) 同上,只是返回 def。在 def 中使用 % 以表示編號。
 @DocDescendants(zero; def) 同上,只是如果沒有后續(xù)文檔的話則返回 zero。
 @DocDescendants(one, zero; def) 同上,如果只有一個(gè)后續(xù)文檔的話,則返回 one。
 @DocChildren 返回當(dāng)前文檔的直接子文檔的編號。
 @DocChildren(def) 同上,僅返回 def。在 def 中使用 % 以表示編號。
 @DocChildren(zero; def) 同上,只是如果沒有后續(xù)文檔的話,則返回 zero。
 @DocChildren(one, zero; def) 同上,如果只有一個(gè)后續(xù)文檔的話,則返回 one。
 @IsCategory 如果當(dāng)前行的當(dāng)前域右邊任何域是一個(gè)分類,則返回一個(gè)星號。
 @IsCategory(True) 同上,只是返回 Frue 代替星號。
 @IsCategory(True; False) 同上,但是如果沒有分類域,則返回 False。
 @IsExpandable 如果當(dāng)前行是可展開的,則返回一個(gè)加號。
 @IsExpandable(True) 同上,只是返回 True 代替加號。
 @IsExpandable(True; False) 同上,但是如果當(dāng)前行是不可展開的,則返回 False。
 
 使用 @function 通過 LS:DO 訪問外部數(shù)據(jù)庫
 
 以下 @function 通過 ODBC 訪問外部數(shù)據(jù)庫并返回一個(gè)值或值的列表:
 @DbColumn 返回表的一列中的全部值,或者全部的不同的值。
 @DbLookup 返回表的一列中通過關(guān)鍵字匹配選定的值。
 @DbCommand 將一個(gè)命令傳遞給外部的數(shù)據(jù)庫管理系統(tǒng)(DBMS)并返回結(jié)果。
 @DbColumn 與 @DbLookup 都只能提取數(shù)據(jù)。它們不能增加、刪除、修改數(shù)據(jù)或執(zhí)行其他操作。@DbCommand 能提取數(shù)據(jù)或發(fā)送其他可以更改數(shù)據(jù)的 SQL 語句。LotusScript 提供了包括更新外部數(shù)據(jù)庫的更加強(qiáng)大的功能。
 前四個(gè)參數(shù)對于三個(gè)函數(shù)是同樣的,通過 ODBC 建立訪問數(shù)據(jù)庫。這些參數(shù)是:
 "ODBC" 是字符常量;或 "ODBC" : "NoCache"
 定義在數(shù)據(jù)源表格中的數(shù)據(jù)源名稱(在 Windows 中的 ODBC.INI)
 用戶標(biāo)識符,兩個(gè)用戶標(biāo)識符列表,或者一個(gè)空串,根據(jù)外部數(shù)據(jù)源而定
 口令,兩個(gè)口令列表,或者一個(gè)空串,根據(jù)外部數(shù)據(jù)源而定
 (@DbColumn 和 @DbLookup) 要訪問的表的名稱
 (@DbCommand) 要執(zhí)行的命令
 (@DbColumn 和 @DbLookup) 要訪問的列的名稱
 處理由數(shù)據(jù)源返回的空數(shù)據(jù)的選項(xiàng)
 (@DbLookup) 包含關(guān)鍵字的列名
 (@DbLookup) 適當(dāng)?shù)臄?shù)據(jù)類型的關(guān)鍵字值,或者是一個(gè)列表
 (@DbColumn 和 @DbLookup) 兩個(gè)元素的列表:“Distinct”作為關(guān)鍵字或空串;“Ascending”或“Descending”作為一個(gè)關(guān)鍵字
 在需要用 IDS 和口令的地方,您可以指定空串并讓用戶在執(zhí)行函數(shù)時(shí)提供它們。
 
 使用 @function 通過 LS:DO 訪問外部數(shù)據(jù)庫
 
 1. 該公式取得 MANUAL 表中的 PARTNO 列。
 @DbColumn("ODBC";"Oracle";"";"";"MANUALS";"PARTNO";"":"Ascending")
 2. 該公式從 MANUALS 表的行中取得 TITLE,在該行中 PARTNO 是 17-895A。
 @DbLookup("ODBC";"Oracle";"";"";"MANUALS";"TITLE";"PARTNO";"17-895A")
 3. 該公式從 MANUALS 表中的 ONHAND 列的數(shù)字值小于 100 的每行中取得 PARTNO 列值。
 @DbCommand("ODBC";"Oracle";"";"";"SELECT PARTNO FROM MANUALS WHERE ONHAND <100")
 
 轉(zhuǎn)換數(shù)據(jù)類型
 
 在對數(shù)據(jù)操作時(shí)類型必須是正確的。以下的函數(shù)用來轉(zhuǎn)換數(shù)據(jù)和測試數(shù)據(jù)類型。
 函數(shù) 描述
 @Text(value) 將一個(gè)值轉(zhuǎn)換為文本字符串。
 @Text(value; format) 根據(jù)指定的格式將一個(gè)數(shù)字或時(shí)間-日期值轉(zhuǎn)換成文本字符串。
 @TextToNumber(string) 將文本字符串轉(zhuǎn)換成一個(gè)數(shù)字。
 @TextToTime(string) 將文本字符串轉(zhuǎn)換成一個(gè)日期-時(shí)間值。
 @IsText(value) 如果值是文本字符串或文本字符串列表,則返回“真”值 (1)。
 @IsNumber(value) 如果值是數(shù)字或數(shù)字列表,則返回“真”值 (1)。
 @IsTime(value) 如果一個(gè)值是時(shí)間-日期或時(shí)間-日期列表,則返回“真”值 (1)。
 @Char(number) 將一個(gè) IBM 代碼頁 850 代碼轉(zhuǎn)換為對應(yīng)的字符。
 
 
 連接、比較和判定長度
 
 
 運(yùn)算符 + 用來連接字符串。運(yùn)算符 =、<>、!=、=!、><、<、>、<= 和 >= 用來比較字符串。以下的函數(shù)用來判定字符串的長度和比較字符串:
 函數(shù) 描述和用法
 @Length (string) 以字符為單位返回字符串的長度。
 @Length(stringlist) 以字符為單位,返回字符串列表中每個(gè)元素的長度。
 @Matches (string; pattern) 判定兩個(gè)字符串是否匹配。可以用通配符來擴(kuò)展比較的范圍。
 @Like (string; pattern) 判定兩個(gè)字符串是否匹配。遵循 ANSI SQL 標(biāo)準(zhǔn)。
 @Like(string; pattern; esc) 與上面的一樣只是多了一個(gè)轉(zhuǎn)義字符。
 @Matches @Matches 用“?”來匹配任意一個(gè)單獨(dú)的字符,用“*”來匹配任意的字符序列,@Matches 使用“\”作為轉(zhuǎn)義字符。
 @Like 按照 ANSI X3.135-1992 標(biāo)準(zhǔn),使用“_”(下劃線)來匹配任意一個(gè)單獨(dú)的字符,用“%”(百分號)來匹配任意的字符序列。
 
 查找并提取子串
 
 樣例
 以下函數(shù)查找并提取子串:
 函數(shù) 描述
 @Contains(string; sub) 判定一個(gè)字符串是否包含一個(gè)子串。
 @Contains(string; list) 判定一個(gè)字符串是否包含一個(gè)列表中的子串。
 @Begins(string; sub) 判定一個(gè)字符串是否以一個(gè)子串開始。
 @Ends(string; sub) 判定一個(gè)字符串是否以一個(gè)子串結(jié)束。
 @Left(string; n) 從一個(gè)字符串中提取最左邊的 n 個(gè)字符。
 @Left(string; sub) 從一個(gè)字符串中提取最左邊的字符,直到一個(gè)子串為止,從左到右搜索。
 @LeftBack (string; n) 從一個(gè)字符串中提取最左邊的字符,直到從右邊開始的第 n 個(gè)字符為止。
 @LeftBack(string; sub) 從一個(gè)字符串中提取最左邊的字符,直到一個(gè)子串為止,從右到左搜索。
 @Right(string; n) 從一個(gè)字符串中提取最右邊的 n 個(gè)字符。
 @Right(string; sub) 從一個(gè)字符串中提取最右邊的字符,直到一個(gè)子串為止,從左到右搜索。
 @RightBack (string; n) 從一個(gè)字符串中提取最右邊的字符,直到從左邊開始的第 n 個(gè)字符為止。
 @RightBack(string; sub) 從一個(gè)字符串中提取最右邊的字符,直到一個(gè)子串為止,從左到右搜索。
 @Middle(string; off; n) 從一個(gè)字符串中提取 n 個(gè)字符,從一個(gè)偏移量開始,從左到右搜索。
 @Middle(string; sub; n) 從一個(gè)字符串中提取 n 個(gè)字符,從一個(gè)子串開始,從左到右搜索。
 @Middle(string; off; sub) 從一個(gè)字符串中提取字符,從一個(gè)偏移量開始,到一個(gè)子串結(jié)束,從左到右搜索。
 @Middle(string; sub; sub) 從一個(gè)字符串中提取字符,從一個(gè)子串開始,到另一個(gè)子串結(jié)束,從左到右搜索。
 @MiddleBack(str; off; n) 從一個(gè)字符串中提取 n 個(gè)字符,從一個(gè)偏移量開始,從右到左搜索。
 @MiddleBack(str; sub; n) 從一個(gè)字符串中提取 n 個(gè)字符,從一個(gè)子串開始,從右到左搜索。
 @MiddleBack(str; off; sub) 從一個(gè)字符串中提取字符,從一個(gè)偏移量開始,到一個(gè)子串結(jié)束,從右到左搜索。
 @MiddleBack(str; sub; sub) 從一個(gè)字符串中提取字符,從一個(gè)子串開始,到另一個(gè)子串結(jié)束,從右到左搜索。
 @ReplaceSubstring(source; from; to) 在 source 中用 from 的內(nèi)容替換 to 的內(nèi)容。如果 from 和 to 都是列表,按次序替換對應(yīng)的項(xiàng)目。
 @Word(string; sep; n) 從 string 提取單詞 n,其中單詞是在指定的分隔符之間的文本。
 @Word(list; sep; n) 從列表中的每個(gè)字符串中提取單詞 n,其中單詞是在指定的分隔符之間的文本。
 
 
 修剪、重復(fù)、添加新行,并改變大小寫
 
 樣例
 
 以下函數(shù)修剪字符串、重復(fù)字符、添加新行(回車),并改變大小寫:
 函數(shù) 描述
 @Trim(string) 從字符串中刪除開頭、結(jié)尾和多余的空格。
 @Trim(list) 從字符串列表的每個(gè)元素中刪除開頭、結(jié)尾和多余的空格,并從列表中刪除空白元素。
 @Repeat(string , number) 將字符串重復(fù)若干次。
 @NewLine 在文本字符串中插入一個(gè)新行(回車)。
 @LowerCase(string) 將字符串中所有的大寫字符轉(zhuǎn)換成小寫。
 @UpperCase(string) 將字符串中所有的小寫字符轉(zhuǎn)換成大寫。
 @ProperCase 將字符串中每個(gè)單詞的第一個(gè)字符轉(zhuǎn)換成大寫,并將其余的字符轉(zhuǎn)換為小寫。
 
 
 執(zhí)行算術(shù)運(yùn)算
 
 乘、除、加、減運(yùn)算符(*/+-)。乘法和除法運(yùn)算符的優(yōu)先級高于加法和減法;運(yùn)算順序是從左到右。但可以使用括號更改運(yùn)算順序。以下列出的是算術(shù)運(yùn)算函數(shù)。
 函數(shù) 描述
 @Abs(number) 計(jì)算一個(gè)數(shù)的絕對(無符號)值。
 @Sign (number) 對于正數(shù)返回 1,對于負(fù)數(shù)返回 -1,對于零則返回 0。
 @Sum(num; num; ...) 計(jì)算數(shù)字和數(shù)字列表的和。
 @Integer(number) 去掉數(shù)字的小數(shù)部分,使它成為整數(shù)。
 @Integer(numlist) 去掉數(shù)字列表所有元素的小數(shù)部分,使它們成為整數(shù)。
 @Round(number) 對一個(gè)數(shù)字進(jìn)行四舍五入。
 @Round(number; factor) 以一個(gè)指定的因子規(guī)整數(shù)字。
 @Round(numlist) 對數(shù)字列表中的每個(gè)數(shù)字進(jìn)行四舍五入。
 @Round(numlist; factor) 以一個(gè)指定的因子規(guī)整數(shù)字列表中的每個(gè)元素。
 @Max(number; number) 取兩個(gè)數(shù)中較大的一個(gè)。
 @Max(numlist; numlist) 對兩個(gè)數(shù)字列表進(jìn)行矩陣式操作時(shí),取兩個(gè)數(shù)字中較大的一個(gè)
 @Min(number; number) 取兩個(gè)數(shù)中較小的一個(gè)。
 @Min(numlist; numlist) 對兩個(gè)數(shù)字列表進(jìn)行矩陣式操作時(shí),取兩個(gè)數(shù)字中較小的一個(gè)。
 @Modulo(number; number) 計(jì)算一個(gè)數(shù)字被第二個(gè)數(shù)字除后得出的余數(shù)。
 @Modulo(numlist; numlist) 對兩個(gè)數(shù)字列表進(jìn)行矩陣式操作時(shí),計(jì)算一個(gè)數(shù)字被第二個(gè)數(shù)字除后得出的余數(shù)。
 @Power(base; exp) 指數(shù)計(jì)算。
 @Sqrt (number) 計(jì)算平方根。
 @Pi 取得圓周率。
 @Log(number) 計(jì)算常用(以 10 為底)對數(shù)。
 @Ln(number) 計(jì)算自然(以 e 為底)對數(shù)。
 @Exp(number) 計(jì)算以 e 為底的指數(shù)。
 @Random 返回一個(gè) 0 到 1 之間的隨機(jī)數(shù)。
 @Sin(angle) 計(jì)算角度的正弦(弧度)。
 @Cos(angle) 計(jì)算角度的余弦(弧度)。
 @Tan(angle) 計(jì)算角度的正切(弧度)。
 @Asin(sine) 反正弦函數(shù)。
 @Acos(cosine) 反余弦函數(shù)。
 @Atan(tangent) 反正切函數(shù)。
 @Atan2(x; y) 計(jì)算以 y/x 作為正切值的反正切函數(shù)。
 
 答復(fù)列的公式
 
 僅用于答復(fù)的列需要公式來生成總結(jié)答復(fù)文檔的文本。
 包含作者的信息
 討論數(shù)據(jù)庫可以使用如下答復(fù)列的公式來顯示答復(fù)文檔的作者、日期和主題:
 From + " added this comment: " + Subject + " (" + @Text(@Created) + ")"
 按以下方式顯示答復(fù):
 Stephanie Mahar added this comment: Great job! (10/10/97 04:43:15 PM)
 跟蹤文檔狀態(tài)
 在雇員信息數(shù)據(jù)庫中,答復(fù)列可以顯示新雇員以及離職雇員的調(diào)查信息,作為“按雇員姓名”視圖中常規(guī)的“雇員記錄”的答復(fù)文檔。下面公式根據(jù)答復(fù)文檔使用的表單的不同,顯示不同的消息,并且顯示文檔的郵遞狀態(tài)。
 @If(Form = "Exit"; "Exit Form, "; "New Hire Information, ") + @If(Mailed = "Yes"; "mailed to employee " + @Text(@Date(PostedDate)); "not yet mailed")
 如果答復(fù)文檔使用 Exit 表單,那么答復(fù)行顯示也許如下:
 Exit Form, mailed to employee 08/26/97
 如果答復(fù)文檔使用 New Hire Information 表單,那么答復(fù)行顯示也許如下:
 New Hire Information, not yet mailed
 跟蹤答復(fù)的數(shù)目
 可以使用 @DocDescendants 跟蹤答復(fù)文檔的數(shù)目,以便作者迅速知道收到多少答復(fù)文檔。下面的主文檔列(不是答復(fù)列)公式對于答復(fù)樣式的視圖非常有用。
 Subject + " (" + @Name([CN]; From) + @DocDescendants(")"; ", % response)"; ", % responses)")
 如果是主文檔,那么列顯示 Subject 域的內(nèi)容、作者名稱、答復(fù)以及答復(fù)的答復(fù)文檔的數(shù)目。如果文檔有一個(gè)答復(fù),那么列顯示“response”;否則顯示“responses”。主文檔行可作如下顯示:
 Need Help with Trade Show (Indy Montoya, 1 response)
 Changing the Product Name (Sandy Braun, 2 responses)
 
 
 
 視圖小程序編程
 通過使用一些 @commands 命令可以對視圖小程序編程。有以下命令:
 @command 描述
 ViewCollapse 折疊所選文檔
 ViewExpand 展開所選文檔
 ViewCollapseAll 折疊所有文檔
 ViewExpandAll 展開所有文檔
 ViewRefreshFields 刷新視圖。
 刷新時(shí),視圖小程序不刪除標(biāo)記為已刪除的文檔
 MoveToTrash 使當(dāng)前所選文檔標(biāo)記為已刪除
 EmptyTrash 永久刪除標(biāo)記為已刪除的文檔
 Folder 將所選文檔移動或拷貝到文件夾
 RemoveFromFolder 從當(dāng)前文件夾刪除所選文檔。
 
 
 用新建表單增強(qiáng)Notes打印功能中央財(cái)經(jīng)大學(xué) 鄒龍泉
 02-1-31 下午 01:56:09
 
 Lotus公司推出的Lotus Domino/Notes作為辦公自動化系統(tǒng)的平臺近年來在國內(nèi)得到了廣泛的應(yīng)用,許多的政府主管部門、金融單位、企事業(yè)單位都使用了Notes以及在Notes上開發(fā)的各種辦公系統(tǒng),工作效率得到了極大的提高。
 在實(shí)際的應(yīng)用中,為了存檔以及供沒安裝Notes系統(tǒng)的部門傳閱,許多在Notes系統(tǒng)中流轉(zhuǎn)的電子文檔需要打印出來。不幸的是,Notes提供的打印功能很弱,一個(gè)文檔只能按照給定表單的版式進(jìn)行打印。但在實(shí)際的使用中,如政府部門,內(nèi)容相同的一個(gè)文檔,其上行公文和下行公文的版式是不一樣的,這就需要將同一文檔用多種樣式打印。最直接的想法當(dāng)然是在Designer中修改表單的版式,但由于應(yīng)用系統(tǒng)一般是隱藏設(shè)計(jì)的,表單無法修改。還有就是最終用戶的計(jì)算機(jī)水平有限,直接修改表單從技術(shù)上講也行不通。
 這時(shí)一個(gè)可行的做法就是:用VC++給用戶提供一個(gè)“所見即所得”的編輯界面,并列出Notes文檔中各部分的內(nèi)容,讓用戶以拖放的方式將相關(guān)內(nèi)容放到適當(dāng)?shù)奈恢蒙?,同時(shí)還可以加入文字、圖片等修飾內(nèi)容,然后按照最終的版式在Notes外部直接生成一個(gè)Notes表單,并用此表單進(jìn)行打印。這種方法既繞過了隱藏設(shè)計(jì)的障礙,又降低了對最終用戶的技術(shù)要求。當(dāng)然這一切都得益于Notes提供的API函數(shù)。
 由于只需一個(gè)NSFItemScan函數(shù)就能收集到Notes文檔中所有的域,而又有多種靈活的方式實(shí)現(xiàn)“所見即所得”的排版功能,因此在提出上述的思路后,本文將主要介紹如何構(gòu)造Notes表單。
 
 一、Notes表單結(jié)構(gòu)簡介
 一個(gè)表單中有三個(gè)必需的域:$TITLE、$INFO和$BODY,輔助性的還有$FIELDS域及屬性為placeholder的各域。
 1.$TITLE域
 $TITLE域的類型為TYPE_TEXT,其中保存表單的名稱,Notes客戶端窗口中“創(chuàng)建”菜單下列出的各表單名即為各表單note中$TITLE域的值。在Notes提供的C API頭文件“stdnames.h”中有預(yù)定義的常量ITEM_NAME_TEMPLATE_NAME代表表單note的名稱域,為保證程序的向后兼容,建議使用常量而避免直接使用$TITLE。
 2.$INFO域
 由于表單和文檔的創(chuàng)建有關(guān),$INFO域定義了通過此表單創(chuàng)建的文檔的一些屬性。實(shí)際上$INFO域中存儲的是一個(gè)名為CDDOCUMENT的結(jié)構(gòu)體,對生成文檔屬性的設(shè)定就是通過對該結(jié)構(gòu)體中各分量的不同賦值實(shí)現(xiàn)的。結(jié)構(gòu)體CDDOCUMENT 的定義及說明見Lotus C API 的參考文檔。
 $INFO域的類型為TYPE_COMPOSITE,對應(yīng)的預(yù)定義常量為ITEM_NAME_DOCUMENT。
 3. $BODY域
 $BODY域是表單note中的核心域,整個(gè)表單顯示和打印時(shí)的格式,還有通過此表單生成的文檔所包含的域及其類型,都是在本域中定義的。由于$BODY域的結(jié)構(gòu)非常復(fù)雜,本文將在第二部分專門介紹。$BODY域也是TYPE_COMPOSITE類型的,名稱預(yù)定義常量為ITEM_NAME_TEMPLATE。
 4. $FIELDS域
 $FIELDS域是一個(gè)TYPE_TEXT_LIST類型的域,其中包含了用此表單生成的文檔包含的所有域。但專為打印生成的表單中可以沒有此域。
 5. "placeholder"域
 對$BODY域中定義的將來文檔中要含有的每一個(gè)域,在表單中都對應(yīng)一個(gè)類型為TYPE_INVALID_OR_UNKNOWN而標(biāo)志為ITEM_PLACEHOLDER的域,域名和$BODY域中定義的一樣,而其值為NULL。
 標(biāo)志為ITEM_PLACEHOLDER的域?qū)⒈患尤氲健坝蛎怼敝?,這樣當(dāng)用戶選擇了客戶端中的“設(shè)計(jì)”菜單中的“視圖”子菜單后,在彈出的對話框中選擇“添加域”時(shí),該域名才會被顯示出來。
 同樣,這些域在打印的表單中不是必需的。
 
 二、$BODY域詳解
 $BODY域中可以包含各種Notes對象,如文本、域、圖像、熱點(diǎn)、鏈接等,還有一些輔助性對象,如段定義、段引用等。為方便管理,所有這些對象的定義都是通過不同的結(jié)構(gòu)體實(shí)現(xiàn)的。Notes中定義對象的結(jié)構(gòu)體都以“CD”開頭,如CDTEXT定義靜態(tài)文本、CDFIELD定義域等,其他對象的具體定義請查閱Lotus C API 的參考文檔。
 通常,一個(gè)$BODY域的整體結(jié)構(gòu)是這樣的:
 CDPABDEFINITION
 CDPABDEFINITION
 ...
 CDPARAGRAPH
 CDPABREFERENCE
 CDTEXT
 text
 ...
 CDPARAGRAPH
 CDPABREFERENCE
 CDBEGINRECORD
 CDFIELD
 CDBEGINRECORD
 ...
 下面對其中的各部分分別予以說明。
 1.段落預(yù)定義部分
 CDPABDEFINITION定義頁面上一個(gè)段落的屬性,在這個(gè)結(jié)構(gòu)體中我們可以定義段落的對齊方式、頁邊距、段間距、行間距等。在后面的某個(gè)具體段落中,如果定義了到此段定義的引用,則該段落就具有了此處定義的各屬性。
 段落的定義可以放在$BODY域的開頭,也可以放在中間,只要保證序號PABID不重復(fù)就可以了。
 2.靜態(tài)文本的定義
 上述總體結(jié)構(gòu)的中間部分定義了一段文本:CDPARAGRAPH定義一段的開始,類似文本串中的一個(gè)回車換行符;CDPABREFERENCE定義一個(gè)到段定義的引用,從而本段就具有了前面定義的各種屬性;CDTEXT是文本的頭部,包含有文本的長度、字體、顏色等信息;text是實(shí)際的文本。
 3.域的定義
 對域的定義也是以CDPARAGRAPH和CDPABREFERENCE開始,但與文本不同的是,像域、圖像等對象的定義,除了有作為頭部的結(jié)構(gòu)體外,還要有一對界定結(jié)構(gòu)體CDBEGINRECORD和CDENDRECORD放在對象定義的前后兩端。
 有時(shí)在域的前面還要有一些提示性文字,如一個(gè)用于接收姓名的域name,通常在其前面要有“姓名”兩個(gè)字,以便具體操作者知道此處要輸入姓名。具體創(chuàng)建域時(shí),這部分內(nèi)容以文本形式放在CDBEGINRECORD之前,格式如上一步中所述。
 在貨幣型或數(shù)值型的域中,為了對數(shù)據(jù)的格式進(jìn)行更進(jìn)一步的控制,在CDBEGINRECORD和CDFIELD中間還要插入一個(gè)CDEXT2FIELD結(jié)構(gòu),該結(jié)構(gòu)提供了附加的格式定義。
 域中的其他元素,如默認(rèn)值計(jì)算公式、輸入變換公式、域名、描述字串等放在CDFIELD后面,排列順序和其長度值在CDFIELD結(jié)構(gòu)體中的位置順序一致。當(dāng)然除域名外,其他元素如不是必要可以省略。
 在本部分中,以文本和域?yàn)槔?,介紹了$BODY域中各對象的具體定義方式,其他對象與此類似。
 
 三、創(chuàng)建Notes表單
 在了解了Notes表單結(jié)構(gòu)的基礎(chǔ)上,通過API函數(shù)建立表單就很容易了。
 首先打開一個(gè)數(shù)據(jù)庫,然后在其中新建一個(gè)空白note,接下來就可以向其中添加各域了。像$TITLE這樣的單一類型的域,可以直接調(diào)用NSFItemSetText函數(shù)創(chuàng)建。而像$INFO和$BODY這樣的復(fù)合類型的域,就比較麻煩一些。通常的做法是,先申請一塊足夠大的內(nèi)存,然后順序?qū)懭敫鞑糠謨?nèi)容,最后調(diào)用NSFItemAppend函數(shù)創(chuàng)建域。
 在向復(fù)合域中寫入數(shù)據(jù)時(shí),文本、域名等一般字符串可以直接寫入,而各種結(jié)構(gòu)體需調(diào)用ODSWriteMemory函數(shù)以Domino規(guī)范的形式寫入,另外就是域定義中用到的各種公式,在寫入前要經(jīng)過NSFFormulaCompile變換。
 
 四、例程
 下面的程序段定義了一個(gè)帶有默認(rèn)值公式的名為“TextField”的域:
 
 char TextFieldName[] = "TextField";
 char TextDescription[] = "This is a Simple Text Field";
 char TextDefValFormula[] = "\"Default\"";
 char far *pBufferStart, far *pBuffer;
 HANDLE hMem;
 CDPABREFERENCE CDPabRef;
 CDPARAGRAPH CDPara;
 CDBEGINRECORD CDBegin;
 CDENDRECORD CDEnd;
 CDEXT2FIELD CDExt2Field;
 CDFIELD CDField;
 FONTIDFIELDS *pFontFields;
 
 // 申請內(nèi)存并鎖定內(nèi)存,獲得指向該塊內(nèi)存的指針
 OSMemAlloc (0, wCDBufferLength, &hMem);
 pBufferStart = (char far *)OSLockObject(hMem);
 memset( pBufferStart, 0, (size_t) wCDBufferLength );
 pBuffer = pBufferStart;
 
 // 填寫 PARAGRAPH 結(jié)構(gòu)
 // 結(jié)構(gòu)體的長度
 CDPara.Header.Length = (BYTE) ODSLength(_CDPARAGRAPH);
 // 結(jié)構(gòu)體的類型
 CDPara.Header.Signature = (BYTE)SIG_CD_PARAGRAPH;
 // 轉(zhuǎn)換為Domino規(guī)范的形式寫入申請的內(nèi)存
 ODSWriteMemory( (void far * far *)&pBuffer, _CDPARAGRAPH, &CDPara, 1 );
 
 // 填寫 PABREF 結(jié)構(gòu)
 CDPabRef.Header.Signature = (BYTE)SIG_CD_PABREFERENCE;
 CDPabRef.Header.Length = (BYTE) ODSLength(_CDPABREFERENCE);
 // 要引用的段定義的序號
 CDPabRef.PABID = wPabDefNumber;
 ODSWriteMemory( (void far * far *)&pBuffer, _CDPABREFERENCE, &CDPabRef, 1 );
 
 // 填寫CDBEGINRECORD 結(jié)構(gòu)
 CDBegin.Header.Length = (BYTE)ODSLength(_CDBEGINRECORD);
 CDBegin.Header.Signature = SIG_CD_BEGIN;
 CDBegin.Version = 0;
 CDBegin.Signature = SIG_CD_FIELD;
 ODSWriteMemory( (void far * far *)&pBuffer, _CDBEGINRECORD,(void far *) &CDBegin, 1 );
 
 // 填寫CDEXT2FIELD 結(jié)構(gòu)
 memset(&CDExt2Field, 0, sizeof(CDEXT2FIELD));
 CDExt2Field.Header.Length = (WORD)ODSLength(_CDEXT2FIELD);
 CDExt2Field.Header.Signature = SIG_CD_EXT2_FIELD;
 ODSWriteMemory( (void far * far *)&pBuffer, _CDEXT2FIELD, (void far *) &CDExt2Field, 1 );
 
 // 填寫CDFIELD 結(jié)構(gòu),定義文本域
 CDField.Header.Signature = SIG_CD_FIELD;
 CDField.Flags = FEDITABLE;
 CDField.DataType = TYPE_TEXT;
 CDField.ListDelim = LDDELIM_SEMICOLON;
 
 // 本域中不用數(shù)值格式參數(shù),全部清零
 CDField.NumberFormat.Digits = 0;
 CDField.NumberFormat.Format = 0;
 CDField.NumberFormat.Attributes = 0;
 CDField.NumberFormat.Unused = 0;
 
 //本域中不用時(shí)間格式參數(shù),全部清零
 CDField.TimeFormat.Date = 0;
 CDField.TimeFormat.Time = 0;
 CDField.TimeFormat.Zone = 0;
 CDField.TimeFormat.Structure = 0;
 
 // 設(shè)定FontID
 pFontFields = (FONTIDFIELDS *)&CDField.FontID;
 pFontFields->Face = FONT_FACE_ROMAN;
 pFontFields->Attrib = 0;
 pFontFields->Color = NOTES_COLOR_BLACK;
 pFontFields->PointSize = 14;
 
 // 編譯默認(rèn)值公式
 NSFFormulaCompile(NULL, 0, TextDefValFormula, (WORD) strlen(TextDefValFormula), &hTextDefValFormula, &wTextDefValFormulaLen, &wdc, &wdc, &wdc, &wdc, &wdc))
 
 // 填寫CDFIELD 結(jié)構(gòu)的其余部分,因?yàn)镈VLength值只有公式編譯后才知道
 CDField.DVLength = wTextDefValFormulaLen;
 CDField.ITLength = 0;
 CDField.TabOrder = 0;
 CDField.IVLength = 0;
 CDField.NameLength = strlen(TextFieldName);
 CDField.DescLength = strlen(TextDescription);
 CDField.TextValueLength = 0;
 CDField.Header.Length = ODSLength(_CDFIELD) +CDField.DVLength +CDField.ITLength +CDField.IVLength +CDField.NameLength +CDField.DescLength +CDField.TextValueLength;
 
 // 保證CDFIELD域長度為偶數(shù)
 if (CDField.Header.Length % 2)
 CDField.Header.Length++;
 ODSWriteMemory( (void far * far *)&pBuffer, _CDFIELD, (void far *)&CDField, 1 );
 
 // 獲取指向編譯后公式的指針
 pTextDefValFormula = OSLock( char, hTextDefValFormula );
 // 寫入公式內(nèi)容到內(nèi)存
 memcpy( pBuffer, pTextDefValFormula, wTextDefValFormulaLen );
 pBuffer += CDField.DVLength;
 // 解鎖并釋放公式占用的空間
 OSUnlockObject(hTextDefValFormula);
 OSMemFree(hTextDefValFormula);
 
 // 域名部分,直接寫入
 memcpy( pBuffer, TextFieldName, CDField.NameLength );
 pBuffer += CDField.NameLength;
 
 // 域描述部分,直接寫入
 memcpy( pBuffer, TextDescription, CDField.DescLength );
 pBuffer += CDField.DescLength;
 
 // 保證整個(gè)域定義的長度為偶數(shù)
 if ((pBuffer-pBufferStart) %2)
 pBuffer++;
 
 // 填寫CDENDRECORD結(jié)構(gòu)
 CDEnd.Header.Length = (BYTE)ODSLength(_CDENDRECORD);
 CDEnd.Header.Signature = SIG_CD_END;
 CDEnd.Version = 0;
 CDEnd.Signature = SIG_CD_FIELD;
 ODSWriteMemory( (void far * far *)&pBuffer, _CDENDRECORD, (void far *) &CDEnd, 1 );
 
 
 
 在web上顯示視圖的時(shí)候,總是不喜歡notes的默認(rèn)界面,想換成表格的。用表格顯示很容易,別讓notes生成HTML,全部由你自己定制就成了。但如何交替用顏色顯示不同行呢?就是說當(dāng)view行數(shù)是寄數(shù)時(shí)顯示一種顏色,偶數(shù)時(shí)顯示另一種顏色。
 原先想用@docnumber去做,但@docnumber產(chǎn)生的值時(shí)一個(gè)特殊值,無法轉(zhuǎn)換成數(shù)字來判斷。在www.lotus.com的開發(fā)者原地有一篇類似介紹,用的方法是把docnumber直接打印到html里,然后再用javascript來判斷,這樣雖然可以,但非常的麻煩。
 下面有一種比較簡便的方法:還是用javascript:
 function transformView() {
 var tableElements = document.getElementsByTagName(‘table‘) ;
 var table = tableElements[tableElements.length - 1] ;
 //上面是你的表格再頁面中倒數(shù)第幾個(gè)表格,如果你是倒數(shù)第2個(gè),就-2
 table.width = ‘100%‘ ;
 table.cellSpacing = ‘0‘ ;
 headers = table.getElementsByTagName("th") ;
 for( i = 0; i < headers.length; i++) {
 headers[i].bgColor = ‘#cccccc‘ ;
 }
 rows = table.getElementsByTagName("tr") ;
 var counter = 0
 for( i = 0; i < rows.length; i++) {
 rows[i].bgColor = (i % 2 ? ‘#efefef‘ : ‘‘) ;
 }
 }
 怎么樣,是不是很cool?
 
 如何將Domino服務(wù)器配置為Internet郵件服務(wù)器?
 在學(xué)習(xí)配置之前,我們需要先簡單了解一下協(xié)議的概念。
 在進(jìn)行Internet郵件收發(fā)的時(shí)候,我們需要使用到下面兩個(gè)協(xié)議:
 SMTP(簡單消息傳輸協(xié)議)管理Internet郵件發(fā)送
 POP3(郵局協(xié)議)管理Internet郵件接收
 實(shí)際上兩者的功能劃分并不是如此清楚,也就是說兩者間關(guān)系是相輔相成的,獨(dú)立任何一方都不可能完成任務(wù)。
 好了,協(xié)議就了解到這里,我們來看看最具體的東西,配置步驟:
 1、配置——服務(wù)器配置文檔——基本中,打開SMTP郵件郵遞和SMTP偵聽任務(wù)選項(xiàng)
 2、在服務(wù)器配置文檔——基本中,定義全限定的Internet主機(jī)名,也就是說用戶的郵件地址會是:用戶名@全限定Internet主機(jī)域名,比如用戶admin,全限定的Internet主機(jī)名為www.flycat.net,那么該用戶的郵件地址就是admin@flycat.net。
 3、將POP3加入NOTES.INI的ServerTasks參數(shù)中
 4、配置——消息處理——網(wǎng)絡(luò)域——添加網(wǎng)絡(luò)域
 5、確定網(wǎng)絡(luò)域類型為全球網(wǎng)絡(luò)域
 6、確定網(wǎng)絡(luò)域名稱,任意都可以
 7、確定網(wǎng)絡(luò)域角色為R5 Internet網(wǎng)絡(luò)域
 8、確定為缺省全球網(wǎng)絡(luò)域
 9、在網(wǎng)絡(luò)域文檔中定義郵件地址轉(zhuǎn)換規(guī)則
 10、配置——消息處理——配置——添加配置
 11、啟動配置文檔中的“在本地INTERNET網(wǎng)絡(luò)域以外發(fā)送消息所用SMTP”
 12、作好域名解析工作
 13、重新啟動服務(wù)器
 14、用E-Mail客戶端試試好了
 |  |  
|  2003-9-30 14:12 |  |  
| 
| myfeeling 版主
 
        
 
 中文網(wǎng)金幣 13 個(gè)
 發(fā)帖 375 篇
 注冊 2003-9-10
 狀態(tài) Offline
 
 | 
| 綜合使用JavaScript、LotusScript Agent和Formula的技巧(2) 
 首頁-->LOTUS文章-->LotusDomino環(huán)境下編寫Web瀏覽器多數(shù)據(jù)庫檢索程序
 隨著計(jì)算機(jī)技術(shù)的日益普及,Internet/Intranet技術(shù)得到了更加廣泛的應(yīng)用,在世 界范圍的大量Web網(wǎng)點(diǎn)上以及公司內(nèi)部的Web服務(wù)器上,都存放著大量的信息。為使這些信 息得到的合理使用,Web服務(wù)器管理員應(yīng)該為用戶提供方便的信息檢索方法。作為群件代 表的Lotus Domino 4.5集成了郵件處理、群件應(yīng)用和Internet出版等功能,是Notes技術(shù)向Internet/ Intranet融合開放的里程碑式的產(chǎn)品。在繼承以往產(chǎn)品全部優(yōu)點(diǎn)與功能的基礎(chǔ)上,Domino 將原先的Notes服務(wù)器提升為用途更廣泛、使用更方便的Internet/Intranet服務(wù)器。在 Domino的幫助下用戶能夠快速 構(gòu)建安全可靠的Web網(wǎng)點(diǎn),開發(fā)出管理和控制Internet/Intranet的應(yīng)用程序,并通過Web 瀏覽器實(shí)現(xiàn)對各類數(shù)據(jù)和服務(wù)器的交互式訪問。Domino還為用戶提供了多種檢索信息的方 法,而且用戶甚至不必編程。本文所要討論的是通過簡單編程實(shí)現(xiàn)在Web瀏覽器上對任意 多個(gè)數(shù)據(jù)庫同時(shí)進(jìn)行檢 索的一種方法。   下面給出具體的實(shí)現(xiàn)方法:   1、創(chuàng)建數(shù)據(jù)庫SiteSearch.NSF。   2、在數(shù)據(jù)庫SiteSearch.NSF上創(chuàng)建Form名稱為 SearchForm。   3、在SearchForm上創(chuàng)建Field,內(nèi)容如下:   (1)DatabaseNames:類型為關(guān)鍵字,可編輯,允許多值,范圍為:每行輸入一個(gè)關(guān) 鍵字。關(guān)鍵字列表框內(nèi)輸入允許搜索的數(shù)據(jù)庫列表。   假設(shè)有五個(gè)數(shù)據(jù)庫允許用戶檢索,它們分別是:討論板(Discuss.NSF)、規(guī)章制度 (Institution.NSF)、技術(shù)論文(TechDocuments.NSF)、公司最新動態(tài)( CompanyNews.NSF)、簡報(bào)及公告(Bulletin.NSF),則在DatabaseNames關(guān)鍵字列表框內(nèi) 可輸入:   討論板 | Discuss.NSF   規(guī)章制度| Institution.NSF   技術(shù)論文| TechDocuments.NSF   公司最新動態(tài) | CompanyNews.NSF   簡報(bào)及公告 | Bulletin.NSF  ?。?)SearchString:類型為文本,可編輯。  ?。?)$$QuerySaveAgent :類型為文本,顯示時(shí)計(jì)算,數(shù)值為textSearchQuerySaveA gent,隱藏。  ?。?)SaveOptions:類型為文本,可編輯,默認(rèn)值為“0”,隱藏。   4、創(chuàng)建代理TextSearchQuerySaveAgent。運(yùn)行代理時(shí)間指定為:從“操作”菜單中 選擇執(zhí)行。指定代理操作的文檔為:運(yùn)行一次(可能使用@命令)。   代理程序的內(nèi)容如下:   Sub Initialize    Dim ArrNsf As Variant    Dim item As NotesItem    ‘獲得文檔 context,因?yàn)榇舜硎且粋€(gè)$$QuerySaveAgent,所以$$QuerySaveAgent 可以訪問 Context文檔上的項(xiàng)目。    Dim sess As New NotesSession    Dim doc As NotesDocument    Set doc = sess.DocumentContext    ‘輸出HTML頁面的頭部和標(biāo)題:    Print {<html>}    Print { <head>}    Print {<meta http-equiv="Content-Type" content="text/html; charset=gb2312">}    Print {<title>}    Print "多數(shù)據(jù)庫搜索"    Print {</title>}    Print {</head>}    ‘設(shè)置HTML頁面的背景顏色:    Print {<body text="000000" bgcolor="f7f7f7">}    ‘獲得欲檢索的數(shù)據(jù)庫,存放在數(shù)組ArrNsf內(nèi):    ArrNsf= doc.DatabaseName    ‘如果沒有輸入檢索條件,則輸出提示信息:    If Trim(Cstr(doc.Query(0)))="" Then    Goto EmptyQuery    End If    Dim MatchDoc As NotesDocument    Dim db As NotesDatabase,    Dim collection As NotesDocumentCollection    ‘下列循環(huán)從數(shù)組ArrNsf中取得欲檢索的數(shù)據(jù)庫進(jìn)行處理:    For nsfCount=0 To Ubound( ArrNsf )    SearchDB=ArrNsf(nsfCount)    Set db = sess.GetDatabase("",SearchDB)    ‘出現(xiàn)錯誤則轉(zhuǎn)向:    On Error Goto BadQuery    ‘獲得滿足查詢條件的記錄集:    Set collection = db.FTSearch(doc.Query(0),0)    On Error Goto 0    ‘輸出數(shù)據(jù)庫標(biāo)題:    Print "<Hr>"    Print db.title    Print "<Hr>"    ‘輸出該數(shù)據(jù)庫中滿足條件的記錄個(gè)數(shù):    Print "<font size=5><b>There are " & Str$(collection.Count) & " matching documents</b></font><br>"    ‘下列循環(huán)從滿足條件的記錄集中讀取記錄并輸出:    For i% = 1 To collection.Count    Set MatchDoc = collection.GetNthDocument(i%)    Print {<br><a href="/} &SearchDB &{/AllDocument/} & MatchDoc.UniversalID &{?OpenDocument">}    Print "<b>"    ‘如果文檔包含Subject或Title,則輸出Subject或Title:    Set item =MatchDoc.GetFirstItem( "Subject" )    If ( item Is Nothing ) Then    Set item = MatchDoc.GetFirstItem( "Title" )    End If    If Not (item Is Nothing) Then    Print " <b>" & item.Name & "</b>: " & item.Text    End If    ‘如果文檔包含Categories,則輸出Categories:    Set item = MatchDoc.GetFirstItem( "Categories" )    If Not (item Is Nothing) Then    Print item.Name & "</b>: " & item.Text    End If    ‘輸出文檔產(chǎn)生日期和作者:    createDate = MatchDoc.Created    Print "Document create date:" &createDate    Print " Authors: "    Forall aAuthor In MatchDoc.Authors    Print aAuthor    End Forall    Print "</a><br>"    Next    Next   Out:    Print {</body></html>}    Exit Sub   EmptyQuery:    Print {<b>Search query can not be empty </b>}    Resume Out   BadQuery:    Print {<b>Query is not understandable: </b>"} & doc.Query(0) & {"}    Resume Out   End Sub   在本例中使用的FTSearch搜索查詢內(nèi)容是一個(gè)符合 Notes 全文檢索規(guī)則的字符串, 搜索內(nèi)容可以是一個(gè)字詞或多個(gè)字詞。搜索內(nèi)容可以包括 ? 和 * 通配符,并且可以由 ! (not)、& (and)、|(or) 操作符混合。所檢索的數(shù)據(jù)庫可以有全文索引,也可以沒有全文索引。如果沒有全文索引 ,則搜索速度會慢一些。運(yùn)行本程序時(shí),應(yīng)先從瀏覽器中輸入U(xiǎn)RL:http://homeURL/Site Search.NSF/SearchForm?OpenForm,然后選擇欲檢索的數(shù)據(jù)庫并輸入檢索條件,單擊 Submit按鈕,則將列出所有 符合檢索條件的文檔。
 版權(quán)所有2001
 
 首頁-->LOTUS文章-->LOTUS Scrpit編碼指南
 編寫公式的方法一個(gè)公式中含有一條或多條按順序執(zhí)行的語句。根據(jù)與公式相關(guān)聯(lián)的對象和其他標(biāo)準(zhǔn)的不同,公式可以在所選的文檔上運(yùn)行一次或多次(每個(gè)文檔運(yùn)行一次)。除了從公式返回以外,公式中沒有循環(huán)和控制跳轉(zhuǎn)的語句。公式中對條件執(zhí)行路徑也有限制。代理公式將在選定的文檔上多次地、有條件地執(zhí)行。您可以:編寫可得出計(jì)算結(jié)果的公式以下公式都應(yīng)該有最后結(jié)果:復(fù)制公式 必須得出結(jié)果為真 (1) 或假 (0),并且可以應(yīng)用到數(shù)據(jù)庫的每個(gè)文檔上。表單公式 必須得出表單名稱。選擇公式 必須得出結(jié)果為真 (1) 或假 (0),并且可以應(yīng)用到視圖中的每個(gè)文檔上。列公式 必須得出一個(gè)可以轉(zhuǎn)換成文本字符串的值。顯示操作公式 必須得出真 (1) 或假 (0)。彈出式公式 必須得出一個(gè)文本串。窗口標(biāo)題公式 必須得出一個(gè)文本或數(shù)字值,除非公式由一個(gè)任意類型的單獨(dú)的域組成。區(qū)段存取公式 必須得出一個(gè)姓名或姓名列表。插入子表單公式 必須得出一個(gè)子表單的名稱的文本值。區(qū)段標(biāo)題公式 必須得出一個(gè)文本或數(shù)字值,除非公式由一個(gè)任意類型的單獨(dú)的域組成。段落隱藏公式 必須得出真 (1) 或者假 (0)。缺省值公式 必須得出一個(gè)可以存放在當(dāng)前域中的值。輸入轉(zhuǎn)換公式 必須得出一個(gè)可以存放在當(dāng)前域中的值。缺省校驗(yàn)公式 必須得出是成功 (1) 還是失敗 (0)。計(jì)算域公式 必須得出一個(gè)可以存放在當(dāng)前域中的值。關(guān)鍵字公式 必須得出一個(gè)可以存放在當(dāng)前域中的值或值的列表。這些公式可以簡單到只有一個(gè)域、常量或者函數(shù),也可以包含很多語句、使用臨時(shí)變量、更改域的內(nèi)容或者產(chǎn)生一些附加效果。但不論如何,其最后一個(gè)語句必須是一個(gè)合適的值。如果關(guān)鍵字 SELECT 沒有顯式指定的話,它會加在一個(gè)邏輯語句之前,這個(gè)邏輯語句用來終止復(fù)制或選擇公式。這些公式運(yùn)行于數(shù)據(jù)庫(復(fù)制公式)或視圖(選擇公式)的每一個(gè)文檔上,以確定復(fù)制和查看過程中包括或不包括哪些文檔。函數(shù) @All 返回一個(gè)真值因此公式“SELECT @All”將包括所有文檔。樣例:編寫得出結(jié)果的公式1. 此樣例是標(biāo)準(zhǔn)討論數(shù)據(jù)庫中“From”域的缺省值公式。它只包含一個(gè)返回用戶姓名的函數(shù)。@UserName2. 此樣例是一個(gè)標(biāo)準(zhǔn)討論數(shù)據(jù)庫中“Subject”域的輸入校驗(yàn)公式。它含有一個(gè) @If 函數(shù),如果“Subject”是空的(用戶未輸入任何值),它將返回一個(gè)失敗的值,反之則返回成功值。失敗時(shí)還將顯示一個(gè)消息。@If(Subject = ""; @Failure("You must enter a subject for your document."
  ; @Success)3. 該樣例是標(biāo)準(zhǔn)討論數(shù)據(jù)庫的“Memo”表單的窗口標(biāo)題公式。它只有一個(gè)語句,但包含有嵌套的 @If 命令。如果當(dāng)前文檔是新的,則窗口標(biāo)題是“New Memo”。如果當(dāng)前文檔已經(jīng)存在,并有一個(gè)“Subject”域,而且該域非空,則窗口標(biāo)題將取“Subject”域中的內(nèi)容(如果文檔帶有附件,則標(biāo)題前還會出現(xiàn)“>>”)。如果不存在“Subject”域或該域?yàn)榭眨瑒t窗口標(biāo)題為創(chuàng)建日期。@If(@IsNewDoc; "New Memo"; @If(@IsAvailable(Subject) & Subject != ""; @If(@Attachments; "* "; ""  + Subject; @Text(@Created)))編寫執(zhí)行操作的公式下列公式不產(chǎn)生一個(gè)最后的可用結(jié)果,但可以改變域值和產(chǎn)生附加動作:便捷圖標(biāo)公式 觸發(fā)時(shí)執(zhí)行一次。代理公式 觸發(fā)時(shí)在一個(gè)數(shù)據(jù)庫上執(zhí)行。一個(gè)代理公式運(yùn)行在數(shù)據(jù)庫中所選的每個(gè)文檔上,這些文檔由 UI 中指定的條件和公式中的 SELECT 關(guān)鍵字所決定。SELECT 關(guān)鍵字缺省是 SELECT @All。操作公式 觸發(fā)時(shí)在一個(gè)視圖或表單中執(zhí)行。按鈕公式 觸發(fā)時(shí)在一個(gè)表單、導(dǎo)航器或 RTF 域中執(zhí)行。操作熱點(diǎn) 觸發(fā)時(shí)在一個(gè)表單、導(dǎo)航器或 RTF 域中執(zhí)行。樣例:編寫執(zhí)行操作的公式該代理樣例將一個(gè)基于“Main”表單的文檔中的“Address”域的“Wayside Street”替換成“Wayside Drive”。有效的操作是 FIELD Address 賦值語句。如果 Address 中含有“Wayside Street”,則新的 Address 的內(nèi)容是將字符串“Wayside Street”左邊的字符,加上字符串“Wayside Drive”,然后再加上 Address 中“Wayside Street”右邊的字符。否則,Address 將被重置為它的當(dāng)前值。SELECT Form = "Main Form";ws := "Wayside Street";wd := "Wayside Drive";FIELD Address := @If(@Contains(Address; ws); @Left(Address; ws) + wd +@Right(Address; ws); Address)處理列表列表就是一個(gè)可以包含多個(gè)同類型值的命名實(shí)體。列表出現(xiàn)在以下幾種情況:允許多值的域可能包含一個(gè)列表而非一個(gè)單值。某些函數(shù)返回一個(gè)列表。常量可以被指定為一個(gè)列表或者是單值。語法是多個(gè)單值用冒號分開;例如,"London":"New York":"Tokyo" 就是一個(gè)由三個(gè)元素構(gòu)成的字符串列表常量。由于列表的連接運(yùn)算具有最高的優(yōu)先級,所以如果列表元素中的表達(dá)式是一個(gè)僅用于其自身的表達(dá)式的話,它就必須用括號括起來。例如,如果 3 為負(fù)數(shù)而 4 不是負(fù)數(shù)的話就應(yīng)該寫成 1:2  -3):4,而不是 1:2:-3:4 。并列運(yùn)算或交叉運(yùn)算時(shí)的列表組合。列表限制了操作的范圍,因?yàn)榱斜聿僮鲀H限于每一個(gè)列表元素。就象在一個(gè)循環(huán)中處理數(shù)組一樣。以下函數(shù)是列表所特有的。函數(shù) 描述@Elements(list) 確定列表元素的數(shù)量。@Explode(string) 將文本字符串轉(zhuǎn)換成一個(gè)文本列表??崭瘛⒍禾柡头痔栍糜诜指糇址脑?。@Explode(string; separator) 與上面的函數(shù)一樣,但第二個(gè)參數(shù)指定了字符串中的元素的分隔符。@Explode(string; separator; empties) 與上面的函數(shù)一樣,但是返回值為 @True ,因?yàn)榈谌齻€(gè)參數(shù)包含空的列表元素,其中出現(xiàn)了連續(xù)的分隔符。@Explode(date-range) 將一個(gè)日期范圍轉(zhuǎn)換成一個(gè)日期列表。參數(shù)必須是一個(gè)時(shí)間-日期值;返回值是文本列表。@Implode(list) 將文本列表轉(zhuǎn)換成文本字符串,用空格分隔各個(gè)元素。@Implode(list; separator) 與上面的函數(shù)一樣,但是第二個(gè)參數(shù)指定了字符串中每個(gè)元素之間的分隔符。@IsMember(string; list) 確定一個(gè)字符串是否為一個(gè)列表的成員。返回真 (1) 或假 (0)。@IsMember(list1; list2) 確定一個(gè)列表是否被包含在另一個(gè)列表中。返回真 (1) 或假 (0)。@IsNotMember(string; list) 確定一個(gè)字符串是否不是一個(gè)列表的成員。返回真 (1) 或假 (0)。@IsNotMember(list1; list2) 確定一個(gè)列表是否不被包含在另一個(gè)列表中。返回真 (1) 或假 (0)。@Keywords(list1; list2) 在 list1 中找到與 list2 中的單詞相匹配的單詞。單詞分隔符有 " , ? ! ; : [ ] { } < >。@Keywords(list1; list2; separator) 與上面的函數(shù)一樣,但第二個(gè)參數(shù)指定了單詞的分隔符。@Member(value; list) 確定一個(gè)值在字符串列表中的位置。@Replace(list1; list2; list3) 將 list1 中與 list2 相匹配的值用 list3 中對應(yīng)的值替換。@Subset(list; n) 從列表中提取出 n 個(gè)值。用 -n 表示從右到左提取。@Unique(list) 從字符串列表中刪除重復(fù)的值。@Unique 返回一個(gè)隨機(jī)的,唯一的文本值。樣例:使用列表1 (并列運(yùn)算)該樣例用并列算法把兩個(gè)數(shù)字列表相加。結(jié)果列表中有四個(gè)值 11、22、27 和 44。list1 := 10 : 20 : 30 : 40;list2 := 1 : 2 : (-3) : 4;list3 := list1 + list2;result := @Text(list1) + " + " + @Text(list2) + " = " + @Text(list3);@Prompt([OKCANCELLIST]; "Result"; ""; ""; result)2 (交叉運(yùn)算)該樣例用交叉算法將兩個(gè)列表連接起來。結(jié)果列表中有 12 個(gè)值:Blue Sedan、Blue Coupe、Blue Van、Blue Truck、Red Sedan 等等最后是 Yellow Truck。cars := "Sedan" : "Coupe" : "Van" : "Truck";colors := "Blue" : "Red" : "Yellow";result := colors + " " *+ cars;@Prompt([OKCANCELLIST]; "Result"; ""; ""; result)3 (@Elements) 如果“Categories”域中沒有元素,此例將顯示一條消息,如果有的話則顯示列表。@If(@Elements(Categories) = 0; @Prompt([OK]; "Categories"; "No categories"  ;@Prompt([OKCANCELLIST]; "Categories"; ""; ""; Categories))4 (@Explode) 該樣例使用缺省的分隔符空格、逗號和分號,把一個(gè)字符串分離成一個(gè)列表。結(jié)果列表中的值是:Paris、London、Chicago 和 Seoul。cityList := @Explode("Paris London,Chicago;Seoul"  ;@Prompt([OKCANCELLIST]; "List of cities"; ""; ""; cityList)5 (@Explode) 該樣例使用分隔符逗號和分號將一個(gè)字符串常量分離成一個(gè)列表。結(jié)果列表中的值為:Paris、London、New York 和 Hong Kong。New York 和 Hong Kong 沒有分離成 New、York、Hong 和 Kong,這是因?yàn)闆]有將空格作為分隔符。cityList := @Explode("Paris,London,New York;Hong Kong"; ",;"  ;@Prompt([OKCANCELLIST]; "List of cities"; ""; ""; cityList)6 (@Explode) 該樣例在 London 和 New York 之間有一個(gè)空條目。如果第三個(gè)參數(shù)是 @False 或者被忽略,那么多個(gè)連續(xù)的分隔符將被看作一個(gè)。請確信逗號是連續(xù)的,沒有被空格分隔。cityList := @Explode("Paris,London,,New York;Hong Kong"; ",;"; @True);@Prompt([OKCANCELLIST]; "List of cities"; ""; ""; cityList)7 (@Implode) 該樣例將一個(gè)列表常量組合到一個(gè)字符串變量中,用空格(缺省)作為分隔符。結(jié)果字符串中的值為:Minneapolis Detroit Chicago。city := "Minneapolis" : "Detroit" : "Chicago";cityString := @Implode(city);@Prompt([OK]; "Imploded string"; cityString)8 (@Implode) 該樣例將一個(gè)列表常量組合到一個(gè)字符串列表中,用逗號和空格作為分隔符。結(jié)果字符串中的值為:Minneapolis, Detroit, Chicago。city := "Minneapolis" : "Detroit" : "Chicago";cityString := @Implode(city; ", "  ;@Prompt([OK]; "Imploded string"; cityString)9 (@Implode) 該樣例使用冒號作為分隔符將一個(gè)列表域分離成一個(gè)字符串。如果 Categories 域中的輸入是 Minneapolis, Detroit, Chicago 則結(jié)果為:Minneapolis  etroit:Chicago 。@Prompt([OK]; "Categories"; @Implode(Categories; ":"  )10 (IsMember) 該代理樣例檢查所選的文檔,看 Categories 列表中是否有 Adjusted,如果有,Categories 將不變化。如果沒有,Adjusted 將被添加到 Categories 列表中。FIELD Categories := @If(@IsMember("Adjusted"; Categories); Categories; @Explode(@Implode(Categories; ";"  + ";Adjusted"; ";"  );SELECT @All11 (@IsNotMember) 該樣例檢查所選文檔,看 Categories 列表中是否有 Adjusted 和 Signed off。如果沒有,則兩者都被加入到 Categories 列表中。如果兩者都已存在,則 Categories 維持原狀。FIELD Categories := @If(@IsNotMember("Adjusted" : "Signed off"; Categories); @Explode(@Implode(Categories; ";"  + ";Adjusted;Signed off"; ";"  ; Categories);SELECT @All12 (@Keywords) 該樣例查找在 Cities 域中用到了哪個(gè)關(guān)鍵字。keywords := @Keywords(Cities ; "Paris" : "Moscow" : "Tokyo" : "Boston"  ;@Prompt([OK]; "Keywords"; keywords)13 (@Member) 該樣例讓用戶從一個(gè)列表中選擇一個(gè)值,并顯示該值在列表中的編號。cars := "Sedan" : "Coupe" : "Van" : "Truck";car := @Prompt([OKCANCELLIST] : [NOSORT]; "Cars"; "Pick one"; "Sedan"; cars);n := @Member(car; cars);@Prompt([OK]; "Your selection is ..."; "Number " + @Text(n))14 (@Replace) 該樣例將 colors 列表中的“red”替換成“scarlet”并將“blue”替換成“turquoise”。colors := "red" : "blue" : "yellow" : "blue" : "black" : "red";from := "red" : "blue";to := "scarlet" : "turquoise";result := @Replace(colors; from; to);@Prompt([OKCANCELLIST] : [NoSort]; "Replacement list"; ""; ""; result)15 (@Subset) 該樣例將 New Orleans, London 和 Frankfurt 放到 first3 中,并將 Singapore 和 Sydney 放到 last2 中。cities := "New Orleans" : "London" : "Frankfurt" : "Singapore" :"Sydney";first3 := @Subset(cities; 3);last2 := @Subset(cities; -2);@Prompt([OKCANCELLIST] : [NoSort]; "First three"; ""; ""; first3);@Prompt([OKCANCELLIST] : [NoSort]; "Last two"; ""; ""; last2)16 (@Unique) 該樣例返回一個(gè)有四個(gè)元素的列表:red, blue, yellow 和 black。colors := "red" : "blue" : "yellow" : "blue" : "black" : "red";result := @Unique(colors);@Prompt([OKCANCELLIST] : [NoSort]; "Unique list"; ""; ""; result)使用條件語句@If 可以使您根據(jù)條件的真假執(zhí)行不同的語句。這個(gè)條件通常是值和值的比較,但也可以是一個(gè)常量、一個(gè)變量或者一個(gè)函數(shù)的結(jié)果。例如:如果當(dāng)前視圖是“By Author”,則 @ViewTitle = "By Author" 為真。如果 Categories 至少有一個(gè)元素,@Elements(Categories) > 0 為真。1 用在條件中時(shí)表示真。@True 和 @Yes 都返回 1。如果條件為真,則比較運(yùn)算和判斷條件的函數(shù)返回 1 。0 用在條件中時(shí)表示假。@False 和 @No 都返回 0。如果條件為假,則比較運(yùn)算和判斷條件的函數(shù)返回 0 。@If 語句有奇數(shù)個(gè)參數(shù),必須至少有三個(gè),例如:條件為第一個(gè)參數(shù),如果 @If 有多個(gè)條件的話,此后每隔一個(gè)參數(shù)就是一個(gè)條件。條件為真時(shí),執(zhí)行的是第二個(gè)參數(shù)中的語句,如果 @If 有多個(gè)條件,則第二個(gè)參數(shù)以后的每隔一個(gè)參數(shù)都是一個(gè)可執(zhí)行的語句。條件為假時(shí)執(zhí)行最后一個(gè)參數(shù)中的語句。最簡單的 @If 語句有如下的形式:@If(condition; true statement; false statement)三個(gè)條件的 @If 語句有如下形式:@If(condition1; true1; condition2; true2; condition3; true3; false)@If 函數(shù)從左到右依次計(jì)算,遇到第一個(gè)為真的條件就執(zhí)行對應(yīng)的語句(也就是接下來的那個(gè)參數(shù)中的語句)。此后就不再執(zhí)行任何 @If 中的語句了。如果沒有一個(gè)條件為真,則執(zhí)行最后一個(gè)參數(shù)中的語句。真值語句和假值語句的形式根據(jù)其前后關(guān)系的不同而有些變化:如果 @If 語句是公式中最后一條需要得出結(jié)果的語句,則真值和假值語句必須得出一個(gè)計(jì)算結(jié)果。如果 @If 語句是賦值語句右邊的部分,則真值和假值語句必須能得出一個(gè)可以存放在左邊的域或臨時(shí)變量中的值。否則,真值和假值語句必須產(chǎn)生一個(gè)操作。@If 中的真值和假值語句不能包含一個(gè)賦值語句。賦值語句左邊的部分只能出現(xiàn)在一個(gè)公式的最外層。以下語法形式是錯誤的:@If(condition; variable := value1; variable := value2)必須寫成:variable := @If(condition; value1; value2)@If 語句是可以嵌套的。嵌套的 @If 語句對于解決公式語言有限的邏輯結(jié)構(gòu)問題是很有幫助的,但它會導(dǎo)致復(fù)雜的語法表達(dá)。@Do 函數(shù)可以使您在一個(gè)條件下執(zhí)行多條語句。樣例:使用條件語句1. 該代理的例子將 Categories 中元素的數(shù)量與 0 比較。如果域中有元素,則不作任何改變(設(shè)置成自己的值)。如果域中沒有元素,則設(shè)置成一個(gè)常量字符串。FIELD Categories := @If(@Elements(Categories) > 0; Categories; "To be supplied ..."  ;SELECT @All2. 此窗口標(biāo)題的樣例首先檢查 @IsNewDoc 的返回值。如果文檔是新的,則窗口標(biāo)題設(shè)置成文本常量“New Topic”。如果文檔已經(jīng)存在,并且當(dāng)前視圖是“AuthorView”的話,窗口標(biāo)題設(shè)置為“Subject”域中的內(nèi)容。否則,窗口標(biāo)題就是“Subject”域的內(nèi)容加上一個(gè)表示答復(fù)文檔數(shù)目的字符串。StandardTitle := Subject + @DocDescendants(" (No Responses)"; " (1 Response)"; " (% Responses)"  ;@If(@IsNewDoc; "New Topic"; @ViewTitle = "AuthorView"; Subject; StandardTitle) 編寫消息和取得用戶輸入的方法您可以通過以下技術(shù)與用戶進(jìn)行交互:使用 @Prompt 編寫消息用以下形式的 @Prompt 編寫消息,與用戶交流。@Prompt([OK]; title; prompt) 顯示一個(gè)信息對話框,標(biāo)題文本在對話框的頂部,提示文本在對話框的主體部分。@Prompt([OKCANCELLIST] : [NOSORT]; title; prompt; default; choices) 將顯示一個(gè)對話框,標(biāo)題文本在對話框的頂部,提示文本在對話框的主體部分,選擇文本列表在提示文本的下面。這種形式的 @Prompt 主要用于取得輸入信息,但也可以用于顯示。最后一個(gè)參數(shù)必須是一個(gè)文本列表。prompt 和 default 可以為空。然而,如果該語句不是公式的最后一條語句,而且用戶單擊了“Cancel”的話,則接下來的公式便不再執(zhí)行了。如果您想將列表排序的話就不要指定 [NOSORT] 。非文本值必須用 @Text 轉(zhuǎn)換成文本才能用作 @Prompt 的參數(shù)。文本值可以是常量、臨時(shí)變量、域或者表達(dá)式。樣例:使用 @Prompt 編寫消息1. 該樣例在對話框中編寫一個(gè)作為標(biāo)題的文本常量和一個(gè)文本表達(dá)式。表達(dá)式是文本常量和已轉(zhuǎn)換成文本的日期-時(shí)間值的組合。@Prompt([OK]; "Current time and date"; "The date is " + @Text(@Now; "D0S0"  + ". " + "The time is " + @Text(@Now; "T0S1"  + "."  2. 該樣例編寫一個(gè)文本常量作為標(biāo)題。而對話框的內(nèi)容是一個(gè)文本常量,后面跟一個(gè)多值域中的值。@Prompt([OKCANCELLIST] : [NoSort]; "Field offices"; "Current field offices are located in the following cities:"; ""; Field_offices)使用 @Prompt 和 @PickList 取得用戶的輸入用以下形式的 @Prompt 和 @PickList 交互的取得用戶輸入:@Prompt([YesNo]; title; prompt) 顯示一個(gè)對話框,其中有標(biāo)題文字、提示文本以及“是”和“否”按鈕。如果用戶單擊“是”,則 @Prompt 返回真 (1),如果用戶單擊“否”,則返回假 (0)。@Prompt([YesNoCancel]; title; prompt) 顯示一個(gè)對話框,其中有標(biāo)題文字、提示文本以及“是”、“否”和“取消”按鈕。如果用戶單擊“是”,則 @Prompt 返回真 (1),如果用戶單擊“否”,則返回假 (0),如果用戶單擊“取消”,則返回 -1 。@Prompt([OkCancelEdit]; title; prompt, default) 顯示一個(gè)對話框,其中有標(biāo)題文字、提示文本和一個(gè)用戶可以鍵入信息的方框。@Prompt 將以文本值的形式返回用戶的鍵入信息。如果用戶單擊“取消”,公式將立即終止。@Prompt([Password]; title; prompt) 與上面的公式作用一樣,只是在用戶鍵入時(shí)方框中顯示 X ,而不是用戶所輸入的內(nèi)容,這是出于保密的考慮。@Prompt([OkCancelList] : [NoSort]; title; prompt; default; choices) 將顯示一個(gè)方框,標(biāo)題文字在框的頂部,提示文本在框的主體部分,文字列表選項(xiàng)在提示文本的下面,并且突出顯示缺省選項(xiàng)。最后一個(gè)參數(shù)必須是文本列表。@Prompt 將返回用戶選擇的列表元素。如果用戶單擊了“取消”,該公式將立即終止。如果您想讓列表排序的話,請不要指定 [NoSort] 。@DbColumn 可以根據(jù)指定數(shù)據(jù)庫中的當(dāng)前視圖的內(nèi)容來生成一個(gè)列表。@Prompt([OkCancelCombo]; title; prompt; default; choices) 與上面的公式作用一樣,但使用的是一個(gè)下拉式列表,框中缺省項(xiàng)目位于列表最頂部。@Prompt([OkCancelEditCombo]; title; prompt; default; choices) 與上面的公式作用一樣,但是允許用戶在列表上的方框中輸入值或者從列表中選取一個(gè)值。@Prompt([OkCancelListMult]; title; prompt; default; choices) 與 OkCancelList 一樣,但是允許用戶選擇多個(gè)列表元素并返回一個(gè)列表。@Prompt[(LocalBrowse]; title; filetype) 顯示一個(gè)對話框,允許用戶從本地文件系統(tǒng)中選擇名稱。標(biāo)題文本位于對話框的頂部,在對話框主體部分的左邊顯示一個(gè)選擇文件的列表框,在它下面是一個(gè)文件類型的列表框,在右邊是一個(gè)選擇目錄的列表框。對話框中包含“選擇”、“取消”和“網(wǎng)絡(luò)”或“幫助”按鈕。filetype 參數(shù)是一個(gè)文本值,從數(shù)字 1 到 3,指定初始化顯示的文件類型:"1" 表示 .nsf 文件,"2" 表示 .ntf 文件;"3" 表示全部文件。@PickList([Custom]:[Single]; server : file; view; title; prompt; column) 顯示一個(gè)對話框,其中包含標(biāo)題文本、提示文本以及選項(xiàng)列表。列表中是指定數(shù)據(jù)庫的視圖。用戶可以選擇一個(gè)(如果指定了 [Single])或任意數(shù)量的元素(如果未指定 [Single])。@PickList 返回所選列表元素的指定列中的值。這有點(diǎn)象用 @DbColumn 來生成一個(gè)列表給 @Prompt 的過程。@PickList([Name]:[Single]) 與上面公式的作用類似,只是數(shù)據(jù)庫是一個(gè)通訊錄,而視圖是“個(gè)人”視圖。用戶可以在 @PickList 對話框中選擇通訊錄。當(dāng)把非文本值用作 @Prompt 和 @PickList 的參數(shù)時(shí),必須先通過 @Text 轉(zhuǎn)換成文本。文本值可以是常量、臨時(shí)變量、域或者表達(dá)式。如果返回值要用作非文本值的話,它還必須再加以轉(zhuǎn)換。樣例:使用 @Prompt 和 @PickList 取得用戶的輸入1 (YesNo) 這個(gè)輸入校驗(yàn)公式向用戶查詢的 TotalAmount 域。如果用戶單擊“否”,則出現(xiàn)一個(gè)錯誤消息。@If(@Prompt([YesNo]; "Is this total within budget?"; @Text(TotalAmount; "C"  ); @Success; @Failure("Total not within budget"  )2 (OkCancelEdit) 此按鈕公式要求用戶指定一個(gè)服務(wù)器和數(shù)據(jù)庫,并打開此數(shù)據(jù)庫。如果用戶沒有向編輯框中輸入信息而直接單擊“是”,則返回值是一個(gè)空字符串。server := @Prompt([OkCancelEdit]; "Server"; "Enter the name of a server"; ""  ;database0 := @Prompt([OkCancelEdit]; "Database"; "Enter the name of a database on " + @If(server = ""; "your workstation"; server); ""  ;database := @If(@Contains(database0; "."  ; database0; database0 + ".nsf"  ;@Command([FileOpenDatabase]; server : database)3 (Password) 這個(gè)域輸入校驗(yàn)公式從用戶那里取得一個(gè)口令。并將此口令與文檔中“Password”域的內(nèi)容相比較。pass := @Prompt([Password]; "Password"; "What is the password?"  ;@If(pass = Password; @Success; @Failure("Password incorrect"  )4 (OkCancelList) 此便捷圖標(biāo)公式向用戶展示數(shù)據(jù)庫目錄中的數(shù)據(jù)庫列表,并打開用戶所選的數(shù)據(jù)庫。第一個(gè) @DbColumn 將 Databases by _Replica ID 視圖的第 4 列的值的列表放入臨時(shí)變量 titles 中。第二個(gè) @DbColumn 將 Databases by _Replica ID 視圖的第 2 列的值的列表放入臨時(shí)變量 servers 中。第三個(gè) @DbColumn 將 Databases by _Replica ID 視圖的第 3 列的值的列表放入臨時(shí)變量 databases 中。臨時(shí)變量 list 將 titles,servers 和 databases 組合起來在 @Prompt 中呈現(xiàn)給用戶。然后,該公式將 @Prompt 的返回值分解成服務(wù)器和數(shù)據(jù)庫的名稱以用在 FileOpenDatabase 命令中。titles := @DbColumn(""; "doc":"catalog.nsf"; "Databases by _Replica ID"; 4);servers := @DbColumn(""; "doc":"catalog.nsf"; "Databases by _Replica ID"; 2);databases := @DbColumn(""; "doc":"catalog.nsf"; "Databases by _Replica ID"; 3);list := titles + " *-* " + servers + " *:* " + databases;member := @Prompt([OkCancelList]; "Open Database"; "Select a database"; ""; list);server := @Left(@Right(member; " *-* "  ; " *:* "  ;database := @Right(member; " *:* "  ;@Command([FileOpenDatabase]; server:database)5 (OkCancelListMult) 此按鈕公式向用戶展示了一個(gè)部門名稱及銷售總額的列表。用戶可以從列表中選擇任意數(shù)量的元素,公式計(jì)算其總和。departments := @DbColumn(""; "" : "sales.nsf"; "Main View"; 1);totalSales := @DbColumn(""; "" : "sales.nsf"; "Main View"; 2);totalsList := @Text(totalSales; "C"  + " " + departments;sumList := @Prompt([OkCancelListMult]; "Total sales by department"; "Select the ones you want to sum"; ""; totalsList);sum := @Sum(@TextToNumber(sumList)); @Prompt([OK]; "Sum"; @Text(sum))6 (Custom) 此按鈕公式向用戶展示 DOC 服務(wù)器上的 CATALOG.NSF 中的 Databases by Replica ID 視圖。用戶從列表(視圖)中選擇一個(gè)元素(行),此公式將打開該行中第 3 列所指定的數(shù)據(jù)庫。name := @PickList([Custom]; "doc" : "catalog"; "Databases by Replica ID"; "Open database"; "Select a database that is on server Doc"; 3);@Command([FileOpenDatabase]; "doc" : name)使用 @DialogBox 填寫表單@DialogBox 將在一個(gè)對話框中顯示一個(gè)設(shè)計(jì)的表單,其中有“確定”和“取消”按鈕。當(dāng)用戶單擊“確定”時(shí),對話框中的某個(gè)域的內(nèi)容將被傳遞到當(dāng)前文檔同名的域中。@DialogBox 不傳遞 RTF 文本。在設(shè)計(jì)時(shí)要注意不能包含 RTF 文本。出現(xiàn)在對話框中的表單最好使用一個(gè)區(qū)域布局來創(chuàng)建,而且 @DialogBox 應(yīng)該使用[AutoVertFit] 和 [AutoHorzFit] 選項(xiàng)。樣例:使用 @DialogBox 填寫表單假如您有一個(gè)包含很多域的表單,但用戶通常在創(chuàng)建文檔時(shí)只填寫其中很少的幾個(gè)域。這時(shí)您可以創(chuàng)建另一個(gè)叫做“Dialog”的隱藏表單,在這個(gè)表單中包含一個(gè)區(qū)域布局,其中有用戶通常填寫的域。在主表單的最上面,您可以創(chuàng)建一個(gè)包含下列公式的按鈕。當(dāng)用戶單擊此按鈕時(shí),此公式將使用“Dialog”表單顯示一個(gè)對話框。用戶可以在對話框中填寫域然后單擊“確定”,于是填寫的內(nèi)容便被傳遞到主表單中。@DialogBox("Dialog"; [AutoVertFit] : [AutoHorzFit])取得和設(shè)置環(huán)境變量您可以從 NOTES.INI 文件中設(shè)置和提取環(huán)境變量(Windows,OS/2 和 UNIX 都適用)。@SetEnvironment(variable; value) 將一個(gè)已命名的變量設(shè)置成指定的值。您也可以用 ENVIRONMENT 關(guān)鍵字和雙參數(shù)形式的 @Environment。@Environment(variable) 提取一個(gè)已命名變量的值。環(huán)境變量的值是文本。非文本值必須在設(shè)置值之前和提取值之后轉(zhuǎn)換成文本。用戶環(huán)境變量是以 $ 字符開頭的。如果您用編輯器或者 LotusScript 添加一個(gè)環(huán)境變量,此后您還想用 @Environment 提取的話,那么它的第一個(gè)字符必須是 $。請了確信您已經(jīng)清楚了您的公式將會影響到哪個(gè) NOTES.INI 文件。如果公式在一個(gè)服務(wù)器數(shù)據(jù)庫中,則以下幾種情況下公式是運(yùn)行在服務(wù)器上的:復(fù)制公式、由“當(dāng)一個(gè)新郵件到來時(shí)執(zhí)行”和定時(shí)執(zhí)行觸發(fā)的代理、選擇公式或者列公式。否則,公式將運(yùn)行于用戶的工作站上。復(fù)本拷貝將根據(jù)其所在的服務(wù)器或工作站決定訪問不同的 NOTES.INI 文件。服務(wù)器訪問服從于管理限制(請參閱在“Notes 管理幫助”中的“限制服務(wù)器上的代理” 或者“管理員指南”)。環(huán)境變量的作用有:在不同的公式和數(shù)據(jù)庫之間傳遞臨時(shí)數(shù)據(jù)。為一個(gè)用戶生成連續(xù)的數(shù)字。樣例:取得和設(shè)置環(huán)境變量1. 該樣例將一個(gè)數(shù)字轉(zhuǎn)換成文本并將其保存在一個(gè)環(huán)境變量中。ENVIRONMENT OrderNumber := @Text(NewOrderNumber);以下公式是等效的。@Environment("OrderNumber"; @Text(NewOrderNumber);@SetEnvironment("OrderNumber"; @Text(NewOrderNumber);2. 該樣例提取一個(gè)環(huán)境變量的值,并將其轉(zhuǎn)換成一個(gè)數(shù)字并存放在局部變量中。OldOrderNumber := @TextToNumber(@Environment("OrderNumber"  ;3. 該樣例適用于“創(chuàng)建時(shí)計(jì)算”域。該公式保留有一個(gè)叫“OrderNumber”的環(huán)境變量。每當(dāng)創(chuàng)建了一個(gè)新文檔時(shí),此公式從環(huán)境變量中取得該值然后加一。這種計(jì)算法對于一個(gè)要進(jìn)行復(fù)制的數(shù)據(jù)庫是不適用的,數(shù)據(jù)庫必須存在于單個(gè)服務(wù)器或工作站上,而且公式必須運(yùn)行在相同的機(jī)器上。OldOrderNumber := @Environment("OrderNumber"  ;NewOrderNumber := @TextToNumber(@If(OldOrderNumber = ""; "0"; OldOrderNumber)) + 1;ENVIRONMENT OrderNumber := @Text(NewOrderNumber);NewOrderNumber;4. 第一個(gè)公式被每個(gè)銷售人員運(yùn)行一次。該公式提示用戶輸入銷售地區(qū),并將其存放在一個(gè)叫“SalesArea”的環(huán)境變量中。在銷售文檔的表單中,您將第二個(gè)公式用作 SalesArea 域的缺省值公式。該公式從環(huán)境變量中取得值。這樣銷售人員便不再需要為每個(gè)新文檔輸入銷售地區(qū)的信息了,而且也避免了在缺省值公式中硬性規(guī)定一個(gè)銷售區(qū)域。ENVIRONMENT SalesArea := @Prompt([OKCANCELLIST]; "Sales Area"; "What is your sales area?"; "Central"; "East" : "Central" : "West"  ;@Environment("SalesArea"  ;處理錯誤的方法錯誤有兩種類型:語法錯誤當(dāng)您確認(rèn)或退出正在編寫的公式時(shí)可能會出現(xiàn)語法錯誤的提示。您將接到一條指定錯誤的消息,有錯誤的行被突出顯示出來。必須查出錯誤并改正它。通常,語法錯誤包括:函數(shù)名稱或關(guān)鍵字拼寫錯誤缺少括號或括號多余字符串常量兩邊缺引號語句之間沒有分號您最好在寫公式時(shí)隨時(shí)檢查。多重嵌套可能會使公式的語法非常復(fù)雜。運(yùn)行錯誤運(yùn)行錯誤在公式運(yùn)行的時(shí)候發(fā)生。這種錯誤可分為以下幾類:無法預(yù)料的錯誤 — 這是在開發(fā)時(shí)出現(xiàn)的錯誤,您的用戶是看不見的。例如,如果遺漏了函數(shù)的某個(gè)參數(shù),則在運(yùn)行時(shí)將出現(xiàn)以下消息:“函數(shù)的參數(shù)不夠”。應(yīng)該測試公式盡量修正所有無法預(yù)料的錯誤。不予匯報(bào)的錯誤 — 這些是錯誤的結(jié)果,但是并不當(dāng)作錯誤匯報(bào)。例如,如果試圖用 @Prompt 來顯示一個(gè)數(shù)字值,@Prompt 可以運(yùn)行,但顯示為空白。您的用戶永遠(yuǎn)也看不見這些錯誤。應(yīng)該測試公式,確保所有結(jié)果都是正確的??梢灶A(yù)料的錯誤 — 這些錯誤可能是用戶在運(yùn)行公式時(shí)造成的。例如,在提示輸入一個(gè)數(shù)據(jù)庫的名稱時(shí),用戶輸入了一個(gè)并不存在的數(shù)據(jù)庫名稱。無法阻止這些錯誤的發(fā)生但可以預(yù)計(jì)得到,或者可以有意測試一下,然后給出適當(dāng)?shù)慕鉀Q辦法。以下函數(shù)可以幫助您處理運(yùn)行錯誤:@IsError(value),當(dāng)它發(fā)現(xiàn)一個(gè)域、臨時(shí)變量或者表達(dá)式中包含錯誤時(shí)就返回 1 。@Error 生成一個(gè)錯誤。@Failure(message),在輸入校驗(yàn)公式中用來顯示消息。@Success 總是返回 1。@Return(value) 終止公式的運(yùn)行并返回一個(gè)值。當(dāng)一個(gè)域內(nèi)嵌的校驗(yàn)檢查失敗時(shí),Notes 將產(chǎn)生一個(gè)錯誤。例如,如果將一個(gè)域指定為數(shù)字型的,而用戶輸入的是一個(gè)非數(shù)字型的值,Notes 將把該域的值設(shè)置為錯誤。您也可以設(shè)置一個(gè)域值為 @Error 來生成錯誤。Notes 在用戶試圖保存文檔時(shí)匯報(bào)域中的錯誤。例如,如果一個(gè)數(shù)字域包含一個(gè)非數(shù)字的值,那么當(dāng)用戶試圖保存文檔時(shí),Notes 將產(chǎn)生一條消息“不能將文本轉(zhuǎn)換為數(shù)字”。為了在錯誤發(fā)生時(shí)改變消息或執(zhí)行另一個(gè)操作,請?jiān)谟虻男r?yàn)公式中使用 @IsError 來檢查域中的錯誤。可以用 @Failure 生成您自己的消息,但僅僅只是在域校驗(yàn)公式中可以這樣做。為了在一個(gè)域中使用您自己的出錯條件,請?jiān)谟蜣D(zhuǎn)換公式中測試域的值,并在檢測出一個(gè)錯誤條件時(shí)返回一個(gè) @Error。除了域公式以外,例如在代理、按鈕或者熱點(diǎn)中,可以檢查域的內(nèi)容并對錯誤條件立即作出反應(yīng)。例如,如果您用一個(gè)按鈕來檢查域,就可以在用戶保存文檔之前修改域值或者報(bào)告錯誤。在檢查錯誤時(shí),值得注意的是,內(nèi)嵌的校驗(yàn)機(jī)制在用戶輸入值時(shí)馬上就可以匯報(bào)錯誤,而使用 @Error 的轉(zhuǎn)換公式直到用戶保存文檔時(shí)才報(bào)告錯誤。樣例:運(yùn)行錯誤1.如果 Price 域中有錯誤的話,這個(gè)校驗(yàn)公式將使該文檔保存失敗,并顯示一條指定的錯誤信息。@If(@IsError(Price); @Failure("The Price field must be numeric"  ; @Success)2. 此樣例包含輸入轉(zhuǎn)換和校驗(yàn)公式。如果 Price 域的值大于 14.99 的話,輸入轉(zhuǎn)換公式將在 Price 域中放置一個(gè)錯誤。如果發(fā)現(xiàn)此錯誤,輸入校驗(yàn)公式它就會使文檔的保存操作失敗,并顯示一條指定的錯誤信息。REM "Input translation formula for Price field";@If(Price > 14.99; @ERROR; Price)REM "Input validation formula for Price field";@If(@IsError(Price); @Failure("The Price field must be numeric and 14.99 or less"  ; @Success)3. 此按鈕公式在對 Price 打折扣之前先檢查它是否有錯誤。如果該域有錯誤,則該公式返回一個(gè)錯誤信息。FIELD Price := @If(!@IsError(Price) & @IsNumber(Price) & Price < 15; Price * 0.85; @Return(@Prompt([OK]; "Error in price field"; "Must be numeric and less than 15.00"; ""  ));@All4. 該按鈕公式檢測 Price 域中是否有錯誤。如果該域含有錯誤,則此公式將該域設(shè)置成一個(gè)通過 @Prompt 從用戶那里得到的值。FIELD Price := @If(!@IsError(Price) & @IsNumber(Price) & Price < 15; Price; @TextToNumber(@Prompt([OKCANCELEDIT]; "Error in price field"; "Enter a number under $15.00"; ""  ));@All使用函數(shù)所有函數(shù)都能計(jì)算出一個(gè)值,并且可以放在公式中任何允許此類型值的地方。當(dāng)公式執(zhí)行的時(shí)候,公式的值代替了公式的位置。有些公式也有附加效果。例如,@Prompt 會產(chǎn)生一個(gè)消息框。大多數(shù)函數(shù)可以用于任意 Notes 對象的公式中,但有一些函數(shù)卻被限制在適當(dāng)?shù)姆秶鷥?nèi)。以下表格列舉了受限的函數(shù),并列舉了它們可以用在哪些對象中。此外,您必須進(jìn)入相應(yīng)的上下文中才能使函數(shù)返回有關(guān)當(dāng)前數(shù)據(jù)庫、視圖、文檔或者域的信息,也就是說,那些對象必須是當(dāng)前的。受限函數(shù) 函數(shù)只應(yīng)用于這些 Notes 對象@All 復(fù)制公式、代理、視圖選擇公式@AllChildren 復(fù)制公式、視圖選擇公式@AllDescendants 復(fù)制公式、視圖選擇公式@Command 便捷圖標(biāo)公式、手動代理、按鈕、操作熱點(diǎn)@DbColumn (Notes 數(shù)據(jù)庫) 便捷圖標(biāo)公式、操作、按鈕、熱點(diǎn)、域設(shè)計(jì)、代理(除郵件以外)@DbLookup (Notes 數(shù)據(jù)庫) 便捷圖標(biāo)公式、操作、按鈕、熱點(diǎn)、域設(shè)計(jì)、代理(除郵件以外)@DeleteDocument 代理@DeleteField 代理@DocChildren 列公式、窗口標(biāo)題公式@DocDescendants 列公式、窗口標(biāo)題公式@DocLevel 列公式、窗口標(biāo)題公式@DocMark 代理@DocNumber 列公式、窗口標(biāo)題公式@DocParentNumber 列公式、窗口標(biāo)題公式@DocSiblings 列公式、窗口標(biāo)題公式@Failure 域校驗(yàn)公式ENVIRONMENT 除彈出式熱點(diǎn)公式以外的所有場合@Environment 除了正在編寫的彈出式熱點(diǎn)公式以外的場合FIELD 便捷圖標(biāo)公式、代理、按鈕、操作熱點(diǎn)、域設(shè)計(jì)@IsCategory 列公式@IsDocBeingLoaded 表單設(shè)計(jì)、域設(shè)計(jì)@IsDocBeingMailed 按鈕、熱點(diǎn)、域設(shè)計(jì)@IsDocBeingRecalculated 按鈕、熱點(diǎn)、域設(shè)計(jì)@IsDocBeingSaved 按鈕、熱點(diǎn)、域設(shè)計(jì)@IsExpandable 列公式@IsNewDoc 便捷圖標(biāo)公式、按鈕、窗口標(biāo)題公式、表單設(shè)計(jì)、域設(shè)計(jì)@MailSend 便捷圖標(biāo)公式、代理、按鈕、操作熱點(diǎn)@PickList 便捷圖標(biāo)公式、手動執(zhí)行的代理、按鈕、操作熱點(diǎn)、域設(shè)計(jì)@Platform 便捷圖標(biāo)公式、手動執(zhí)行的代理、按鈕、熱點(diǎn)、除選擇公式和列公式以外的視圖設(shè)計(jì)、表單設(shè)計(jì)、域設(shè)計(jì)@Prompt 便捷圖標(biāo)公式、手動執(zhí)行的代理、按鈕、操作熱點(diǎn)、域設(shè)計(jì)@Responses 窗口標(biāo)題公式、域設(shè)計(jì)@Return 便捷圖標(biāo)公式、代理、按鈕、熱點(diǎn)、域設(shè)計(jì)SELECT 復(fù)制公式、代理、視圖選擇公式@SetDocField 便捷圖標(biāo)公式、代理、按鈕、操作熱點(diǎn)、域設(shè)計(jì)@SetEnvironment 除了彈出式熱點(diǎn)公式以外的所有場合@SetField 便捷圖標(biāo)公式、代理、按鈕、操作熱點(diǎn)、域設(shè)計(jì)@Success 校驗(yàn)公式@Unavailable 代理@ViewTitle 代理使用命令命令就是一些可以用戶界面中執(zhí)行即時(shí)操作的特殊函數(shù)。大多數(shù)命令是模仿與菜單命令的。例如以下公式,如果從按鈕執(zhí)行,就是將當(dāng)前文檔置于編輯模式并將插入點(diǎn)下移兩次:@Command([EditDocument]; "1"  ;@Command([EditDown]; "2"  命令的語法表示如下:@Command([command-name]; arg1; arg2; ... argn)@PostedCommand([command-name]; arg1; arg2; ... argn)函數(shù)名稱是 @Command 或者 @PostedCommand。第一個(gè)參數(shù)是用方括號括起來的命令名稱。在幫助導(dǎo)航器中選擇“Scripts & formulas”,然后選擇“Notes 公式語言命令 A-Z”即可得到一個(gè)命令的列表,或者請參閱“程序員指南”的第八章。其他則是命令所帶的參數(shù)。您不能在一個(gè)不與用戶交互的公式中使用命令,如定時(shí)代理、域公式或一個(gè)后臺宏。您不能在 Web 應(yīng)用程序中使用大多數(shù)的命令,因?yàn)樗鼈兪腔?Notes 工作站用戶界面的。在 Web 應(yīng)用程序中只能夠使用以下命令(在各個(gè)命令的描述中分別注明了它的限制):[CalendarFormat]、[CalendarGoTo]、[Compose]、[EditClear]、[EditDocument]、[EditInsertFileAttachment]、[FileCloseWindow]、[FileOpenDatabase]、[OpenDocument]、[FileSave]、[NavigateNext]、[NaviagtePrev]、[NavigateNextMain]、[NavigatePrevMain]、[OpenNavigator]、[OpenView]、[ToolsRunMacro]、[ViewChange]、 [ViewExpandAll]、ViewCollapseAll] 和 [ViewShowSearchBar]、[ViewRefreshFields] 和 [FileOpenDBRepID]。@Command 函數(shù)按順序和其他函數(shù)一起執(zhí)行,但有一些例外。例如,以下公式就是先執(zhí)行命令:@Command([EditDocument]; "1"  ;@Prompt([OK]; "Edit mode"; "The document is now in edit mode."  @PostedCommand 函數(shù)將在所有其他函數(shù)執(zhí)行完畢后才按順序執(zhí)行。這是為了模仿 Notes R3 中的 @Command。例如,以下公式將在最后才執(zhí)行命令:@PostedCommand([EditDocument]; "1"  ;@Prompt([OK]; "Edit mode"; "The document will go into edit mode."  您可以檢查 @Command 的返回值(但 @PostedCommand 不行),并對其作出響應(yīng)。如果命令執(zhí)行正確返回值為 @True ,否則返回值為 @False 。以下便捷圖標(biāo)的公式樣例在命令 FileOpenDatabase 執(zhí)行失敗時(shí)返回。@If(@Command([FileOpenDatabase]; "NEWSUBJ"  ; ""; @Return(""  );@Command([Compose]; ""; "Main Topic"  ;@Command([EditGotoField]; "Subject"  ;@Command([EditInsertText]; "New subject"  ;@Command([EditGotoField]; "Body"  執(zhí)行字符串操作的方法公式語言函數(shù)支持?jǐn)?shù)據(jù)類型轉(zhuǎn)換、字符串長度、字符串比較、子串、大小寫和修剪等操作。您可以:轉(zhuǎn)換數(shù)據(jù)類型在對數(shù)據(jù)操作時(shí)類型必須是正確的。以下的函數(shù)用來轉(zhuǎn)換數(shù)據(jù)和測試數(shù)據(jù)類型。函數(shù) 描述@Text(value) 將一個(gè)值轉(zhuǎn)換為文本字符串。@Text(value; format) 根據(jù)指定的格式將一個(gè)數(shù)字或時(shí)間-日期值轉(zhuǎn)換成文本字符串。@TextToNumber(string) 將文本字符串轉(zhuǎn)換成一個(gè)數(shù)字。@TextToTime(string) 將文本字符串轉(zhuǎn)換成一個(gè)日期-時(shí)間值。@IsText(value) 如果值是文本字符串或文本字符串列表,則返回真值 (1) 。@IsNumber(value) 如果值是數(shù)字或數(shù)字列表,則返回真值 (1) 。@IsTime(value) 如果一個(gè)值是時(shí)間-日期或時(shí)間-日期列表,則返回真值 (1)。@Char(number) 將一個(gè) IBM 代碼頁 850 代碼轉(zhuǎn)換為對應(yīng)的字符。樣例:轉(zhuǎn)換數(shù)據(jù)類型1 (@TextToNumber, @Text)。該樣例使用 @Prompt 交互的讀取一個(gè)數(shù)字,計(jì)算其對數(shù),并用 @Prompt 交互的顯示答案。由于 @Prompt 只能處理文本值,所以輸入的值 i 在進(jìn)行對數(shù)計(jì)算之前必須轉(zhuǎn)換成數(shù)字,答案 n 必須在顯示之前必須轉(zhuǎn)換成文本字符串。i := @Prompt([OKCANCELEDIT]; "@Log Test"; "Enter a number"; ""  ;n := @Log(@TextToNumber(i));@If(@IsError(n); @Return(@Prompt([OK]; "@Log Test"; i + " is not a number"  ); ""  ; @Prompt([OK]; "@Log Test"; "The logarithm of " + i + " is " + @Text(n))2 (@Text)。該樣例根據(jù)日期-時(shí)間格式 T1S1 將 @Now 返回的日期-時(shí)間值轉(zhuǎn)換成文本。T1 僅指時(shí)間,S1 僅指小時(shí)和分鐘。在晚上六點(diǎn)時(shí),用戶可以看到一個(gè)信息框,其中的文字以“The time is ...”開頭,后面是“06:00 PM”。@Prompt([OK]; "The time is ..."; @Text(@Now; "T1S1"  )3 (@Text)。該樣例根據(jù)數(shù)字格式 C,2 將數(shù)字 800 轉(zhuǎn)換成文本并予以顯示。C 表示貨幣格式(以美元符開頭),2 表示保留兩位小數(shù)。用戶看到的信息框中的文字以“800 dollars”打頭,后面是“$800.00”。@Prompt([OK]; "800 dollars"; @Text(800; "C,2"  )4 (@Text, @TextToTime)。此樣例將文本字符串“Today”轉(zhuǎn)換成當(dāng)天的日期,然后將此日期轉(zhuǎn)換成文本供 @Prompt 使用。例如,如果今天是 1995 年 7 月 8 日,用戶將看到一個(gè)信息框,其中的文字以“Today‘s Date”開頭,后面跟著“07/08/95”。@Prompt([OK]; "Today‘s Date"; @Text(@TextToTime("Today"  ))5 (@IsNumber)。此樣例將域 A 和 B 相加。如果某一個(gè)域不是數(shù)字型的話,它將被轉(zhuǎn)換成數(shù)值 0。因?yàn)橛脩魺o法在一個(gè)數(shù)字域中輸入非數(shù)字的值,所以如果一個(gè)數(shù)字域是空的,并且沒有缺省值公式的話,它的缺省值就是一個(gè)空的文本字符串。此公式中的 @IsNumber 函數(shù)就避免了這個(gè)情況。@If(@IsNumber(A); A; 0) + @If(@IsNumber(B); B; 0)6 (@Char)。此樣例將整數(shù) 65 轉(zhuǎn)換成大寫字符 A。@Prompt([OK]; "IBM Code Page 850 code 65"; @Char(65))連接、比較和判定長度+ 運(yùn)算符用來連接字符串。=、<>、!=、=!、><、<、>、<= 和 >= 運(yùn)算符用來比較字符串。以下的函數(shù)用來判定字符串的長度和比較字符串:函數(shù) 描述@Length (string) 返回字符串的長度,以字符為單位。@Length(stringlist) 返回字符串列表中每個(gè)元素的長度,以字符為單位。@Matches (string; pattern) 判定兩個(gè)字符串是否匹配??梢杂猛ㄅ浞麃頂U(kuò)展比較的范圍。@Like (string; pattern) 判定兩個(gè)字符串是否匹配。遵循 ANSI SQL 標(biāo)準(zhǔn)。@Like(string; pattern; esc) 與上面的一樣只是多了一個(gè)轉(zhuǎn)義字符。@Matches 用 ? 來匹配任意一個(gè)單獨(dú)的字符,用 * 來匹配任意的字符序列,此序列中也可以包括其他的通配符。@Like 使用 _(下劃線)來匹配任意一個(gè)單獨(dú)的字符,用 %(百分號)來匹配任意的字符序列,符合 ANSI X3.135-1992 標(biāo)準(zhǔn)。@Matches 使用 作為轉(zhuǎn)義字符。樣例:連接、比較和判定長度1 (+)。該樣例連接兩個(gè)字符串以形成 ABCDEF。@Prompt([OK]; "Concatenation"; "ABC" + "DEF"  2 (+)。該樣例連接兩個(gè)輸入的字符串。Input1 := @Prompt([OKCANCELEDIT]; "Concatenation - first element"; "Enter any text in the box"; "ABC"  ;Input2 := @Prompt([OKCANCELEDIT]; "Concatenation - second element"; "Enter any text in the box"; "DEF"  ; @Prompt([OK]; "Concatenation - result"; Input1 + Input2)3 (=)。如果兩個(gè)輸入字符串相等,該樣例為 YesNo 返回 True,如果不等的話則為 YesNo 返回 False。Input1 := @Prompt([OKCANCELEDIT]; "Comparison - first element"; "Enter any text in the box"; "ABC"  ;Input2 := @Prompt([OKCANCELEDIT]; "Comparison - second element"; "Enter any text in the box"; "DEF"  ;YesNO := @If(Input1 = Input2; "The strings are equal"; "The strings are not equal"  ; @Prompt([OK]; "Comparison - result"; YesNo)4 (@Length)。該樣例顯示 9,即字符串 abcdefghi 的長度。@Prompt([OK]; "Length of abcdefghi"; @Text(@Length("abcdefghi"  ))5 (@Length)。該樣例創(chuàng)建一個(gè)數(shù)字列表。該列表中的每個(gè)元素包含 TextList 中相應(yīng)元素的長度。@Length(TextList)6 (@Matches)。如果輸入 abc,則該樣例在 YesNo 中返回 True。Input := @Prompt([OKCANCELLIST]; "@Matches Input"; "Choose one"; "abc"; "abc" : "bcd" : "cde" : "xyz" : "123"  ;YesNo := @If(@Matches(Input; "abc"  ; " matches abc"; " does not match abc"  ; @Prompt([OK]; "@Matches Result"; Input + YesNo)7 (@Matches). 該樣例為 YesNo 返回 True,如果輸入的每個(gè)字符都是字母的話,也就是說,從 a 到 z 的范圍內(nèi)。集合 {a-z} 指定字母的范圍,前面的 + 表示任意多個(gè)字母。Input := @Prompt([OKCANCELLIST]; "@Matches Input"; "Choose one"; "abc"; "abc" : "bcd" : "cde" : "xyz" : "123"  ;YesNo := @If(@Matches(Input; "+{a-z}"  ; " matches +{a-z}"; " does not match +{a-z}"  ; @Prompt([OK]; "@Matches Result"; Input + YesNo)8 (@Matches)。如果每個(gè)輸入的字符都不是字母,也就是說,在集合 {a-z} 之外,則該樣例為 YesNo 返回 True。{!a-z} 表示不在集合 a 到 z 中。前面的 + 表示任意多個(gè)字母。Input := @Prompt([OKCANCELLIST]; "@Matches Input"; "Choose one"; "abc"; "abc" : "bcd" : "cde" : "xyz" : "123"  ;YesNo := @If(@Matches(Input; "+{!a-z}"  ; " matches +{!a-z}"; " does not match +{!a-z}"  ; @Prompt([OK]; "@Matches Result"; Input + YesNo)9 (@Matches)。如果輸入包含由任意數(shù)目字符包圍的連續(xù)的 bc 字符,則該樣例為 YesNo 返回 True。Input := @Prompt([OKCANCELLIST]; "@Matches Input"; "Choose one"; "abc"; "abc" : "bcd" : "cde" : "xyz" : "123"  ;YesNo := @If(@Matches(Input; "*bc*"  ; " matches*bc*"; " does not match *bc*"  ; @Prompt([OK]; "@Matches Result"; Input + YesNo)10 (@Matches)。如果輸入是以 a 開始并且有三個(gè)字符長,或者輸入以 1 開始并且有三個(gè)字符長,則該樣例為 YesNo 返回 True。Input := @Prompt([OKCANCELLIST]; "@Matches Input"; "Choose one"; "abc"; "abc" : "bcd" : "cde" : "xyz" : "123"  ;YesNo := @If(@Matches(Input; "a??|1??"  ; " matches a??|1??"; " does not match a??|1??"  ; @Prompt([OK]; "@Matches Result"; Input + YesNo)11 (@Like)。該代理檢查每個(gè)文檔中 textBody 域內(nèi)的兩個(gè)字符串集合。第一個(gè)字符串是順序包含“acquisition”和“Acme”的任何文本。第二個(gè)字符串是順序包含“Acme”和“51%”的任何文本。第二個(gè) @Like 語句使用斜杠 (/) 作為轉(zhuǎn)義字符,因而可以指定百分號 (%)。不要使用反斜杠 () 作為轉(zhuǎn)義字符。@If(@Like(textBody; "%acquisition%Acme%"  ; @Prompt([OK]; "Found reference to "acquisition""; Subject); ""  ;@If(@Like(textBody; "%Acme%51/%%"; "/"  ; @Prompt([OK]; "Found reference to "51%""; Subject); ""  ;SELECT @All查找并提取子串以下函數(shù)查找并提取子串:函數(shù) 描述@Contains(string; sub) 判定一個(gè)字符串是否包含一個(gè)子串。@Contains(string; list) 判定一個(gè)字符串是否包含一個(gè)列表中的子串。@Begins(string; sub) 判定一個(gè)字符串是否以一個(gè)子串開始。@Ends(string; sub) 判定一個(gè)字符串是否以一個(gè)子串結(jié)束。@Left(string; n) 從一個(gè)字符串中提取最左邊的 n 個(gè)字符。@Left(string; sub) 從一個(gè)字符串中提取最左邊的字符,直到一個(gè)子串為止,從左到右搜索。@LeftBack(string; n) 從一個(gè)字符串中提取最左邊的字符,直到從右邊開始的第 n 個(gè)字符為止。@LeftBack(string; sub) 從一個(gè)字符串中提取最左邊的字符,直到一個(gè)子串為止,從右到左搜索。@Right(string; n) 從一個(gè)字符串中提取最右邊的 n 個(gè)字符。@Right(string; sub) 從一個(gè)字符串中提取最右邊的字符,直到一個(gè)子串為止,從左到右搜索@RightBack(string; n) 從一個(gè)字符串中提取最右邊的字符,直到從右邊開始的第 n 個(gè)字符為止。@RightBack(string; sub) 從一個(gè)字符串中提取最右邊的字符,直到一個(gè)子串為止,從右到左搜索。@Middle(string; off; n) 從一個(gè)字符串中提取 n 個(gè)字符,從一個(gè)偏移量開始,從左到右搜索。@Middle(string; sub; n) 從一個(gè)字符串中提取 n 個(gè)字符,從一個(gè)子串開始,從左到右搜索。@Middle(string; off; sub) 從一個(gè)字符串中提取字符,從一個(gè)偏移量開始,到一個(gè)子串結(jié)束,從左到右搜索。@Middle(string; sub; sub) 從一個(gè)字符串中提取字符,從一個(gè)子串開始,到另一個(gè)子串結(jié)束,從左到右搜索。@MiddleBack(str; off; n) 從一個(gè)字符串中提取 n 個(gè)字符,從一個(gè)偏移量開始,從右到左搜索。@MiddleBack(str; sub; n) 從一個(gè)字符串中提取 n 個(gè)字符,從一個(gè)子串開始,從右到左搜索。@MiddleBack(str; off; sub) 從一個(gè)字符串中提取字符,從一個(gè)偏移量開始,到一個(gè)子串結(jié)束,從右到左搜索。@MiddleBack(str; sub; sub) 從一個(gè)字符串中提取字符,從一個(gè)子串開始,到另一個(gè)子串結(jié)束,從右到左搜索。@ReplaceSubstring(source; from; to) 在 source 中用 from 的內(nèi)容替換 to 的內(nèi)容。如果 from 和 to 都是列表,按次序替換對應(yīng)的項(xiàng)目。@Word(string; sep; n) 從 string 提取單詞 n,其中單詞是在指定的分隔符之間的文本。@Word(list; sep; n) 從列表中的每個(gè)字符串中提取單詞 n,其中單詞是在指定的分隔符之間的文本。樣例:查找并提取子串1 (@Contains)。如果 Substring 在 String 中的某個(gè)地方出現(xiàn),則該樣例為 R 返回 True。該搜索是區(qū)分大小寫的。String := @Prompt([OKCANCELEDIT]; "String"; "Enter a string"; ""  ;Substring := @Prompt([OKCANCELEDIT]; "Substring"; "Enter a beginning substring"; ""  ;Yes := Substring + " is in " + String;No := Substring + " is not in " + String;R := @Contains(String; Substring);@If(R; @Prompt([OK]; "Yes"; Yes); @Prompt([OK]; "No"; No))2 (@Contains)。如果 Substring1 或 Substring2 在 String 的某個(gè)地方出現(xiàn),則該樣例為 R 返回 True。該搜索是區(qū)分大小寫的。String := @Prompt([OKCANCELEDIT]; "String"; "Enter a string"; ""  ;Substring1 := @Prompt([OKCANCELEDIT]; "Substring"; "Enter substring 1"; ""  ;Substring2 := @Prompt([OKCANCELEDIT]; "Substring"; "Enter substring 2"; ""  ;Yes := Substring1 + " or " + Substring2 + " is in " + String;No := Substring1 + " and " + Substring2 + " are not in " + String;R := @Contains(String; Substring1 : Substring2);@If(R; @Prompt([OK]; "Yes"; Yes); @Prompt([OK]; "No"; No))3 (@Left)。該樣例為 R 返回 String 中最左邊的 N 個(gè)字符。String := @Prompt([OKCANCELEDIT]; "String"; "Enter a string"; ""  ;Number := @Prompt([OKCANCELEDIT]; "Number of characters"; "Enter a number of characters"; ""  ;N := @TextToNumber(Number);R := @Left(String; N); @Prompt([OK]; "Leftmost characters"; R)4 (@Left)。該樣例為 R 返回 String 中的 Substring 左邊的字符。String := @Prompt([OKCANCELEDIT]; "String"; "Enter a string"; ""  ;Substring := @Prompt([OKCANCELEDIT]; "Substring"; "Enter a substring"; ""  ;R := @Left(String; Substring); @Prompt([OK]; "Characters left of " + Substring; R)5 (@RightBack, @Left)。如果在 ComposedBy 域中的公共名是“Judith Woo”,本公式計(jì)算出“Woo, Judith”。@RightBack 返回姓,@Left 返回名。@RightBack(@Name([CN]; ComposedBy); " "  + ", " + @Left(@Name([CN]; ComposedBy); " "  6 (@Middle)。該樣例為 R 返回 String 中從 Substring 以后開始的 N 個(gè)字符。String := @Prompt([OKCANCELEDIT]; "String"; "Enter a string"; ""  ;Substring := @Prompt([OKCANCELEDIT]; "Substring"; "Enter a substring"; ""  ;Number := @Prompt([OKCANCELEDIT]; "Number of Characters"; "Enter the number of characters"; ""  ;N := @TextToNumber(Number);R := @Middle(String; Substring; N); @Prompt([OK]; Number + " characters starting after " + Substring; R)7 (@ReplaceSubstring)。此代理樣例對所選文檔的 textBody 域作了三個(gè)替換。第三個(gè)替換是為了避免句子結(jié)尾連續(xù)出現(xiàn)兩個(gè)句號。FIELD textBody := @ReplaceSubstring(textBody; "Acme" : "mousetrap" : ".." ; "Acme, Inc." : "mouse detention device" : "."  ;SELECT @All8 (@Word)。該樣例從字符串 s 中提取單詞 n ,用空格作為單詞分隔符。s := @Prompt([OKCANCELEDIT]; "String"; "Enter a string of words"; ""  ;n := @Prompt([OKCANCELEDIT]; "Word"; "Enter the number of the word to extract"; ""  ;ss := @Word(s; " "; @TextToNumber(n)); @Prompt([OK]; "Substring"; "Word " + n + " is "" + ss + """  修剪、重復(fù)、添加新行,并改變大小寫以下函數(shù)修剪字符串、重復(fù)字符、添加新行(回車),并改變大小寫:函數(shù) 描述@Trim(string) 從字符串中刪除開頭、結(jié)尾和多余的空格。@Trim(list) 從字符串列表的每個(gè)元素中刪除開頭、結(jié)尾和多余的空格,并從列表中刪除空白元素。@Repeat(string, number) 將字符串 string 重復(fù) number 次。@NewLine 在字符串中插入一個(gè)新行(回車)。@LowerCase(string) 將字符串中所有的大寫字符轉(zhuǎn)換成小寫。@UpperCase(string) 將字符串中所有的小寫字符轉(zhuǎn)換成大寫。@ProperCase 將字符串中每個(gè)單詞的第一個(gè)字符轉(zhuǎn)換成大寫,并將其余的字符轉(zhuǎn)換為小寫。樣例:修剪、重復(fù)、添加新行,并改變大小寫1 (@Trim)。該樣例返回 [Now is the time],刪除全部多余的空格。Untrimmed := " Now is the time ";Trimmed := @Trim(Untrimmed);@Prompt([OK]; "Untrimmed"; "[" + Untrimmed + "]"  ;@Prompt([OK]; "Trimmed"; "[" + Trimmed + "]"  2 (@Trim, @ProperCase)。該樣例將 Name 中的單詞轉(zhuǎn)換成首字母大寫的單詞,并刪除開頭、結(jié)尾和多余的空格。如果為 Name 輸入“ jane j smith”,該公式將它轉(zhuǎn)換為“Jane J Smith”。@Trim(@ProperCase(Name))3 (@Repeat)。如果 Sales 域大于或等于 100,000,則本樣例在 Comments 域中返回“Great Month! Great Month! Great Month!”FIELD Comments := @If(Sales >= 100000; @Repeat("Great Month! "; 3); Sales >= 50000; "Good Month"; "I want to see you in my office"  ;SELECT @All4 (@NewLine)。本樣例返回由一個(gè)新行分隔開的用戶名和日期。@UserName + @NewLine + @Text(@Now)5 (@LowerCase)。本樣例返回小寫的用戶名。@LowerCase(@UserName)6 (@UpperCase)。本樣例返回大寫的用戶名。@UpperCase(@UserName)執(zhí)行算術(shù)運(yùn)算乘、除、加、減運(yùn)算符 (* / + -)。乘法和除法運(yùn)算符的優(yōu)先級高于加法和減法;運(yùn)算的順序是從左到右。以下列出的是一些算術(shù)運(yùn)算函數(shù)。函數(shù) 描述@Abs(number) 計(jì)算一個(gè)數(shù)的絕對值。@Sign (number) 對于正數(shù)返回 1,對于負(fù)數(shù)則返回 -1,對于零則返回 0。@Sum(num; num; ...) 計(jì)算數(shù)字和數(shù)字列表的和。@Integer(number) 去掉數(shù)字的小數(shù)部分。@Integer(numberlist) 去掉數(shù)字列表元素的小數(shù)部分。@Round(number) 對一個(gè)數(shù)字進(jìn)行四舍五入。@Round(number; factor) 以一個(gè)指定的因子規(guī)整數(shù)字。@Round(numberlist) 將列表中的每個(gè)數(shù)字都進(jìn)行四舍五入。@Round(numlist; factor) 以一個(gè)指定的因子規(guī)整數(shù)字列表中的每個(gè)元素。@Max(number; number) 取兩個(gè)數(shù)中最大的一個(gè)。@Max(numlist; numlist) 用矩陣式的列表操作計(jì)算最大值。@Min(number; number) 取得兩個(gè)數(shù)中最小的一個(gè)。@Min(numlist; numlist) 用矩陣式的列表操作計(jì)算最小值。@Modulo(number; number) 計(jì)算第一個(gè)數(shù)被第二個(gè)數(shù)除之后得出的余數(shù)。@Modulo(numlist; numlist) 用矩陣式列表操作計(jì)算余數(shù)。@Power(base; exp) 指數(shù)運(yùn)算。@Sqrt (number) 計(jì)算平方根。@Pi 圓周率值。@Log(number) 計(jì)算常用對數(shù)。@Ln(number) 計(jì)算自然對數(shù)。@Exp(number) 計(jì)算以 e 為底的指數(shù)。@Random 返回一個(gè) 0 到 1 之間的隨機(jī)數(shù)。@Sin(angle) 計(jì)算角度的正弦(弧度)。@Cos(angle) 計(jì)算角度的余弦(弧度)。@Tan(angle) 計(jì)算角度的正切(弧度)@Asin(sine) 反正弦函數(shù)。@Acos(cosine) 反余弦函數(shù)@Atan(tangent) 反正切函數(shù)@Atan2(x; y) y/x 正切值的反正切函數(shù)樣例:執(zhí)行算術(shù)運(yùn)算1 (*, 優(yōu)先級)。對于第一個(gè) @Prompt,該例樣打印 15,因?yàn)橄葓?zhí)行乘法 4 * 3。對于第二個(gè) @Prompt 該樣例打印 21,因?yàn)槔ㄌ枏?qiáng)制先運(yùn)算 3 + 4。@Prompt([OK]; "3 + 4 * 3"; @Text(3 + 4 * 3)); @Prompt([OK]; "(3 + 4) * 3"; @Text((3 + 4) * 3))2 (/ *)。該樣例對于第一個(gè) @Prompt 打印 0.333333333333333,先執(zhí)行除法再將結(jié)果四舍五入精確到小數(shù)點(diǎn)后 15 位。對于第二個(gè) @Prompt,該樣例打印 1.2635268885E+17,顯示結(jié)果的 11 位小數(shù)作為乘以 1017 的系數(shù)。@Prompt([OK]; "1 / 3"; @Text(1 / 3)); @Prompt([OK]; "123456789 * 1023456789"; @Text(123456789 * 1023456789))3 (@Abs)。該樣例計(jì)算 Score1 與 Score2 之差的絕對值。@Abs(Score1 - Score2)4 (@Abs)。該樣例計(jì)算 Sales 和 CostOfSales 之差的絕對值,在文本域中將它格式化,并用括號括在負(fù)數(shù)結(jié)果兩邊。GP := @Abs(Sales - CostOfSales); @If(Sales >= CostOfSales; @Text(GP); "(" + @Text(GP) + "  "  5 (@Sign)。該代理樣例顯示 Total 域。如果域值是負(fù)數(shù),則在括號中放置的是它的絕對值;如果域值是0,則顯示“Zero”。sign := @Sign(Total);display := @If(sign = 1; @Text(Total); sign = -1; "(" + @Text(@Abs(Total)) + "  "; "Zero"  ;@Prompt([OK]; "Total"; display);SELECT @All6 (@Sum)。該樣例打印 15,列表 One23、變量 Four 和常量 5 的總和。One23 := 1 : 2 : 3; Four := 4;S := @Sum(One23; Four; 5); @Prompt([OK]; "Sum of 1-5"; @Text(S))7 (@Integer)。該樣例將 3.12 截為 3 而將 6.735 截為 6。@Prompt([OK]; "@Integer(3.12)"; @Text(@Integer(3.12))); @Prompt([OK]; "@Integer(6.735)"; @Text(@Integer(6.735)))8 (@Integer)。該樣例在列表中將 Sales 和 Commission 截為整數(shù)。@Integer(Sales : Commission)9 (@Round)。該樣例將 3.12 四舍五入為 3,將 6.735 取為 7,7.5 取為 8;753 以 10 為因子歸整為 750; 列表元素中的 3.12、 6.735 和 7.5 分別歸整為 3、 6 和 7(把它們轉(zhuǎn)換為文本字符串以顯示)。@Prompt([OK]; "@Round(3.12)"; @Text(@Round(3.12))); @Prompt([OK]; "@Round(6.735)"; @Text(@Round(6.735))); @Prompt([OK]; "@Round(7.5)"; @Text(@Round(7.5))); @Prompt([OK]; "@Round(753; 10)"; @Text(@Round(753; 10))); @Prompt([OK]; "@Round(3.12 : 6.735 : 7.5)"; @Implode(@Text(@Round(3.12 : 6.735 : 7.5))))10 (@Max)。該樣例打印 3,即 1 和 3 中的最大值,第二個(gè)樣例打印 99 6 7 8,即分別是兩個(gè)列表中平行元素的最大值。@Prompt([OK]; "@Max(1; 3)"; @Text(@Max(1; 3))); @Prompt([OK]; "@Max(99 : 2 : 3; 5 : 6 : 7 : 8)"; @Implode(@Text(@Max(99 : 2 : 3; 5 : 6 : 7 : 8))))11 (@Min)。該樣例打印 1,即 1 和 3 中的最小值,第二個(gè)樣例打印 5 2 3 3,即分別是兩個(gè)列表中平行元素的最小值。@Prompt([OK]; "@Min(1; 3)"; @Text(@Min(1; 3))); @Prompt([OK]; "@Min(99 : 2 : 3; 5 : 6 : 7 : 8)"; @Implode(@Text(@Min(99 : 2 : 3; 5 : 6 : 7 : 8))))12 (@Modulo)。該樣例打印 4/3 的余數(shù) 1;-14/3 的余數(shù) -2,(當(dāng)被除數(shù)是負(fù)數(shù)時(shí),余數(shù)是負(fù)數(shù));還有 1 2 3 3,這分別是第一個(gè)列表中的被除數(shù)除以對應(yīng)的第二個(gè)列表中的除數(shù)的余數(shù)。@Prompt([OK]; "@Modulo(4; 3)"; @Text(@Modulo(4; 3))); @Prompt([OK]; "@Modulo(-14; 3)"; @Text(@Modulo(-14; 3))); @Prompt([OK]; "@Modulo(4 : 6 : 8 : 9; 3 : 4 : 5 : 6)"; @Implode(@Text(@Modulo(4 : 6 : 8 : 9; 3 : 4 : 5 : 6))))13 (@Modulo)。該樣例確定輸入的數(shù)字是奇數(shù)還是偶數(shù)(被 2 除其余數(shù)為 0)。n := @TextToNumber(@Prompt([OKCANCELEDIT]; "Input Number"; "Type a number"; ""  ); @Prompt([OK]; "The number is ..."; @If(@Modulo(n; 2) = 0; "Even"; "Odd"  )14 (@Power)。該樣例打印 2 的 3 次冪即 8,和 -2 的 3 次冪即 -8,和 2 的 -3次冪即 0.125。@Prompt([OK]; "@Power(2; 3)"; @Text(@Power(2; 3))); @Prompt([OK]; "@Power(-2; 3)"; @Text(@Power(-2; 3))); @Prompt([OK]; "@Power(2; -3)"; @Text(@Power(2; -3)))15 (@Sqrt, @Power)。該樣例是用于一個(gè)計(jì)算域的值公式,計(jì)算矩形的斜邊,該矩形的邊在 Length 和 Width 域中指定。@If(Length = "" | Width = ""; ""; @Sqrt(@Power(Length; 2) + @Power(Width; 2)))16 (@Pi, @Power)。該樣例是用于一個(gè)計(jì)算域的值公式,計(jì)算一個(gè)圓形的面積,該圓形的半徑在 Radius 域中指定。@If(Radius = ""; ""; @Pi * @Power(Radius; 2))17 (@Log)。該樣例打印 0.602059991327962 和 14,它們分別是 4 和 1014 的常用對數(shù)。@Prompt([OK]; "Common log of 4"; @Text(@Log(4))); @Prompt([OK]; "Common log of 1.0E+14"; @Text(@Log(1.0E+14)))18 (@Ln)。該樣例打印 0.693147180559945,即 2 的自然對數(shù)。@Prompt([OK]; "Natural log of 2"; @Text(@Ln(2)))19 (@Exp)。該樣例計(jì)算出第一個(gè) @Exp 函數(shù)值為 2.71828182845904 (e 的值),第二個(gè) @Exp 函數(shù)值為 3.49034295746184 (e 的 1.25 次冪),第三個(gè) @Exp 函數(shù)值為 0.28650479686019 (e 的 -1.25 次冪)。@Prompt([OK]; "e to 1"; @Text(@Exp(1))); @Prompt([OK]; "e to 1.25"; @Text(@Exp(1.25))); @Prompt([OK]; "e to -1.25"; @Text(@Exp(-1.25)))20 (@Random)。 
 [ 本貼由 huchungling 于 2003-10-1 11:08 最后編輯 ]
 |  |  
|  2003-9-30 14:16 |  |  |  
| 
| myfeeling 版主
 
        
 
 中文網(wǎng)金幣 13 個(gè)
 發(fā)帖 375 篇
 注冊 2003-9-10
 狀態(tài) Offline
 
 | 
| 綜合使用JavaScript、LotusScript Agent和Formula的技巧(3) 
 該視圖操作樣例從用戶那里取得一個(gè)數(shù)字,并將它和 1 到 99 之間的隨機(jī)數(shù)比較,包含 1 和 99 。userNumber := @Prompt([OKCANCELEDIT]; "Number"; "Must be 1-99"; "");winningNumber := @Text(@Integer(98 * @Random + 1));@Prompt([OK]; "Result"; @If(userNumber = winningNumber; "YOU WIN"; "Sorry - winning number is " + winningNumber))21 (@Sin, @Cos)。該樣例顯示兩個(gè)計(jì)算域的公式。第一個(gè)公式計(jì)算矩形的長,第二個(gè)公式計(jì)算矩形的寬。Diagonal * @Sin(Angle * @Pi / 180)Diagonal * @Cos(Angle * @Pi / 180)執(zhí)行時(shí)間/日期運(yùn)算時(shí)間-日期值包含年、月、日、小時(shí)、分鐘和秒。您可以象在時(shí)間-日期域中那樣使用一個(gè)時(shí)間-日期值,但是必須用 @Text 把它們轉(zhuǎn)換為字符串。您可以用 @TextToTime 將一個(gè)字符串轉(zhuǎn)換成時(shí)間-日期值。時(shí)間-日期常量可以是日期、時(shí)間或者兩者的結(jié)合,它們被括在方括號中。日期的格式是年、月、日(年份可選。缺省為當(dāng)前年;兩位數(shù)的年如果年數(shù)大于或等于 50 表示是在 20 世紀(jì),如果年數(shù)小于 50 表示是在 21 世紀(jì)),由斜杠 (/) 或連字符 (-)(對于 OS/2)分開。時(shí)間的格式是小時(shí)、分鐘、秒(可選。缺省為 0),由冒號分開。您可以使用 24 小時(shí)的時(shí)間形式或用“PM”表示下午時(shí)間。您可以增加時(shí)區(qū)以指示一個(gè)時(shí)區(qū)。將這些部分用空格分開。以下是幾個(gè)時(shí)間/日期常量的例子:[6/30/97]、[5:30:00 PM]、[17:30:00]、[17:30 EST]、[6/30 5:30 PM]。日期可以進(jìn)行比較或做減法。減法操作的結(jié)果是以秒為單位的數(shù)字。以下的函數(shù)用來確定并操作時(shí)間-日期值。函數(shù) 描述@Created 返回文檔創(chuàng)建的時(shí)間-日期。@Accessed 返回最后一次訪問文檔的時(shí)間-日期。@Modified 返回最后一次編輯并保存文檔的時(shí)間-日期。@Now 返回當(dāng)前的時(shí)間-日期。@Today 返回當(dāng)天的日期。@Tomorrow 返回明天的日期。@Yesterday 返回昨天的日期。@Weekday(time-date) 返回星期幾如 1-7(星期日到星期六)。@Day(time-date) 從時(shí)間-日期中提取月歷中的日期。@Month(time-date) 從時(shí)間-日期中提取月份值,從 1 到12。@Year(time-date) 從時(shí)間-日期中提取年值。@Hour(time-date) 從時(shí)間-日期中提取小時(shí)值。@Minute(time-date) 從時(shí)間-日期中提取分鐘值。@Second(time-date) 從時(shí)間-日期中提取秒值。@Date(y; m; d) 返回年,月,日中的日期部分。@Date(y; m; d; h; m; s) 返回年,月,日,小時(shí),分鐘,秒中的日期部分。@Date(time-date) 返回時(shí)間-日期中的日期部分。@Time(y; m; d) 返回年,月,日中的時(shí)間部分。@Time(y; m; d; h; m; s) 返回年,月,日,小時(shí),分鐘,秒中的時(shí)間部分。@Time(time-date) 返回時(shí)間-日期的時(shí)間部分。@Adjust(time-date; y; m; d; h; m; s) 通過加減某一數(shù)值以調(diào)整時(shí)間-日期。@Zone 返回當(dāng)前計(jì)算機(jī)的時(shí)區(qū)設(shè)置。@Zone 返回當(dāng)前時(shí)間-日期的時(shí)區(qū)設(shè)置。樣例:執(zhí)行時(shí)間-日期運(yùn)算1 (@Created)。如果當(dāng)前文檔是在 1995 年以前創(chuàng)建,則該樣例將“Archive”寫入 Status 域,否則寫入“Current”。SELECT @All;FIELD Status := @If(@Created < [01/01/95 12:00:00 AM]; "Archive"; "Current");2 (@Modified, @Date, @Today, @Yesterday)。根據(jù)當(dāng)前文檔最后一次修改的日期,該代理樣例將“Today”,“Yesterday”,或“Old”寫入到 ViewStatus 域中。FIELD ViewStatus := @If(@Date(@Modified) = @Today; "Today"; @Date(@Modified) = @Yesterday; "Yesterday"; "Old");SELECT @All3 (@Modified, @Date, @Weekday, @Today, @Adjust, @Yesterday)。該樣例在上例的基礎(chǔ)上做些修改,在指定“Yesterday”時(shí)要跳過星期六。如果今天是星期一,則 y 被設(shè)置為今天的日期再減去 3 天;否則設(shè)置為昨天的日期。用 y 代替 @Yesterday 用于測試 @Modified date。d := @Date(@Modified);y := @If(@Weekday(@Today) = 2; @Adjust(@Today; 0; 0; -3; 0; 0; 0); @Yesterday);FIELD ViewStatus := @If(d = @Today; "Today"; d = y; "Yesterday"; "Old");SELECT @All4 (@Now, @Month, @Year, @Day)。該計(jì)算文本域的樣例在 letterhead 表單的開頭顯示當(dāng)天的日期。例如,6/30/95 顯示為“June 30, 1995”。months := "January" : "February" : "March" : "April" : "May" : "June" : "July" : "August" : "September" : "October" : "November" : "December";month := @Subset(@Subset(months; @Month(@Now)); -1);year := @Year(@Now);day := @Day (@Now);month + " " + @Text(day) + ", " + @Text(year)5 (@Adjust, @Weekday, @Created)。這個(gè)計(jì)算時(shí)間域的樣例顯示距文檔創(chuàng)建日期兩天的日期。如果創(chuàng)建日期是星期五,則該樣例增加 4 天以跳過周末。increment := @If(@Weekday(@Created) = 6; 4; 2);@Date(@Adjust(@Created; 0; 0; increment; 0; 0; 0))訪問用戶環(huán)境用戶環(huán)境是包含公式的數(shù)據(jù)庫所在的服務(wù)器或工作站,公式包括以下情況: 復(fù)制公式、由新郵件到達(dá)時(shí)或定時(shí)觸發(fā)的代理、選擇公式或列公式。否則,用戶環(huán)境是用戶運(yùn)行公式的 Notes 工作站。用戶名可以是專有名稱也可以是非專有名稱,專有名稱可以是規(guī)范或縮寫的,使用 @Name 以改變用戶名的格式。以下是在用戶環(huán)境中返回或處理信息的函數(shù)。函數(shù) 描述@UserName 返回用戶名或服務(wù)器名.@Name([key]; name) 改變用戶名的結(jié)構(gòu)。關(guān)鍵字包含 [CN] 以從一個(gè)專有名字中解析出公共名,[Abbreviate] 縮寫規(guī)范格式的專有名字,[Canonicalize] 與上述作用相反,[ToKeyword] 將名字各部分按相反順序排序,用反斜杠分開(用于分類視圖)。@UserRoles 對于服務(wù)器上的數(shù)據(jù)庫,返回當(dāng)前用戶的角色列表。@MailDbName 返回用戶郵件數(shù)據(jù)庫的服務(wù)器名和路徑名。該函數(shù)判定兩個(gè)元素的列表。@OptimizeMailAddress(address) 從地址中刪除無用的網(wǎng)絡(luò)域。@Platform 返回用戶當(dāng)前運(yùn)行的平臺:Macintosh、NetWare、OS2V1、OS2V2、UNIX、Windows/16 或 Windows/32。@Version 返回正在運(yùn)行的 Notes 版本(字符串)。@Password(string) 對一個(gè)字符串編碼。您無法從編碼結(jié)果中確定原始字符串。樣例:訪問用戶環(huán)境1. 該視圖選擇公式限制視圖中只能有這樣一些文檔,這些文檔的 From_1 域與當(dāng)前用戶名相匹配。From_1 和 @UserName 都被縮簡至層次名稱的公共名部分,以更好地確保匹配。SELECT @Name([CN]; @UserName) = @Name([CN]; From_1)2. 該列公式中,@Name 函數(shù)從“From”域中提取公共名部分。Subject + " (" + @Name([CN]; From) + @DocDescendants(")"; ", % response)"; ", % responses)")3. 該公式顯示有關(guān)用戶環(huán)境的信息。@MailDbName 的返回值被組合,因?yàn)檫@是一個(gè)包含服務(wù)器名和路徑名的二元素列表。@Prompt([OK]; "User name"; @Name([CN]; @UserName));@Prompt([OK]; "Mail database"; @Implode(@MailDbName));@Prompt([OK]; "Platform"; @Platform);@Prompt([OK]; "Notes version"; @Version)4. 這是“By Author”視圖中第一列的公式。它轉(zhuǎn)換 From 域,該域包含了一個(gè)典型的專有名字,將其轉(zhuǎn)換為姓、逗號、名的格式。AuthorName := @If(!@IsAvailable(From);"Anonymous";@Name([CN]; From));Name := @Trim(@Word(AuthorName; "("; 1));LastName := @RightBack(Name; " ");FirstName := @LeftBack(Name; " ");CombinedName := LastName + ", " + FirstName;@If(CombinedName = ", "; Name; CombinedName)5. 這是一個(gè)對于某表單的“Password”域的輸入校驗(yàn)公式。作者可在口令被鍵入的時(shí)候看到口令,但是文檔被保存后,口令被編碼而且不可讀。@Password(Password)訪問當(dāng)前數(shù)據(jù)庫和視圖您對運(yùn)行公式的數(shù)據(jù)庫有直接的訪問權(quán)(便捷圖標(biāo)公式除外,它沒有數(shù)據(jù)庫環(huán)境)。如果您在視圖的上下文中,則您對運(yùn)行公式的視圖有直接的訪問權(quán)。在文檔的上下文中,您對文檔所在視圖有直接的訪問權(quán)。數(shù)據(jù)庫和視圖屬性下表列出返回?cái)?shù)據(jù)庫和視圖屬性的函數(shù)。函數(shù) 描述@DbManager 返回當(dāng)前對數(shù)據(jù)庫有“管理者”權(quán)限的用戶、群組和服務(wù)器。 返回一個(gè)列表。@DbName 返回當(dāng)前 Notes 服務(wù)器和數(shù)據(jù)庫的名字。返回二元素列表。@ViewTitle 返回當(dāng)前視圖的標(biāo)題。窗口標(biāo)題和列公式函數(shù)許多函數(shù)提供了有關(guān)視圖的答復(fù)層次和其他方面的信息。文檔在視圖中以 1, 2, 3 編號,這是對主文檔而言。每組答復(fù)文檔或答復(fù)的答復(fù)文檔則有第二個(gè)和第三個(gè)層次的編號(從 1 開始)。缺省的情況下,完整的答復(fù)文檔的編號以小數(shù)形式出現(xiàn)。例如,第三個(gè)主文檔的第二個(gè)答復(fù)文檔編號為 3.2,而它下面的第一個(gè)答復(fù)文檔編號為 3.2.1。這些函數(shù)僅工作于窗口標(biāo)題和列公式中,有一些會被限制。返回值都是一個(gè)字符串。函數(shù) 描述@Responses 返回在當(dāng)前視圖中當(dāng)前文檔的答復(fù)編號。只限于窗口標(biāo)題公式。@DocLevel 返回在當(dāng)前視圖中當(dāng)前文檔的級別。@DocSiblings 返回與當(dāng)前文檔同級的文檔編號,包含當(dāng)前文檔。@DocNumber 返回在當(dāng)前視圖中的當(dāng)前文檔或分類的編號。@@DocNumber(sep) 與上相同,只是用 sep 分隔編號,替換了句點(diǎn)。@DocNumber("") 與上相同,只是僅返回編號的最右邊部分。@DocParentNumber 返回在當(dāng)前視圖中當(dāng)前文檔或分類的父文檔或父分類的編號。@@DocParentNumber(sep) 與上相同,只是用 sep 分隔編號,替換了句點(diǎn)。@DocParentNumber("") 與上相同,只是僅返回編號的最右邊部分。@DocDescendants 返回后續(xù)文檔的編號,包含當(dāng)前文檔的子文檔,子文檔的子文檔。@DocDescendants(def) 與上相同,只是返回 def。在 def 中使用 % 以表示編號。@DocDescendants(zero; def) 與上相同,只是如果沒有后續(xù)文檔的話則返回 zero。@DocDescendants(one, zero; def) 與上相同,只是如果有一個(gè)后續(xù)文檔的話則返回 one 。@DocChildren 返回當(dāng)前文檔的直接子文檔的編號。@DocChildren(def) 與上相同,只是返回 def。在 def 中使用 % 以表示編號。@DocChildren(zero; def) 與上相同,只是如果沒有后續(xù)文檔的話則返回 zero。@DocChildren(one, zero; def) 與上相同,只是如果有一個(gè)后續(xù)文檔的話則返回 one 。@IsCategory 如果當(dāng)前行的當(dāng)前域右邊任何域是一個(gè)分類的話,則返回一個(gè)星號。@IsCategory(true) 與上相同,只是返回 true 代替星號。@IsCategory(true; false) 與上相同,只是如果沒有域是分類的話則返回 false 。@IsExpandable 如果當(dāng)前行是可展開的話則返回一個(gè)加號。@IsExpandable(true) 與上相同,只是返回 true 代替加號。@IsExpandable(true; false) 與上相同,只是如果當(dāng)前行是不可展開的話則返回 false 。樣例:訪問當(dāng)前數(shù)據(jù)庫和視圖1. 該樣例顯示數(shù)據(jù)庫標(biāo)題、它的服務(wù)器和數(shù)據(jù)庫名和對它具有“管理者”權(quán)限的用戶名。@Prompt([OK]; "Title"; @DbTitle);@Prompt([OK]; "Server and database"; @Trim(@Implode(@DbName)));@Prompt([OK]; "Managers"; @Implode(@DbManager; ", "))2. 如果視圖標(biāo)題公式為新文檔顯示“New Title”。如果視圖標(biāo)題為“AuthorView”則顯示 Subject 域;否則顯示 Subject 域加上答復(fù)文檔的數(shù)目。StandardTitle := Subject + @DocDescendants(" (No Responses)"; " (1 Response)"; " (% Responses)");@If(@IsNewDoc; "New Topic"; @ViewTitle = "AuthorView"; Subject; StandardTitle)3. 該列公式顯示 Subject 域、用戶名和答復(fù)文檔的數(shù)目。Subject + " (" + @Name([CN]; From) + @DocDescendants(")"; ", % response)"; ", % responses)")在公式語言中訪問當(dāng)前文檔對于表單操作、按鈕、熱點(diǎn)和域公式,當(dāng)前文檔被是打開的那個(gè)。對于視圖操作,當(dāng)前文檔是突出顯示的那個(gè)(不是復(fù)選的文檔)。對于代理,當(dāng)前文檔是根據(jù)代理構(gòu)造器選擇以及 SELECT 關(guān)鍵字標(biāo)準(zhǔn)激活的那個(gè)文檔。要閱讀當(dāng)前文檔中的域,命名該域。命名不區(qū)分大小寫,但是名字必須準(zhǔn)確。要編寫當(dāng)前文檔中的域,您必須使用 FIELD 關(guān)鍵字或者 @SetField 函數(shù)。不能簡單的命名該域。關(guān)鍵字 FIELD 用于賦值語句并有以下格式。如果省略關(guān)鍵字 FIELD,則指定的變量將被認(rèn)為是臨時(shí)變量。FIELD field-name := expression@SetField 寫入域,它與使用關(guān)鍵字 FIELD 的賦值語句效果相同。@SetField 可以嵌套到另一個(gè)語句;對于關(guān)鍵字 FIELD 則不能這樣做。域名被表達(dá)成一個(gè)文本值,所以它可以是一個(gè)括號中的準(zhǔn)確名字。有一個(gè)限制是 @SetField 只工作于已存在的域中;如果文檔中不存在您想寫入的域,則可使用 FIELD 賦值語句在公式開頭“聲明”它。@SetField 有以下格式。@SetField( field-expression-name; expression )DEFAULT 關(guān)鍵字是為了處理當(dāng)一個(gè)域不在文檔中的情況。如果文檔中存在此域,那么就用它的值,如果沒有,則用 DEFAULT 值。DEFAULT field-name := expression@MailSend 函數(shù)郵寄文檔。不帶參數(shù)的 @MailSend 郵寄當(dāng)前文檔,它必須包含一個(gè)域名為“SendTo”,該域包含收件人。帶有參數(shù)的 @MailSend 構(gòu)造文檔并按指定參數(shù)郵寄。@MailSend@MailSend( to; cc; bcc; subject; body; fields; flags )@DeleteField 函數(shù)刪除域。在 FIELD 賦值語句中指定它作為表達(dá)式。FIELD field-name := @DeleteField@DocMark([NoUpdate]) 函數(shù)防止文檔中公式的改變被保存。在公式處理完以后的文檔與以前是一樣的。該函數(shù)只影響代理。該表格列出返回文檔和域?qū)傩缘暮瘮?shù)。函數(shù)        描述
 @DocumentUniqueID        返回文檔唯一的標(biāo)識符,這是文檔的全部復(fù)本唯一的標(biāo)識符;在一個(gè)域中,創(chuàng)建一個(gè)當(dāng)前文檔的文檔鏈接。
 @InheritedDocumentUniqueID        返回文檔的父文檔唯一的標(biāo)識符,在一個(gè)域中,創(chuàng)建一個(gè)當(dāng)前文檔的文檔鏈接。
 @NoteID        返回“NT”和跟在后面的文檔的項(xiàng)目標(biāo)識符。
 @DocLength        返回文檔的字節(jié)數(shù)大小。
 @Author        返回全部作者的縮寫姓名。
 @DocFields        返回文檔中全部域的名稱。
 @IsAvailable(field)        如果某域存在于文檔中,則返回真 (1)。
 @IsUnavailable(field)        如果某域不存在于文檔中,則返回真 (1)。
 @Attachments        返回附件的個(gè)數(shù)。
 @AttachmentNames        返回全部附件的文件名。
 @AttachmentLengths        返回每個(gè)附件的字節(jié)數(shù)大小。
 @Responses        返回在當(dāng)前視圖中當(dāng)前文檔的答復(fù)數(shù)目。
 @AllChildren        選擇匹配文檔的直接答復(fù);只用于選擇公式中。
 @AllDescendants        選擇匹配文檔的所有答復(fù);只用于選擇公式中。
 @IsResponseDoc        如果文檔是一個(gè)答復(fù)則返回真 (1)。
 @IsNewDoc        如果文檔未被保存過則返回真 (1)。
 @IsDocBeingEdited        如果文檔處于編輯模式則返回真 (1)。
 @IsDocBeingLoaded        如果文檔正在被加載則返回真 (1)。
 @IsDocBeingSaved        如果文檔正在被保存則返回真 (1)。
 @IsDocBeingMailed        如果文檔正在被郵寄則返回真 (1)。
 @IsDocBeingRecalculated        如果文檔正在被重新計(jì)算則返回真 (1)。
 樣例:訪問當(dāng)前文檔1. 該計(jì)算域公式執(zhí)行涉及文檔中另外兩個(gè)域的數(shù)學(xué)計(jì)算。這些域必須存在于文檔中,必須是數(shù)字型的且被初始化為數(shù)字值。TotalSales - CostOfSales2. 該代理樣例在當(dāng)前文檔中的兩個(gè)域上執(zhí)行數(shù)學(xué)運(yùn)算,并將結(jié)果指定給第三個(gè)域。這兩個(gè)被引用的域必須存在;GrossSales 域可以是新的。FIELD GrossSales := TotalSales - CostOfSales;SELECT @All3. 該代理公式在當(dāng)前文檔中的兩個(gè)域上執(zhí)行數(shù)學(xué)運(yùn)算,并將一個(gè)數(shù)值放到第三個(gè)域中或者發(fā)送一個(gè)郵件信息。第一個(gè)語句初始化 GrossSales,如果您能肯定該域已經(jīng)存在則無須此初始化操作。FIELD GrossSales := 0;gs := TotalSales - CostOfSales;@If(gs > 0; @SetField("GrossSales"; gs); @MailSend("Ian Perron"; ""; ""; "No gross sales"; "Gross sales are zero or less for "; Subject));SELECT @All4. 該列公式樣例判定文檔是否包含 KeyThought 域。如果文檔不包含一個(gè) KeyThought 域,則它的缺省值為 Topic。DEFAULT KeyThought := Topic;KeyThought5. 這是另一種實(shí)現(xiàn)上例的方法。@If(@IsAvailable(KeyThought); KeyThought; Topic)6. 該代理樣例刪除 GrossSales 域。@If (@IsUnavailable(GrossSales); @Return(""); "");FIELD GrossSales := @DeleteField;SELECT @All7. 該代理樣例計(jì)算 GrossSales 域,然后顯示結(jié)果,而且不標(biāo)記文檔為更新。作為結(jié)果,保存的文檔未發(fā)生任何變化。如果忽略了 @DocMark 或者指定了“@DocMark([Update])”則變化被保存。FIELD GrossSales := TotalSales - CostOfSales;@Prompt([OK]; "Gross sales for " + Subject; @Text(GrossSales));@DocMark([NoUpdate]);SELECT @All8. 該樣例顯示當(dāng)前文檔中的全部域。@Prompt([OKCANCELLIST]; "Fields"; "Fields in document"; ""; @DocFields);SELECT @All9. 該窗口標(biāo)題公式為一個(gè)新文檔顯示“New Document”。對于一個(gè)現(xiàn)有的文檔,該公式顯示 Subject 域和答復(fù)的個(gè)數(shù)。@If(@IsNewDoc; "New Document"; Subject + " with " + @Text(@Responses) + " response(s)")10. 該視圖選擇公式選擇全部文檔,除了那些 Form 域包含“Profile”或“Log”的文檔。SELECT !@Contains(Form; "Profile" : "Log")11. 該視圖選擇公式選擇所有 Subject 域包含“acme”(不區(qū)分大小寫)的文檔和它們的子文檔。SELECT @Contains(@LowerCase(Subject); "acme") | @AllDescendants12. 該表單操作公式顯示所有文檔附件的名稱和長度,或者如果文檔沒有附件的話,則顯示“No attachments”。@If(@Attachments > 0; @Prompt([OKCANCELLIST]; "Attachments"; "Attachment names and lengths"; ""; @AttachmentNames + " (" + @Text(@AttachmentLengths) + " bytes)"); @Prompt([OK]; "Attachments"; "No attachments"))訪問在當(dāng)前文檔和數(shù)據(jù)庫以外的數(shù)據(jù)以下函數(shù)從指定的數(shù)據(jù)庫中取得數(shù)據(jù)值。您不能用這些函數(shù)設(shè)置數(shù)值。@DbLookup 在指定數(shù)據(jù)庫的指定視圖中的第一個(gè)排序列中查找指定的值。對于每個(gè)匹配搜索值的文檔,@DbLookup 返回文檔或視圖中的列的指定域中的值。@DbColumn 返回指定數(shù)據(jù)庫的指定視圖中的指定列中的全部值。前三個(gè)參數(shù)對于每個(gè)函數(shù)是相同的:[NOTES] : [NOCACHE] 指定操作是在 Notes 數(shù)據(jù)庫上并且未使用緩存。因?yàn)?[NOTES] 是缺省的,所以您可以為第一個(gè)列表元素指定空串 ""。如果數(shù)據(jù)是穩(wěn)定的或者您訪問過數(shù)據(jù)庫許多次了,則可以指定第二個(gè)列表元素為空串 "",不使用緩存。您可以為整個(gè)參數(shù)使用一個(gè)空串 "" 表示打開一個(gè) Notes 數(shù)據(jù)庫而且沒有緩存。server : database 指定您訪問的服務(wù)器和數(shù)據(jù)庫。為第一個(gè)列表元素指定空串 "" 以表示本地 Notes 目錄。指定整個(gè)參數(shù)為空串 "" 以表示當(dāng)前數(shù)據(jù)庫。您可以指定整個(gè)參數(shù)為數(shù)據(jù)庫的復(fù)本標(biāo)識符。Notes 將在本地和服務(wù)器上搜索,并且使用第一個(gè)它找到的復(fù)本。從“文件”“數(shù)據(jù)庫”“設(shè)計(jì)摘要”“復(fù)制”中取得復(fù)本標(biāo)識符。view 指定通過哪個(gè)視圖訪問數(shù)據(jù)庫。對于 @DbLookup,第四個(gè)參數(shù)是關(guān)鍵字,它是在視圖中第一個(gè)排序列中找到的值。@DbLookup 查找每一個(gè)與該關(guān)鍵字匹配的文檔。對于 @DbLookup,第五個(gè)參數(shù)或者是數(shù)據(jù)庫中的域名,或者是視圖中的列號。@DbLookup 返回找到文檔中的域或列值的列表。對于 @DbColumn,第四個(gè)參數(shù)是列號。@DbColumn 返回列中全部值的列表。以下函數(shù)在當(dāng)前數(shù)據(jù)庫中取得并設(shè)置另一個(gè)文檔的域值。不過,您必須知道文檔的唯一的標(biāo)識符。@GetDocField(unid; fieldName) 給定唯一標(biāo)識符,取得域值。@SetDocField(unid; fieldName; value) 給定唯一標(biāo)識符,設(shè)置域值。由于父文檔的唯一標(biāo)識符在子文檔的 $Ref 域中,所以該函數(shù)適用于在答復(fù)文檔的父文檔中訪問并設(shè)置域值。在設(shè)置了“公式繼承選定文檔中的數(shù)值”的文檔中,可以在基文檔的一個(gè)隱藏域的公式中使用 @InheritedDocumentUniqueID,然后在繼承文檔的一個(gè)隱藏域的公式中使用上述隱藏域的名稱。否則,您必須設(shè)計(jì)一種保存并提取您想訪問文檔的標(biāo)識符的方法。樣例:訪問當(dāng)前文檔和數(shù)據(jù)庫以外的數(shù)據(jù)1. 該樣例在本地通訊錄 (NAMES.NSF) 的“個(gè)人”視圖中查找一個(gè)人的姓名,并從包含此姓名的文檔中取得辦公室的電話號碼。inputName := @Prompt([OKCANCELEDIT]; "User name"; "Enter user name as FIRST LAST"; "");adjName := @Right(inputName; " ") + ", " + @Left(inputName; " ");phoneNumber := @DbLookup("Notes" : "NoCache"; "" : "NAMES"; "People"; adjName; "OfficePhoneNumber");@Prompt([OK]; "Office phone number"; inputName + "‘s office phone is " + phoneNumber)2. 該樣例除了有兩點(diǎn)不同以外,與上面的例子一樣。在這里使用的是通訊錄數(shù)據(jù)庫的復(fù)本標(biāo)識符而不是其名稱。Notes 先在本地搜索復(fù)本然后上服務(wù)器搜索,并確定使用第一個(gè)發(fā)現(xiàn)的復(fù)本。@DbLookup 的最后一個(gè)參數(shù)是列 2,而不是 OfficePhoneNumber。實(shí)際上它與列 2 是一回事,因?yàn)榱?2 中就包含電話號碼。inputName := @Prompt([OKCANCELEDIT]; "User name"; "Enter user name as FIRST LAST"; "");adjName := @Right(inputName; " ") + ", " + @Left(inputName; " ");phoneNumber := @DbLookup("Notes" : "NoCache"; "85255AD6:006AE971"; "People"; adjName; 2);@Prompt([OK]; "Office phone number"; inputName + "s office phone is " + phoneNumber)3. 該樣例在本地通訊錄的“群組”視圖中查找一個(gè)群組的成員。groupName := @Prompt([OKCANCELEDIT]; "Group name"; "Enter group name"; "");members := @DbLookup("Notes" : "NoCache"; "" : "NAMES"; "Groups"; groupName; "Members");@Prompt([OKCANCELLIST]; "Group members"; "Members of " + groupName; ""; members)4. 該樣例在給出辦公室電話號碼的情況下,取得與該號碼有關(guān)的人員的姓名。設(shè)計(jì)這個(gè)例子是為了在號碼與人員一一對應(yīng)的情況下使用的。由于數(shù)據(jù)庫沒有按電話號碼排序的視圖,所以此樣例使用 @DbColumn 來獲得所有電話號碼(列 2)和所有人員(列 1),然后查找與號碼對應(yīng)的人員。phone := @Prompt([OKCANCELEDIT]; "Phone number"; "Enter phone number"; "");phoneList := @DbColumn("Notes" : "NoCache"; "" : "NAMES"; "People"; 2);nameList := @DbColumn("Notes" : "NoCache"; "" : "NAMES"; "People"; 1);position := @Member(phone; phoneList);@If(position = 0; @Do(@Prompt([OK]; "Not listed"; "No listing for " + phone); @Return(" " )); "");name := @Subset(@Subset(nameList; position); -1);nameAdj := @Right(name; " ") + " " + @Left(name; ",");@Prompt([OK]; "Phone number " + phone; nameAdj)使用函數(shù)通過 ODBC 訪問外部數(shù)據(jù)庫以下函數(shù)通過 ODBC 訪問外部數(shù)據(jù)庫并返回一個(gè)值或值的列表:@DbColumn 返回表的一列中的全部值,或者全部不同的值。@DbLookup 返回表的一列中通過關(guān)鍵字匹配選定的值。@DbCommand 將一個(gè)命令傳遞給外部 DBMS 并返回結(jié)果。@DbColumn 與 @DbLookup 都只能提取數(shù)據(jù)。它們不能增加、刪除、修改數(shù)據(jù)或執(zhí)行其他操作。@DbCommand 能提取數(shù)據(jù)或發(fā)送其他可以改變數(shù)據(jù)的 SQL 語句。LotusScript 提供了一種更廣泛的能力,包括更新外部數(shù)據(jù)庫的能力。前四個(gè)參數(shù)對于三個(gè)函數(shù)是同樣的,通過 ODBC 建立訪問。這些參數(shù)是:"ODBC" 是字符串常量;或者 "ODBC" : "NoCache"數(shù)據(jù)源的名稱,定義在數(shù)據(jù)源表格中(在 Windows 中的 ODBC.INI)用戶標(biāo)識符,兩個(gè)用戶標(biāo)識符列表,或者一個(gè)空串,依外部數(shù)據(jù)源而定口令,兩個(gè)口令的列表,或者一個(gè)空串,依外部數(shù)據(jù)源而定(@DbColumn 和 @DbLookup)要訪問的表名稱(@DbCommand) 要執(zhí)行的命令字符串(@DbColumn 和 @DbLookup)要訪問的列名稱處理由數(shù)據(jù)源返回的空數(shù)據(jù)的選項(xiàng)(@DbLookup) 包含關(guān)鍵字的列名(@DbLookup) 適當(dāng)數(shù)據(jù)類型的關(guān)鍵字值,或者是一個(gè)列表(@DbColumn 和 @DbLookup)兩個(gè)元素的列表:“Distinct”作為關(guān)鍵字或空串;“Ascending”或“Descending”作為一個(gè)關(guān)鍵字在需要用戶標(biāo)識符和口令的地方,您可以指定空串并讓用戶在執(zhí)行函數(shù)時(shí)提供它們。樣例:使用函數(shù)通過 ODBC 訪問外部數(shù)據(jù)庫1. 該公式取得 MANUALS 表中的 PARTNO 列。@DbColumn("ODBC";"Oracle";"";"";"MANUALS";"PARTNO";"":"Ascending")2. 該公式從 MANUALS 表的行中取得 TITLE,在該行中 PARTNO 是 17-895A 。@DbLookup("ODBC";"Oracle";"";"";"MANUALS";"TITLE";"PARTNO";"17-895A")3. 該公式從 MANUALS 表中 ONHAND 列的數(shù)字值小于100 的每行取得 PARTNO 列值。@DbCommand("ODBC";"Oracle";"";"";"SELECT PARTNO FROM MANUALS WHERE ONHAND <100")
 版權(quán)所有2001
 首頁-->LOTUS文章-->強(qiáng)迫WEB用戶重新登錄的方法(兩種)
 我們知道在Web應(yīng)用中,一旦我們曾經(jīng)輸入過一次用戶口令,那么,系統(tǒng)將會一直使用當(dāng)前Web用戶與Domino HTTP服務(wù)器連接。如果我們希望以另一名Web用戶訪問此服務(wù)器,只好關(guān)閉瀏覽器,再重新連接服務(wù)器時(shí),重新輸入其他用戶的名程和口令。(這是我們不愿意作的。)如何不關(guān)閉瀏覽器,強(qiáng)迫瀏覽器顯示登陸窗口呢?關(guān)于如何強(qiáng)迫一個(gè)Web用戶輸入登錄口令的方法,在此列出兩個(gè):1。Java Servlet程序2. Domino URL 命令這兩種方法都是強(qiáng)迫瀏覽器顯示登陸窗口,以使用戶可以其他用戶名登陸。實(shí)際上不能注銷當(dāng)前已連接Web用戶,除非在登陸窗口輸入錯誤的用戶名和口令或者不同于當(dāng)前已連接的Web用戶的正確的用戶名和口令。注釋:這段程序有一段邏輯錯誤,本人已經(jīng)對其更正這段程序可以使用Domino URL命令代替,功能完全相同。在R5中試驗(yàn)可行,4.6估計(jì)可行。比如:http://host/anydatabase.nsf?login注意這里一定要寫一個(gè)數(shù)據(jù)庫的名字,可以是任何一個(gè)數(shù)據(jù)庫,甚至是不存在的數(shù)據(jù)庫。請注意格式。你可以試試,有結(jié)果您可以寫信給我。-------丁香書 1999.8.13=====================================問題5:怎么使一個(gè)Web用戶注銷登錄?來自:http://dingxiang.更新:1999.8.14解答:How do you add a logoff button for web users?Using the username:password@www. URL does not work because the browser thinks your realm is "username:password@www." instead of "www.".<P>You can use a Java servlet to pass a 401 exception to the browser to log someone off of TestRealm (in most cases, this is "www."): <P>// From Terry Courtneyimport java.io.*;import javax.servlet.*;import javax.servlet.http.*;public class LogOff extends HttpServlet {  public void init(ServletConfig config)  throws ServletException  {    super.init(config) ;  }  public void doGet (HttpServletRequest req, HttpServletResponse res)  throws ServletException, IOException  {    String auth ;    // get output streem    ServletOutputStream out = res.getOutputStream() ;    // get authorization from header    auth = req.getHeader("Authorization") ;//    if (auth == null) { //It‘s a logic Error,rem by dingxiang    if (auth != null) {      // force prompt of login      res.setContentType("text/html");      res.setHeader("WWW-Authenticate", "WWW-Authenticate: basic realm=\"/TestRealm\"") ;      res.setStatus(401, "401 Unauthorized") ;    }    out.println("Hi") ;  } // end doGet} // end class LogOffWhen you call this servlet w/ a URL of http://www./LogOff, it will send the right HTTP headers back to the browser to trick the browser into thinking that the user did not authenticate with this Realm.<P>This servlet can also be written as a LotusScript agent.
 版權(quán)所有2001
 首頁-->LOTUS文章-->自動切換用戶ID
 Sub Initialize%REM 切換用戶ID本程序的作用是:1、從指定的目錄中搜索所有ID文件,2、然后提供用戶選擇3、再從注冊用戶時(shí)保存在names.nsf數(shù)據(jù)庫中的密碼進(jìn)行校對看是否相同。4、再通過用戶選擇的ID文件更換操作員ID本程序有以下缺陷:1、取得特殊指定目錄下的ID文件2、無法判斷獲得的ID文件是用戶ID,還是Server.id,cart.id3、用戶密碼需要保存在names.nsf中,首先進(jìn)行密碼核對,造成安全泄露。但不這樣做,無法截獲用戶輸入密碼錯誤,程序不好處理。4、因此此公式僅適合單機(jī)用戶。tndahttp://notes.%END REMREM 首先搜索指定目錄下的所有ID文件Dim ss As New notessessionxx = ss.UserNameListIDPath = ss.GetEnvironmentString("Directory",True)IDFileAll = IDPath+"\*.id"‘沒有方法遍歷所有目錄,所以假定所有ID文件在此目錄下fileName = Dir(IDFileAll, 0)num = 0Do While fileName <> ""num = num + 1fileName = Dir()LoopIf num = 0 Then Exit Sub ‘沒有找到ID文件就退出程序Redim ids(1 To num) num = 1fileName = Dir(IDFileAll, 0)Do While fileName <> ""ids(num) = Left(filename,Instr(1,filename,".")-1)num = num + 1fileName = Dir()LoopDim uiw As New notesuiworkspaceIDuser = uiw.Prompt( PROMPT_OKCANCELLIST,"更換操作員","請選擇一個(gè)操作員:","",ids)If IDuser = "" Then Exit SubREM 從names.nsf中獲取密碼 Dim ndb As notesdatabaseSet ndb = ss.getdatabase("","names.nsf")Dim nvi As notesviewSet nvi = ndb.getview("People")Dim pdoc As notesdocumentSet pdoc = nvi.getdocumentbykey(IDuser)pass = pdoc.comment(0)For i = 1 To 3IDpass = uiw.Prompt( PROMPT_PASSWORD,"輸入密碼","請輸入您的密碼:")If pass = IDpass Then Exit For NextIf pass <> IDpass Then Exit SubDim idfile As Stringidfile = IDPath+"\"+IDuser+".id"Dim newreg As New NotesRegistration Call newreg.SwitchToID( idfile,pass )Messagebox "當(dāng)前操作員是:"+IDuser,64,"更換成功"Exit SubEnd Sub
 版權(quán)所有2001
 首頁-->LOTUS文章-->RTF域全接觸
 RTF域完全掌握 1、RTF域是Notes中最重要的域,由于它能夠保存文本、聲音、圖片、動畫、附件以及按鈕操作、鏈接等多媒體信息資料,是Notes不同于普通關(guān)系型數(shù)據(jù)庫的重要特征。2、RTF域的存儲容量僅受機(jī)器硬盤限制,可以任意大的文件和程序。3、當(dāng)存儲各種類型的RTF域,改變域類型成為文本類型時(shí),僅其中的文本字符能夠保存,其他的圖片、附件等不能保存在文本類型域中。4、RTF域在編程中,是不能通過公式函數(shù)來計(jì)算處理的,只能通過LotusScript來對其進(jìn)行復(fù)制操作。5、以下是用LotusScript復(fù)制、添加RTF域內(nèi)容,經(jīng)測試無誤。Sub Click(Source As Button)%REM RTF域復(fù)制操作作者:tnda 2000.3.5http://notes. mail:notes@RTF域值在程序中編輯修改后,只能調(diào)用doc.save(false,true)不能調(diào)用uidoc.save,也不能在文檔中單擊保存按鈕,否則后臺修改無效。并且其修改的內(nèi)容當(dāng)前不能顯示,只有不保存退出文檔,再打開才能顯示。因?yàn)镽TF域只能通過后臺LotusScript修改。%END REM Dim uiw As New notesuiworkspaceDim uidoc As notesuidocumentDim doc As notesdocumentSet uidoc = uiw.currentdocumentSet doc = uidoc.document ‘獲得當(dāng)前文檔Dim rtitem1 As NotesRichTextItemSet rtitem1 = doc.GetFirstItem( "aaaa" )If rtitem1 Is Nothing Then Exit SubIf rtitem1.Type <> RICHTEXT Then Exit Sub‘文檔沒有保存以前,無法發(fā)現(xiàn)RTF域Call rtitem1.AppendText( "這是第一個(gè)域值內(nèi)容" ) Dim rtitem2 As NotesRichTextItemSet rtitem2 = rtitem1.CopyItemToDocument( doc,"bbbb")Call rtitem2.AppendText( "這是第二個(gè)域新內(nèi)容" ) Call doc.Save( False, True )End Sub
 版權(quán)所有2001
 首頁-->LOTUS文章-->域公式
 域公式本節(jié)主要介紹域在何處需要使用公式,具體公式編程,下章介紹??梢允褂糜蚬降氖录校河蜻x擇公式、域隱含公式、域初始值和計(jì)算公式、域校驗(yàn)公式、域刷新公式、域事件公式等。域選擇公式:在選擇域類型為對話框列表、復(fù)選框、單選框、列表框、組合框時(shí),需要輸入域可以選擇的選項(xiàng)。選擇項(xiàng):對于固定不變的選擇項(xiàng),如:性別、學(xué)歷等,可以手動輸入。對于可能會變化,或者說無法確定的選擇項(xiàng)目,如:畢業(yè)學(xué)校、所學(xué)專業(yè)等,需要使用公式獲得。手動輸入的方法為:在選擇項(xiàng)目輸入框內(nèi),輸入男|1女|2“|”前面的“男”,為顯示內(nèi)容,即用戶可以看見的,“|”后面的“1”,為實(shí)際內(nèi)容,即當(dāng)用戶選擇了“男”時(shí),實(shí)際上此域保存的內(nèi)容是“1”。因此,此域在表單中顯示為“男”,但在視圖中顯示為實(shí)際值“1”,如果希望顯示和保存的內(nèi)容一致,則放棄使用“|”,即可,如:男女注意:“1”是文本字符,不是數(shù)字類型,利用選擇項(xiàng)輸入的域類型一律是文本類型。一行為一個(gè)選擇項(xiàng)目,如果選擇項(xiàng)內(nèi)容需要空值,直接回車,在一行中不要輸入任何內(nèi)容即可。公式選擇項(xiàng)的方法為:1、從視圖讀?。盒枰褂霉剑篅DbColumn,此公式的作用是從任何服務(wù)器上的數(shù)據(jù)庫中,讀取指定的視圖中的指定的列。@DbColumn( class : "NoCache" ; server : database ; view ; columnNumber )·        class:輸入空值,或"Notes" ·        "NoCache":不從緩沖區(qū)讀取 ·        server:指定的服務(wù)器,本地服務(wù)器,可以使用空值"" ·        database:指定的數(shù)據(jù)庫名稱,如果找不到則報(bào)錯,如果是當(dāng)前數(shù)據(jù)庫則為空值 ·        view:指定的視圖,可以為隱含視圖, ·        columnNumber:指定視圖中的第n列,可以是隱含列,從視圖的左數(shù)第N個(gè)列,包括隱含列。 ·        注意:如果視圖的第N列有重復(fù)內(nèi)容,則選擇項(xiàng)目中也會有重復(fù)內(nèi)容供選擇,需要第N列排序分類即可。 如:@DbColumn("";"";"aaaa";1),讀取當(dāng)前數(shù)據(jù)庫的aaaa視圖的第1列值。2、從其他文檔讀取:可以從其他文檔讀取一個(gè)多值域,作為選擇項(xiàng)目,如可以將公司的部門輸入指定配置屬性文檔中,供選擇。使用公式@DbLookup,此公式的作為是從指定的文檔中讀取一個(gè)域值內(nèi)容。@DbLookup( class : "NoCache" ; server : database ; view ; key ; fieldName )·        key:根據(jù)此值,從視圖中的第一列選擇指定的文檔,如果key是多值列表,如:"男":"團(tuán)員",則視圖第一列性別必須排序分類,第二列政治面貌必須排序,依此類推。 ·        filedName:指定文檔中的域名稱,函數(shù)將返回此域的值。如果輸入數(shù)字N,則表示讀取視圖中指定文檔的第N列值,建議使用域名稱。 ·        注意:如果沒有找到文檔,系統(tǒng)將定位為此視圖的第一個(gè)文檔,如果視圖中沒有文檔,則出錯。 如:@DbLookup("";"" ;"aaaa"; "abc" ; "City" ),返回從當(dāng)前數(shù)據(jù)庫中aaaa視圖,根據(jù)aaa值定位的文檔的City域值。返回內(nèi)容必須是多值域,如果是單值域,則僅有一個(gè)選項(xiàng)。使用視圖對話框的方法:選擇項(xiàng)目可以使用視圖來選擇,可以使用函數(shù):@PickList,其作用是顯示一個(gè)視圖對話框,可以從中選擇一個(gè)或幾個(gè)文檔,并返回指定的域值。@PickList( [Custom] : [Single] ; server : file ; view ; title ; prompt ; column ; categoryname )·        [Custom]用戶自定義選項(xiàng) ·        [Single]:選擇此項(xiàng)表示返回單值,否則可以返回多值 ·        title:對話框標(biāo)題 ·        prompt:對話框顯示提示 ·        column:返回第N列域值 ·        categoryname:5.0新增功能,表示視圖僅顯示此參數(shù)指定的分類文檔。 ·        此函數(shù)功能比較多,具體請參閱幫助數(shù)據(jù)庫 使用地址對話框的方法:顯示names.nsf的人員視圖供選擇使用存取權(quán)限框的方法:顯示當(dāng)前數(shù)據(jù)庫存取權(quán)限指定的人員供選擇如果選擇了域?qū)傩浴翱梢允褂貌辉诹斜碇械臄?shù)值”,則可以從選擇項(xiàng)目中選擇的同時(shí),可以輸入新建內(nèi)容。域隱含公式:域隱含公式必須返回@True或@False,來根據(jù)邏輯對或錯判斷域是否隱含。如:aaa = "",表示域aaa的值為空時(shí)隱含域初始值和計(jì)算公式:根據(jù)公式返回一個(gè)指定的值,返回的值類型必須和域類型一致,否則出錯。公式位置為:Default Value如:文檔創(chuàng)建時(shí)間域初始公式可以為,@New,表示返回當(dāng)前工作站時(shí)間域校驗(yàn)公式:判斷域值輸入是否正確,僅編輯類型可以使用。公式位置為:Input Validation如:數(shù)量域值大于0,小于100,其公式為@If(ShuLian > 0 & ShuLiang < 100 ; @Success ; @Failure("數(shù)量輸入范圍是0 ~100"))·        @Success:返回正確,表示此域內(nèi)容符合要求。 ·        @Failure:返回錯誤,表示此域內(nèi)容不符合要求,并顯示提示內(nèi)容,且輸入光標(biāo)會自動進(jìn)入此域輸入框中。。 域刷新公式:當(dāng)表單刷新時(shí),會根據(jù)此公式返回的值改變域值內(nèi)容,僅編輯類型可以使用。公式位置為:Input Translation如:如果在省份輸入的內(nèi)容是“廣東”則自動將其內(nèi)容轉(zhuǎn)化為“廣東省”@If(@Right(ShengFen;1) = "省" ; ShengFen ; ShengFen + "省" )此公式判斷ShengFan域內(nèi)容,最后一個(gè)字符是否是“省”,如果不是,則加入,否則返回原值。域事件公式:根據(jù)域觸發(fā)的事件運(yùn)行一段程序,事件有:·        Entering:進(jìn)入編輯域,即此域獲得輸入焦點(diǎn),激活此事件,一般可以設(shè)置動態(tài)初始值。 ·        Exiting:退出編輯域,即此域失去輸入焦點(diǎn),激活此事件,一般可以校驗(yàn)域,或根據(jù)域內(nèi)容改變其他域內(nèi)容。 ·        Initialize:域調(diào)入內(nèi)存時(shí),激活此事件 ·        Terminite:域從內(nèi)存中退出時(shí),激活此事件
 版權(quán)所有2001
 首頁-->LOTUS文章-->代理調(diào)試方法
 在notes編程中,尤其web開發(fā)中,代理是很常用的,但是,相對而言,代理的調(diào)試也很不方便。下面就我的經(jīng)驗(yàn),列出幾種常用的方法,歡迎大家指正和補(bǔ)充。(這里討論的都是lotussript代理)  1.notes端跟蹤法  使用notes開發(fā)客戶端時(shí),對于那些在客戶端運(yùn)行的代理(與服務(wù)器端運(yùn)行相對)可以直接跟蹤代理的運(yùn)行。  方法:選中菜單中“文件-〉工具-〉調(diào)試lotusscript”后再運(yùn)行代理即可?! ?yōu)點(diǎn):調(diào)試直觀,代理可以單步跟蹤、設(shè)置斷點(diǎn)(使用stop語句或者在調(diào)試窗口中雙擊需要加斷點(diǎn)的語句)、觀察該中斷時(shí)刻的各種變量和對象的值等。所以使用這種調(diào)試方法可以很快地知道問題的所在?! ∪秉c(diǎn):只適用于客戶端運(yùn)行的代理,而且有些web客戶端運(yùn)行的代理也無法調(diào)試。 一些調(diào)試技巧:  可以把那些在服務(wù)器端運(yùn)行的代理的核心代碼先在客戶端調(diào)試通過后,再改回服務(wù)器端運(yùn)行,這樣有時(shí)可以節(jié)省很多調(diào)試時(shí)間。有些web端運(yùn)行的代理也可照此方法調(diào)試?! ?.輸出調(diào)試信息  對于那些在服務(wù)器端運(yùn)行的代理,或在web端運(yùn)行的代理,可以利用print命令來輸出一些關(guān)鍵的信息來幫助你了解問題的所在?! 》椒ǎ涸诖碇袘岩捎袉栴}的地方或分支點(diǎn)附近加入print命令來打印一些關(guān)鍵信息,從而幫助了解問題的所在。  a.對于處于非調(diào)試狀態(tài)下的notes客戶端而言,print的信息將顯示在客戶端下部的狀態(tài)條中?! .對于處于調(diào)試狀態(tài)下的notes客戶端而言,print的信息將顯示在客戶端下部的狀態(tài)條中和調(diào)試窗口的輸出窗口中?! .對于web應(yīng)用而言,print的信息將直接輸出到瀏覽器中。(但請注意,位于表單的webqueryopen代理中的print輸出都將被忽略)  d.對于服務(wù)器端運(yùn)行的代理,print的信息將保存在NOTES.LOG文件中  附帶說一句,當(dāng)代理產(chǎn)生錯誤時(shí),一般都會在domino的命令窗口中產(chǎn)生一個(gè)錯誤信息,說明錯誤的類型,可能的話,先看看這些信息,了解一下錯誤的類型,可能會比一上來就盲目地跟蹤要好一些。當(dāng)然,在程序編碼的同時(shí),利用on error來建立一些錯誤報(bào)告機(jī)制,也有助于更快地分析錯誤的類型與所在?! ?.代理日志  建立一個(gè)代理日志,這恐怕是最通用的方法了,但也相對較繁瑣。 方法:在代碼的頭部加入如下代碼(xxxx為一隨意的日志名,mylog為日志對象的名稱,可以自定):dim mylog as new noteslog("xxxx")call mylog.openagentlog在代碼需要調(diào)試的部分加入下面的語句call mylog.logaction(description$)description$ 是一個(gè)字符串常量或變量,內(nèi)容根據(jù)調(diào)試的需要而定。這些內(nèi)容將會寫到代理的日志中?! ∪罩镜牟炜捶椒ǎ骸 .在designer中打開數(shù)據(jù)庫的代理窗口?! .在制定的代理上面點(diǎn)擊鼠標(biāo)的右鍵  c.在彈出的菜單中選擇日志即可  注意,代理一旦重新保存,代理日志就會被清空。代理每次運(yùn)行,新產(chǎn)生的代理日志會覆蓋上一次的日志。
 版權(quán)所有2001
 某食堂管理系統(tǒng),希望根據(jù)不同的用戶身份,進(jìn)入相應(yīng)的頁面。下面就是實(shí)現(xiàn)這種功能的一段代理的Initialize代碼: Sub InitializeOn Error Goto errorsDim session As New notessessionDim note As notesdocumentDim result As VariantDim i As IntegerDim viewname As StringDim querystring As StringDim doc As notesdocumentDim view As notesviewDim normaluserday As VariantDim useridday As Variantnormaluserday=Evaluate("@If(@Weekday(@Today)=1;@Adjust(@Today;0;0;-6;0;0;0);@Adjust(@Today;0;0;2-@Weekday(@Today);0;0;0))")Const notesmcro$=|@ismember("[manager]";@userroles)|‘format后的normaluserday是字符串型useridday=Format(normaluserday(0),"yyyy-mm-dd")Set db=session.currentdatabaseSet view=db.getview("vshipu")Set doc=view.getdocumentbykey(useridday)Set note=session.documentcontextresult=Evaluate(notesmcro$)If result(0)=1 Then ‘a(chǎn)dministratorPrint "[/"+getdbpath+"/myview?openform&view=vshipu]"Else ‘normal userIf (doc Is Nothing) ThenPrint "本周食譜還未制訂,請下次再來,謝謝合作."End IfPrint "[/"+getdbpath+"/vshipu/"+doc.universalid+"?opendocument]"End IfExit Suberrors:Print ErrExit SubEnd Sub
 版權(quán)所有2001
 Notes R5同外部郵件系統(tǒng)路由的設(shè)置
 
 我們知道NOTES作為內(nèi)部郵件系統(tǒng)是非常簡單易行的,很受大家歡迎,但習(xí)慣于使用
 OUTLOOK的用戶還是喜歡使用POP3郵件格式,尤其是要和外界的POP3用戶交流信息,其實(shí)
 ,NOTES不僅提供了POP3服務(wù),而且還能通過SMTP(簡單郵件傳輸協(xié)議)和其他的POP3郵
 件系統(tǒng)進(jìn)行通訊。本文主要介紹如何和其他POP3郵件系統(tǒng)交換信息。
 目標(biāo):
 1、使NOTES能夠同外部郵件系統(tǒng)通訊(包括接收和發(fā)送外來和外出郵件);
 2、為組織內(nèi)的非應(yīng)用用戶提供NOTES的郵件服務(wù),這些用戶無須安裝NOTES客戶端軟
 件,就可以使用NOTES的郵件系統(tǒng)。
 配置服務(wù)器需要:
 1、為服務(wù)器 啟用"在本地 Internet 網(wǎng)絡(luò)域外部發(fā)送消息時(shí)所用的 SMTP"
 2、為服務(wù)器 啟用 SMTP偵聽 任務(wù)
 3、正確設(shè)置 DNS 將 DNS服務(wù)器 設(shè)置為合適的郵件連接服務(wù)器。
 具體步驟:
 一、設(shè)置到本地 Internet 網(wǎng)絡(luò)域外部的 SMTP 路由
 必須啟用 SMTP 路由在本地 Internet 網(wǎng)絡(luò)域外部發(fā)送消息(如 Internet 或其他
 私有網(wǎng)絡(luò))。
 啟用到本地 Internet 網(wǎng)絡(luò)域外部的 SMTP 路由:
 1.確保已準(zhǔn)備好發(fā)送郵件到 Internet 的系統(tǒng)。
 2.確保已經(jīng)配置了服務(wù)器的"配置設(shè)置"文檔。
 3.在 Domino Administrator 中,單擊"配置"附簽,然后展開"消息處理"區(qū)段。
 4.選擇"配置"。
 5.選中"配置設(shè)置"文檔,然后單擊"編輯配置"。
 6.在"路由器/SMTP"下的"基本"附簽,完成以下域,并保存文檔:
 域 (在本地 Internet 網(wǎng)絡(luò)域外部發(fā)送消息時(shí)所用的 SMTP)
 輸入 (啟用,使用 SMTP 將郵件路由到 Internet)
 二、設(shè)置服務(wù)器接收通過 SMTP 路由發(fā)送的郵件
 要設(shè)置服務(wù)器接收 SMTP 路由的消息,必須啟用"偵聽程序"。然后,服務(wù)器則可以
 "偵聽"TCP/IP 端口(通常端口為 25)上的 SMTP 通信量,并可接收 MAIL.BOX 數(shù)據(jù)庫
 中的 SMTP 消息。
 注釋: 不要將 SMTP 作為任務(wù)添加到 Notes .INI 文件中的任務(wù)列表中,否則此功
 能將無法工作。
 啟用"偵聽程序":
 1.在 Domino Administrator 中,單擊"配置"附簽,然后展開"服務(wù)器"區(qū)段。
 2.選擇要編輯的"服務(wù)器"文檔,然后單擊"編輯服務(wù)器"。
 3.在"基本"附簽,完成以下域,然后保存文檔:
 域 (SMTP 偵聽 任務(wù))
 輸入 ("啟用",打開偵聽程序,以便服務(wù)器可以接收通過 SMTP 路由路由的消息)
 三、網(wǎng)絡(luò)域命名服務(wù) (DNS) 和郵件路由
 在網(wǎng)絡(luò)域名服務(wù)器上設(shè)置Domino郵件服務(wù)器的 A記錄和MX記錄,使得Domino郵件服
 務(wù)器能夠接收外來郵件;在網(wǎng)絡(luò)域名服務(wù)器上設(shè)置非Domino郵件服務(wù)器的 A記錄和MX記
 錄,使得Domino郵件服務(wù)器能夠發(fā)送外出郵件。
 示例:
 該示例實(shí)現(xiàn)了兩個(gè)Domino郵件服務(wù)器的郵件路由。
 1、首先要確認(rèn)兩臺服務(wù)器能夠互相PING通;
 2、要確認(rèn)兩臺服務(wù)器內(nèi)部郵件收發(fā)暢通;
 3、對Domino服務(wù)器進(jìn)行上述修改;
 4、在網(wǎng)絡(luò)域名服務(wù)器上設(shè)置上設(shè)置A記錄和MX記錄。
 Domino服務(wù)器1的A記錄為:
 apps.salmon.forward.com. IN A 147.25.8.17
 Domino服務(wù)器1的MX記錄為:
 salmon.forward.com. IN MX apps.salmon.forward.com.
 Domino服務(wù)器2的A記錄為:
 mail.ntserver.nmg.gov.cn. IN A 147.25.8.66
 Domino服務(wù)器2的MX記錄為:
 ntserver.nmg.gov.cn. IN MX mail.ntserver.nmg.gov.cn.
 注:
 1、在郵遞失敗和 Domino 發(fā)送無法郵遞消息之前,消息在服務(wù)器之間所能傳送的最
 大次數(shù)默認(rèn)是25次。
 2、服務(wù)器在重試將消息傳送到另一臺服務(wù)器之前應(yīng)等待的分鐘數(shù)。如果再次失敗,
 Domino 將增加等待時(shí)間。缺省為 15 分鐘。
 環(huán)境介紹:
 1、郵件服務(wù)器
 2、DNS服務(wù)器設(shè)置
 首頁-->LOTUS文章-->如何在Notes開發(fā)的程序中實(shí)現(xiàn)修改留痕
 如何在Notes開發(fā)的程序中實(shí)現(xiàn)修改留痕Notes 的一項(xiàng)很強(qiáng)大的功能是能夠?qū)崿F(xiàn)工作流審批,但是如何能使每個(gè)審批人在對原文進(jìn)行修改后留下他們的修改痕跡呢?本人寫了一段程序在Notes中嵌入word 97實(shí)現(xiàn)了該功能,希望對網(wǎng)友有所幫助。具體實(shí)現(xiàn)如下:首先在表單中創(chuàng)建一個(gè)RTF域body,以嵌入word 97,再做一按鈕,該按鈕實(shí)現(xiàn)對修改的留痕。其源程序?yàn)椋篋im db As New notesdatabase(servername,"jswfw")Dim handle As Variant Dim doc As NotesDocumentSet doc=source.documentDim rtitem As VariantDim object As NotesEmbeddedObject Set rtitem = doc.GetFirstItem( "Body" )Dim session As New NotesSessionDim user As Stringuser = session.commonUserNameIf ( rtitem.Type = RICHTEXT ) ThenSet object = rtitem.GetEmbeddedObject_( "Microsoft Word 文檔" )Set handle=object.activate(False)handle.showgrammaticalerrors=Falsehandle.showspellingerrors=Falsehandle.TrackRevisions = Truehandle.PrintRevisions = Truehandle.ShowRevisions = Truehandle.parent.UserName = userhandle.parent.UserInitials = userhandle.parent.UserAddress = ""handle.save End If 起草人在起草了文章后,單擊該按鈕,以后對該文章的所有修改都將保留痕跡。
 首頁-->LOTUS文章-->Notes文檔查詢的研究
 Notes文檔查詢的研究 合肥工業(yè)大學(xué)管理系 張錄娥 ---- Lotus Notes/Domino是一種基于Internet/Intranet技術(shù)為構(gòu)架的群件系統(tǒng),是構(gòu)造企業(yè)信息網(wǎng)主要工具之一。信息檢索技術(shù)作為 LotusNotes/Domino的一個(gè)主要技術(shù),為用戶提供了包括全文檢索、按關(guān)鍵字查詢、視圖和文件夾等多種方式, 本文結(jié)合在實(shí)際開發(fā)中的經(jīng)驗(yàn)體會,對Notes應(yīng)用中文檔查詢進(jìn)行討論。 文檔的查詢 ---- 在LotusNotes中,信息是以文檔男問獎4嬖謔菘庵械模桓鑫牡迪嗟庇詮叵敵褪菘庵械囊桓黽鍬肌?也就是說,在NOTES應(yīng)用中,對信息的查詢就是對文檔的查詢,對文檔的查詢主要有以下幾種方式:視圖、文件夾、全文檢索。下面我們來一一探討他們的特點(diǎn)。 ---- 1. 視圖 ---- 視圖是 LotusNotes中文檔的主要瀏覽窗口,每一視圖都包含符合一定條件的文檔。當(dāng)一個(gè)視圖的選擇條件給定以后,通過該視圖所看到的文檔就是符合條件的文檔,如某一視圖的選擇條件為:Select form="請假單"; 則打開該視圖后,我們所看到的文檔都是請假單。視圖除了有選擇條件外,還可以按不同的特性將文檔進(jìn)行分類和排序,使得我們可以及其快捷地導(dǎo)航到要查找的文檔。對于簡單的查詢,可以不編寫任何程序,而通過把視圖按合理的方式進(jìn)行分類和排序就可以了。 Notes視圖設(shè)計(jì)是應(yīng)用程序設(shè)計(jì)過程中較快的一步,如果數(shù)據(jù)庫第一次就設(shè)計(jì)正確,擁有在正確文檔中可用的全部必需的字段,那么設(shè)計(jì)視圖應(yīng)是一個(gè)容易的過程,且對用戶來說是直觀的,可打印輸出屏幕上顯示的視圖。 ---- 2. 文件夾 文件夾也是文檔的瀏覽窗口之一,但是和視圖不同的是,文件夾沒有選擇條件,它里面的文檔是通過Putinfolder來放進(jìn)的,必須通過RemoveFromFolder來將其中的文檔移開。 ---- 3. 全文檢索 ---- 全文檢索是 LotusNotes提供的基于數(shù)據(jù)庫全文索引的搜索工具,它能根據(jù)給定的檢索關(guān)鍵字在整個(gè)數(shù)據(jù)庫中搜索,并把搜索結(jié)果顯示在該視圖的頂端。 ---- 4. 按關(guān)鍵字查詢 ---- 好的查詢設(shè)計(jì)應(yīng)是對用戶的查詢給于準(zhǔn)確快速的響應(yīng),準(zhǔn)確,靈活地顯示用戶所需的數(shù)據(jù)。為滿足用戶多條件的組合查詢,開發(fā)人員一般為用戶設(shè)計(jì)一種"按關(guān)鍵字查詢"方式,需要編寫程序使用戶可以輸入一個(gè)或多個(gè)查詢條件進(jìn)行組合條件查詢,找滿足條件的文檔。但是由于NOTES無法直接顯示結(jié)果,一般的解決方法是:將查詢結(jié)果存放到文件夾中,最后,打開文件夾顯示查詢結(jié)果。 文件夾方式存在的缺陷及解決方法 ---- 由于LotusNotes的文檔是可以共享的,文件夾也可以共享,也就是說,你可以用這個(gè)文件夾來存放你的檢索結(jié)果,我也可以用這個(gè)文件夾來存放我的查詢結(jié)果,而且LotusNotes應(yīng)該保證互相不沖突。然而遺憾的是,LotusNotes不作這個(gè)保證,導(dǎo)致的結(jié)果是大家互相影響,產(chǎn)生訪問沖突。為了解決這一問題我們提出兩種方法: ---- 1、建立私有文件夾 ---- 所謂私有文件夾,是指文件夾屬于一人私有,其他人看不見這個(gè)文件夾??梢酝ㄟ^創(chuàng)建一個(gè)"啟動后私有"文件夾,每個(gè)用戶使用該文件夾后,系統(tǒng)立即根據(jù)這個(gè)啟動后私有文件夾創(chuàng)建一個(gè)新的屬于該用戶的文件夾。這樣,每個(gè)用戶都有一個(gè)結(jié)構(gòu)完全相同而且互相不干擾的文件夾。這種解決方法保證沖突不會產(chǎn)生,但系統(tǒng)為每個(gè)用戶保存一個(gè)文件夾,會導(dǎo)致系統(tǒng)維護(hù)上的困難。如果系統(tǒng)的用戶太多,情況會更壞。如果用戶注銷,它的私有文件夾不會自動刪除。 ---- 2、改進(jìn)的視圖方法 ---- 視圖一般是大家共享的,我們可以通過改進(jìn)視圖的選擇條件,將視圖作為我們存儲查詢結(jié)果的地方,就能避免文件夾方式產(chǎn)生的問題。我們提出解決問題的思路是:把滿足某一用戶查詢條件的文檔作選擇標(biāo)記,創(chuàng)建一個(gè)共享視圖,用視圖選擇公式來顯示該用戶的查詢結(jié)果,顯示或打印完成后,刪除選擇標(biāo)記。具體實(shí)現(xiàn)方法如下: ---- (1) 在要查詢的數(shù)據(jù)庫文檔表單上創(chuàng)建一個(gè)可編輯多值的隱含?quot;SelectedUserName"用于存放查詢該文檔的用戶名。 ---- (2) 創(chuàng)建一個(gè)共享視圖vwSelect,視圖公式為: ---- SELECT Form = "frmFormName" & ---- @Contains(SelectedUserName;@UserName) ---- 用于顯示該用戶查到的文檔 ---- (3) 創(chuàng)建一個(gè)顯示視圖的導(dǎo)航器"nvgQueryResult",其初始視圖為vwSelect。 ---- (4) 用Sript語言,利用FTSearch函數(shù)進(jìn)行組合條件查詢,查找滿足條件的文檔。 編程實(shí)現(xiàn) ---- (1) 查詢顯示 ---- 功能:完成按關(guān)鍵字條件查詢,顯示查詢結(jié)果. Dim session As New NotesSessionDim db As NotesDatabaseDim doc As NotesDocumentDim view As NotesViewSet db = session.CurrentDatabaseitemvalues=item1.valuesCondition=itemvalues(0)For i=Lbound(itemvalues)+1 to Ubound(itemvalues)Condition=Condition+itemvalues(i)‘記載用戶輸入的全部查詢條件NextCount=view.FTSearch(Condition,0) ‘完成全文查找If count〈〉0 ThenMessagebox"本數(shù)據(jù)庫中共有:"+Str(Count) + "個(gè)記錄滿足條件!",0+64,"提示信息" For j=1 To countSet doc=dc.getnthdocument(j)Set item = doc.GetFirstItem( "SelectedUserName" ) Call item.AppendToTextList( session.UserName ) ‘在域SelectedUserName中Call doc.Save( True, True )‘追加用戶名NextServerName = session.GetEnvironmentString("ServerName")DirName = session.GetEnvironmentString("DirectionName")DatabaseName=DirName+"DBName.nsf" ‘打開導(dǎo)航器調(diào)用視圖,即顯示查詢結(jié)果Call workspace.OpenDatabase ( ServerName,DatabaseName,"nvgQueryResult" )ElseMessagebox "沒有滿足條件的記錄!",0 +48,"提示信息:"End Ifend(2) 退出顯示 功能:清除用戶的選擇標(biāo)記 Dim session As New NotesSessionDim db As NotesDatabaseDim doc As NotesDocumentDim view As NotesViewSet db = session.CurrentDatabase ‘ ViewName = session.GetEnvironmentString("envViewNa")Set view = db.GetView(vwSelect)Set doc = view.GetFirstDocumentUserName=session.UserName‘取現(xiàn)用戶名到變量:UserNameWhile Not (doc Is Nothing ) TempValue=doc.SelectedUserName ‘清除文檔域"SelectedUserName"中doc.SelectedUserName=""‘自己的用戶名;Call doc.save(True,False) ‘同時(shí)保留其他用戶的用戶名.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主要技術(shù)要點(diǎn): ---- 以上應(yīng)用設(shè)計(jì)主要運(yùn)用了以下技術(shù)要點(diǎn)來保證顯示結(jié)果的準(zhǔn)確性和數(shù)據(jù)的共享性. ---- (1) 要查詢的數(shù)據(jù)庫文檔表單上創(chuàng)建的可編輯多值的隱含域"SelectedUserName" . 域是構(gòu)成表單的重要元素,對一個(gè)NOTES數(shù)據(jù)庫來說,外部數(shù)據(jù)的錄入要通過域, 庫內(nèi)存放數(shù)據(jù)顯示也要依靠域。我們這里創(chuàng)建域"SelectedUserName"的作用是:存放查詢該文檔的用戶名作為選擇標(biāo)志。 選擇標(biāo)志的確定: ---- 使用用戶名作為選擇標(biāo)志主要因?yàn)樵贜otes中用戶名是唯一的,不同的用戶有不同的用戶名,不會存在兩個(gè)相同的用戶名。這樣,該域記住了有哪幾個(gè)不同用戶查詢選擇了此文檔。為用視圖顯示文檔做準(zhǔn)備. 域的主要屬性是: ---- 可編輯:數(shù)據(jù)可以通過按鈕執(zhí)行Formulas或Script來產(chǎn)生。 ---- 隱含的:只作存儲,沒有顯示作用。顯示文檔時(shí)不顯示該域的數(shù)據(jù)準(zhǔn)許多值,準(zhǔn)許用戶存入多個(gè)值,保證該域記錄下選擇該文檔所有的用戶名。因?yàn)樵诠蚕頂?shù)據(jù)狀態(tài)下,同一個(gè)文檔同時(shí)可被多個(gè)用戶查詢選擇,你必須記住所有選擇該文檔的用戶名。這一點(diǎn)對于多用戶下顯示數(shù)據(jù)十分重要。 ---- (2) 視圖及視圖選擇公式: ---- 我們設(shè)計(jì)了一個(gè)共享視圖vwSelect,視圖公式為: ---- SELECT @Contains(SelectedUserName;@UserName) ---- 視圖功能:顯示所有域SelectedUserName中含有當(dāng)前的用戶名的文檔。 ---- @UserName:返回當(dāng)前的用戶名。 ---- @Contains(SelectedUserName;@UserName): ---- 用于判斷是否文檔域SelectedUserName中含有當(dāng)前的用戶名; 因?yàn)樵诓樵儠r(shí),那些滿足條件文檔的域"SelectedUserName"中已被加入了用戶名作為選擇標(biāo)志,所以該視圖選擇顯示那些域SELECTEDUSERNAME中包含用戶名的文檔。 ---- 在視圖的設(shè)計(jì)時(shí),使用"打開后廢棄索引"選項(xiàng)。 小結(jié) ---- 綜上所述,LousNotes為查詢應(yīng)用程序開發(fā)提供了靈活快速的環(huán)境,本文所述的幾種方式都能實(shí)現(xiàn)對數(shù)據(jù)文檔的查詢檢索,但是,它們的實(shí)現(xiàn)方法和滿足的目的要求不盡相同。盡管還有不足之處需要完善, 但是仍然說明了一些能結(jié)合到你的應(yīng)用程序中去的Notes技術(shù),同時(shí),我們必須清醒地認(rèn)識到它與傳統(tǒng)關(guān)系型數(shù)據(jù)庫應(yīng)用程序開發(fā)系統(tǒng)有很大的差別,查詢設(shè)計(jì)有其獨(dú)特的方式,一個(gè)應(yīng)用程序能很快地被設(shè)計(jì)出來并且達(dá)到可用狀態(tài)。試圖將傳統(tǒng)的應(yīng)用程序開發(fā)技術(shù)映射到Notes環(huán)境中的開發(fā)人員,將很難獲得Notes應(yīng)用程序的優(yōu)點(diǎn)。
 版權(quán)所有2001
 LotusNotes4.5是一個(gè)很好的群件工作平臺,它有很好的電子郵件系統(tǒng),領(lǐng)先的全文檢索和復(fù)制功能。它還具有極強(qiáng)的安全措施,可以可靠地保證信息安全性。但它在解決事務(wù)處理問題上功能較弱,這時(shí)就需要傳統(tǒng)的關(guān)系型數(shù)據(jù)庫管理系統(tǒng)來協(xié)助解決。如何把現(xiàn)有的關(guān)系型數(shù)據(jù)庫信息轉(zhuǎn)移到Notes數(shù)據(jù)庫中,以利用Notes的許多良好性能共享數(shù)據(jù),就是本文要討論的問題。本文以Foxpro數(shù)據(jù)庫為例,介紹LotusNotes訪問異種數(shù)據(jù)庫的一種實(shí)現(xiàn)方法。LotusNotes訪問異種數(shù)據(jù)庫的途徑LotusNotes使用ODBC標(biāo)準(zhǔn)存取異種數(shù)據(jù)庫信息。通過Notes里內(nèi)嵌的公式或Script語言,可在Notes文檔中引入非Notes數(shù)據(jù)庫信息,把現(xiàn)成的數(shù)據(jù)轉(zhuǎn)換成Notes數(shù)據(jù)庫。Notes提供以下方法來存取外部數(shù)據(jù):1.在Notes公式里利用@Db函數(shù)Notes提供@DbColumn、@DbLookup及@DbCommand三個(gè)函數(shù),這三個(gè)函數(shù)的第一個(gè)參數(shù)用“ODBC",就可訪問異種數(shù)據(jù)庫信息。但它有一個(gè)缺陷:只能按列存取信息,而不能按記錄存取信息。2.。利用LotusScript數(shù)據(jù)對象LSX兼容模塊使用LotusScript語言來編寫存取外部數(shù)據(jù)的函數(shù),Notes的ODBCConnection、ODBCQuery及ODBCResultSet三個(gè)類為Notes提供了用ODBC標(biāo)準(zhǔn)存取異種數(shù)據(jù)庫的屬性和操作。實(shí)例:1.定義數(shù)據(jù)源在存取外部數(shù)據(jù)之前,必須定義一個(gè)數(shù)據(jù)源,以便讓ODBC驅(qū)動程序管理器知道怎樣獲取數(shù)據(jù)。一個(gè)數(shù)據(jù)源把一個(gè)特定的ODBC驅(qū)動程序和要存取的數(shù)據(jù)聯(lián)系在一起,并包括要存取的數(shù)據(jù),它與服務(wù)器或目錄、后臺DBMS以及網(wǎng)絡(luò)平臺相聯(lián)系,這些信息都記錄在一個(gè)注冊文件中(在Winows95中是ODBC.INI),可采用Windows的管理工具注冊數(shù)據(jù)源。在Windows95中操作步驟如下:打開Windows控制面板,按ODBC圖標(biāo),擊Add按鈕;選擇需要的驅(qū)動程序,擊OK按鈕;輸入數(shù)據(jù)源名稱、描述信息以及所需要的其它信息;有些驅(qū)動程序還需要其他一些信息,輸入這些必需的信息,并擊OK按鈕;擊Close按鈕關(guān)閉ODBC配置。2.LotusNotes訪問Foxpro的一種實(shí)現(xiàn)方法實(shí)現(xiàn)Notes訪問Foxpro數(shù)據(jù)庫的基本編程思想是:對Foxpro的一個(gè)數(shù)據(jù)庫,按其結(jié)構(gòu)相應(yīng)地在Notes數(shù)據(jù)庫里建立一個(gè)同樣結(jié)構(gòu)的表單,以便把Foxpro字段的信息經(jīng)轉(zhuǎn)換后存入Notes表單相應(yīng)字段中;建立一個(gè)代理,用Script語言編寫轉(zhuǎn)換程序;再創(chuàng)建一個(gè)視圖運(yùn)行這個(gè)代理,以實(shí)現(xiàn)異種數(shù)據(jù)庫信息向Notes數(shù)據(jù)庫轉(zhuǎn)換?,F(xiàn)有一個(gè)Foxpro數(shù)據(jù)庫BMZBK.DBF,其結(jié)構(gòu)如下:字段名類型寬度說明codeCharacter7指標(biāo)編碼nameCharacter40指標(biāo)名稱fullnameCharacter60指標(biāo)全稱unitCharacter12計(jì)量單位3.把這個(gè)庫的所有信息轉(zhuǎn)換到Notes庫中的實(shí)現(xiàn)步驟如下:1.在Notes中新建一個(gè)數(shù)據(jù)庫,取名為Convert.nsf,在這個(gè)數(shù)據(jù)庫里創(chuàng)建一個(gè)表單,取名為codelib,其內(nèi)容如下:域名類型說明code文本可編輯指標(biāo)編碼name文本可編輯指標(biāo)名稱fullname文本可編輯指標(biāo)全稱unit文本可編輯計(jì)量單位0在Convert.nsf庫中建立一個(gè)代理,取名為vfpagent,定義如下:運(yùn)行此代理的時(shí)間設(shè)定為:人工選擇“操作”菜單執(zhí)行;指定代理操作的文檔設(shè)定為:視圖中所有文檔。2.此代理要執(zhí)行的操作,用Script編寫兩個(gè)事件:(1)Option事件作如下編程:OptionPublicUselsx"*LSXODBC"‘存取ODBC類庫的全局對象(2)Initialize事件作如下編程:SubInitializeDimsessionAsNewNotessessionDimdbAsNotesdatabaseDimdocAsnotesdocumentSetdb=session.currentdatabaseSetdoc=Newnotesdocument(db)doc.form="codelib"DimconnAsNewODBCConnectionDimqryAsODBCQueryDimresultAsODBCResultSetCallconn.Disconnect()Setqry=NewODBCQuerySetresult=NewODBCResultSet‘VFR是ODBC里注冊好的數(shù)據(jù)源Ifconn.ConnectTo("VFP")ThenSetqry.Connection=connqry.SQL="SELECT*fromBMZBK"‘發(fā)送查詢請求Setresult.Query=qryCallresult.Execute()columns=result.Columns‘取出結(jié)果集,并存入Notes相應(yīng)的字段中DoUntilresult.IsEndOfDatadoc.code=Trim$(result.getvalue(1))doc.name=Trim$(result.getvalue(2))doc.fullname=Trim$(result.getvalue(3))doc.unit=Trim$(result.getvalue(4))Calldoc.save(True,True)Setdb=session.currentdatabaseSetdoc=Newnotesdocument(db)doc.form="codelib"Callresult.nextrow()LoopCallconn.Disconnect()‘與數(shù)據(jù)源斷開連接ElseMessagebox("Couldnotconnecttoserver")EndIfEndSub3.在Convert.nsf庫中建立一個(gè)視圖,取名為DemoView,在此視圖里創(chuàng)建一個(gè)操作,標(biāo)題為“轉(zhuǎn)換”,運(yùn)行方式為簡單操作:運(yùn)行“vfpagent"代理。這樣在打開Convert.nsf數(shù)據(jù)庫時(shí),點(diǎn)擊DemoView視圖,就會在屏幕上方出現(xiàn)“轉(zhuǎn)換”操作按鈕,點(diǎn)擊這個(gè)按鈕,就可把Foxpro一個(gè)數(shù)據(jù)庫BMZBK.DBF的所有信息轉(zhuǎn)換成Notes數(shù)據(jù)庫了。
 版權(quán)所有2001
 |  |  |  |