当ブログに掲載しているサンプルは、すべて利用者の自己責任という形でお願いします。
ただし、明らかな不具合がある場合、ご連絡いただければ、訂正記事を出します。
また、こちらのサンプルは、別のサイト等への公開、転載は一切禁止しています。
どうしてもと言う場合は、筆者にあらかじめご連絡ください。
記事そのもののリンクについてはご自由に行っていただいてよいです。

テクてく Lotus 技術者 Slack に参加しよう!

2008年12月26日金曜日

そろそろ今年最後について一言いっとくか

ということで、これが今年最後の投稿です。

ほとんどがLotusScriptのサンプルについてでしたね。

重大な不具合情報も、まだ決着が付いていません。来年には是非、この記事を完結させたいです。
もうしばらくお待ちください。
ちなみに、不具合自体は解消されました。IBM様、ありがとうです。


今年一年(っていうか9ヶ月半)、ご愛読(?)いただき、ありがとうございました。
アクセス5,000件突破!でも宣言したように、来年も継続して書いていきますので、よろしくお願いします。

また、筆者同様、株式会社エフもよろしくお願いします。
ノーツの小さな開発から大きな開発や、運用保守のお手伝い等、承っております。

それでは、皆様、よい年をお迎えください。

サーバー名の取得

溜めておいたネタがなくなってきました。
なので、今更な感がありますが、データベースがあるサーバの名前を取得するというサンプルにします。
(もう少し、考えて書いてくれば良かったなぁ・・・)

自DBはNotesSessionクラスのCurrentDatabaseプロパティで取得できます。
そのNotesDatabaseクラスのServerプロパティを取得するだけです。
ここで注意してほしいのは、ローカルPCにあるDBの場合、このServerプロパティは""(空の文字列)を返すということです。

ちなみに、@関数でもDBのサーバ名を取得できます。
@DBNameという関数がそうなのですが、この戻り値が「サーバ名:DBファイル名」というリストを返します。
なので、リストの一番目を取得すればよいのです。

LotusScriptのサンプルはこちら。

Sub Click(Source As Button)
    Dim session As New NotesSession
    Dim db As NotesDatabase
    
    'データベースが存在するサーバー名を表示する
    Set db = session.CurrentDatabase
    If db.Server = "" Then
        'db.Serverが空白の場合、ローカルディスクにあることになる。
        Messagebox "このデータベースはローカルにあります。", 0, "結果"
    Else
        Messagebox "このデータベースは、" & db.Server & "にあります。", 0, "結果"
    End If
End Sub



@関数のサンプルはこちら。

SRV := @Subset(@DbName;1);
@If(SRV="";@Prompt([OK];"結果";"このデータベースはローカルにあります。");@Prompt([OK];"結果";"このデータベースは" + SRV + "にあります。"))









Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年12月25日木曜日

文書内のアイテムを全部取得する

昨日はクリスマスイヴということで、投稿を休んでしまいましたね。え?関係ないだろって?
あはは。その通りですね。単純に忙しかっただけです。

さて、今回はちょっと応用です。
文書の中に格納されているアイテムの値を全部見たいと言うことがありますよね?筆者はたまにあります。
文書のプロパティ画面をせこせこと見ていけば良いのですが、アイテム数が多いと、一苦労です。
そのようなときに、今回のサンプルを使いましょう。

ビューで選択した文書(複数選択した場合は最初の文書)のアイテム名とその内容をプロンプト表示するものです。
サンプルと言うことで簡易的なものにしてありますが、今までのサンプルと組み合わせてもらえば、
ファイルに書き出したり、複数の文書に対応したりすることも可能でしょう。

アイテムが複数値の場合でも、すべてを表示するように対応してあります。
リッチテキストの場合は、テキストだけが抽出されます。

Sub Initialize
    Dim session As New NotesSession
    Dim db As NotesDatabase
    Dim docs As NotesDocumentCollection
    Dim doc As NotesDocument
    Dim sbj As String 'アイテム名称
    Dim itemVal As String 'アイテム値
    Dim i As Integer 'カウンタ
    
    i = 0
    Set db = session.CurrentDatabase
    Set docs = db.UnprocessedDocuments
    Set doc = docs.GetFirstDocument
    
    '文書のアイテム一覧を取得する
    Forall x In doc.Items
        i = i + 1
        itemVal = ""
        Forall y In doc.GetItemValue( x.Name )
            If itemVal = "" Then
                itemVal = y
            Else
                itemVal = itemVal & ":" & y
            End If
        End Forall
        sbj = sbj & Cstr( i ) & "." & x.Name & " : " & Chr$(9) & itemVal & Chr$(10)
    End Forall
    
    Msgbox sbj, 0, "文書のアイテム一覧"
End Sub



Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年12月22日月曜日

ビュー名の一覧を表示する

復帰第一弾です。
まだ、多少ぼけてるところがあるので、簡単なものにします。

DBのビューの一覧を取得するものです。
と言いつつ、フォルダも取得されるので、そこは注意してください。
フォルダは取得したくない場合は、NotesViewクラスのIsFolderプロパティが
Falseのものだけを取得すると良いでしょう。

サンプルはフォルダも含めて取得して、一覧をプロンプト表示するようにしています。

Sub Click(Source As Button)
    Dim session As New NotesSession
    Dim db As NotesDatabase
    Dim view As NotesView
    Dim i As Integer
    Dim sbj As Variant
    
    Set db = session.CurrentDatabase
    
    i = 1
    'db.Viewsは、データベースのビューを全部取得する(戻りは配列でくる)
    'どれだけの配列か分からないので、Forall関数で、繰り返し処理を行う(配列の回数分行う)
    Forall x In db.Views
        Set view = x
        'view.Nameで、そのビューの名前を取得する
        sbj = sbj & Cstr( i ) & ". " & view.Name & Chr$(13)
        i = i + 1
    End Forall
    
    Messagebox sbj, 0, "ビュー一覧"
End Sub




Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年12月15日月曜日

一週間投稿休止します

私事なのですが、ちょっと休暇をいただきます。
なので、このブログ、今週はお休みです。楽しみにしている方(いるのかな?)、ごめんなさい。

次回の投稿は、12/22を予定しています。
休んだら,普通は「パワーアップして帰ってきます!」とかいうのがありますが、このブログにはそんなものはありません。

次回の投稿も、淡々と行うと思いますので、よろしくお願いします。
「ポイしないでください」なぁんてね。(古い?)

2008年12月12日金曜日

ユーザ情報の取得

今回はユーザ情報の取得に挑戦してみる。

ユーザのメールDBファイル名やサーバ名を取得するとき、
よく使うのはサーバのnames.nsfにアクセスして、ユーザ文書を取得して、そこの値を読み取るとか、
個人アドレス帳のロケーション文書を取得するなどではないかと思う。

しかし、ロケーション文書は間違って設定されることがあったりするし、names.nsfもビューを開かないといけない(筆者は($VIMPeople)ビューを使っていた)とか、面倒である。

今日、紹介するのはNotesRegistrationクラスを使うもので、調査したいサーバ名とユーザ名を与えれば、そのユーザがドミノディレクトリにどのように登録されているのかを返してくれるものだ。

サンプルは、アドレス帳で選択したユーザのメールファイル情報を取得して、ダイアログ表示するものである。


Sub Click(Source As Button)
    Dim session As New NotesSession
    Dim curdb As NotesDatabase
    Dim uiws As New NotesUIWorkspace
    Dim ret As Variant '選択したユーザ名
    Dim regist As New NotesRegistration 'ドミノ登録情報
    Dim mailserver As String 'メールサーバ
    Dim mailfile As String 'メールファイル名
    Dim maildomain As String 'メールドメイン
    Dim mailsystem As Integer 'メールシステム
    Dim mailprofile As String 'セットアッププロフィール(今回は利用しない)
    Dim mailtype As String 'メールシステムの表示用
    
    Set curdb = session.CurrentDatabase
    
    '取得したいユーザ名を選択する
    ret = uiws.PickListStrings( 0, False )
    If Isempty(ret) Then
        Msgbox "処理を中断します。", 0 + 16, "ユーザ情報の取得"
        Exit Sub
    End If
    
    'ユーザ情報を取得するサーバをセットする
    regist.RegistrationServer = curdb.Server
    'ユーザ情報の取得(2番目以降の引数に戻り値がセットされる)
    Call regist.GetUserInfo( ret(0), mailserver, mailfile, maildomain, mailsystem, mailprofile )
    
    'メールシステムは、数値で戻ってくるので、実際の表示値に変換
    Select Case mailsystem
    Case 0:
        mailtype = "Notes"
    Case 1:
        mailtype = "cc:Mail"
    Case 2:
        mailtype = "その他"
    Case 3:
        mailtype = "X.400"
    Case 4:
        mailtype = "その他のインターネットメール"
    Case 5:
        mailtype = "POP or IMAP"
    Case 99:
        mailtype = "なし"
    End Select
    
    Msgbox _
    "メールサーバ :" & mailserver & Chr$(10) &_
    "メールファイル:" & mailfile & Chr$(10) &_
    "メールドメイン:" & maildomain & Chr$(10) &_
    "メールシステム:" & mailtype, 0, "ユーザ情報の取得"
End Sub


Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年12月11日木曜日

固定回数の繰り返し処理

繰り返し処理の第?弾です。なんで、こんなに種類があるんでしょうね?どれを使って良いのか分からなくなってしまいます。

今回は、ループ回数があらかじめ分かっている場合の方法です。
For ~ Nextステートメントを使います。
このステートメントは、指定した回数だけループするのが特徴ですが、ループの途中で抜けることもできます。
Exit Forという命令です。
このExit ~というのは、繰り返し処理を抜けるのによく使いますが、唯一Whileステートメントだけには適用できません。

なので筆者はWhileステートメントは使わないです。同様の繰り返し処理ができるDo Whileステートメントを利用します。


恒例のサンプルは、ループする回数を最初に入力して、その分ループをします。
ループ中にダイアログを表示していますが、そこで、[キャンセル]ボタンをクリックすると、ループを強制的に抜けるようにしてあります。


Sub Click(Source As Button)
    Dim cnt As Variant 'ループ回数
    Dim i As Integer 'カウンタ
    Dim ret As Integer 'ダイアログの戻り値
    Dim msg As String 'メッセージ
    
    cnt = Inputbox( "ループする回数を入力してください。", "繰り返し回数入力" )
    If cnt = "" Or ( Not Isnumeric(cnt) ) Then
        Msgbox "ループ処理は行われません。", 0, "繰り返し処理"
    End If
    
    For i = 1 To cnt
        msg = "現在、" & i & "回目のループです。" & Chr$(10) &_
        "[キャンセル]をクリックすると、ループを抜けることができます。"
        
        'OKとキャンセルのボタンが付いたダイアログを表示する
        ret = Msgbox( msg, 0 + 1, "繰り返し処理" )
        'retが2の場合、キャンセルボタンがクリックされたことを意味する
        If ret = 2 Then
            'ループを強制的に抜ける
            Exit For
        End If
    Next
End Sub


Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年12月8日月曜日

不定回数の繰り返し処理その3

繰り返し処理の第三弾。
今回はForallステートメントです。

このステートメントは配列、リスト、コレクション(NotesDocumentCollection等)の要素分、繰り返して実行します。
配列の要素が5であれば、5回のループをするということです。
複数の値が格納されているフィールドの内容に対して、何か処理をするときとかに利用することが多いでしょう。
このブログでも、そのようなサンプルを多々書いています。

サンプルは、リスト変数を作成して、その要素の回数ループするようにしたものです。
リストの要素数は最初に、数値を入力して決めていますので、実行する度にループする回数を変えることができます。


Sub Click(Source As Button)
    Dim res As Variant '繰り返し回数の決定
    Dim i As Integer 'カウンタ
    '配列の定義(変数の後ろに()をつけると、その変数は配列と見なされる)
    Dim lst() As String
    
    '0~5の数値を入力させる(0~5以外の値が入力されたら再入力)
    'キャンセルボタンも無効
    Do
        res = Inputbox("1~5までの数字を入力してください。" & Chr$(10) & "0で終了", "繰り返し回数の決定", "1")
    Loop While res <> 5
    If res = 0 Then
        Msgbox "処理を中断します。", 0, "繰り返し処理"
        Exit Sub
    End If
    
    '【Redimは変数の再定義】
    '配列を定義する場合、配列の数が明示されていないと一回で定義できない。
    '今回は最初に入力させているので、一度の定義では確定できないため、このように再定義という形を取る。
    Redim lst( 1 To res ) As String
    
    '配列に文字列を代入している。(変数なので、繰り返し処理を使って代入すると早いだけ)
    For i = 1 To res
        lst(i) = Cstr(i) & "つめの配列"
    Next
    
    'lstという配列の数の分繰り返しを行うという意味。
    'その際、配列の内容をxという変数に吐き出している。
    Forall x In lst
        'xの内容を表示している。
        Msgbox x, 0, "配列の内容"
    End Forall
End Sub


Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年12月5日金曜日

ビューの列の内容が設定と違って表示される


左図のように、まれにビューの列の計算式の結果と実際に表示されている値の結果がマッチしないことがある。


ビューの索引情報が破損した場合とそうでない場合がある。
ビューの索引情報が破損した場合、ビューを開いて、Ctrl+F9を押せば、再構築をしてくれるのでそれで直る(直らない場合は、Shift+Ctrl+F9)。

ではそうでない場合はどういうときか?
ノーツの不具合ではなく、プログラムの方に問題がある。
実際にはビューの列のプロパティに不正な部分があるのである。


下図を見て欲しい。
これは、列のプロパティの一番右側のタブを開いた状態である。
ここに「名前」という欄があり、値が設定してある。この値はノーツDBのプログラム中で利用することが出来るビューの列の識別子なのである。
ここの値はビュー内で重複してはならず、重複した場合には、一番左側にある列の計算式の結果が表示されるのである。
今回の場合は、ここの「$2」というのがすでに他で使われていた値であったと言うことである。




















Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年12月4日木曜日

時間の計算

時間の計算についてです。
今回紹介するTimeNumber関数は、二つの時間の差を計算するときに使えます。
NotesDateTimeクラスを使うことなく計算できるので、その分手軽です。

出勤時間と退勤時間の差を計算するときなどに使えそうですね。

Sub Click(Source As Button)
    Dim hh1, hh2 As Integer
    Dim mm1, mm2 As Integer
    Dim ss1, ss2 As Integer
    Dim tmp As Variant
    
    '最初の時間の入力
    hh1 = Inputbox( "最初の時を入力してください。", "時間の計算", Cstr( Hour( Now ) ) )
    mm1 = Inputbox( "最初の分を入力してください。", "時間の計算", Cstr( Minute( Now ) ) )
    ss1 = Inputbox( "最初の秒を入力してください。", "時間の計算", Cstr( Second( Now ) ) )
    
    '二番目の時間の入力
    hh2 = Inputbox( "二番目の時を入力してください。", "時間の計算", Cstr( Hour( Now ) ) )
    mm2 = Inputbox( "二番目の分を入力してください。", "時間の計算", Cstr( Minute( Now ) ) )
    ss2 = Inputbox( "二番目の秒を入力してください。", "時間の計算", Cstr( Second( Now ) ) )
    
    '時間の差を計算する(時、分、秒をそれぞれ差し引いた値をセットする)
    tmp = Timenumber( hh2 - hh1, mm2 - mm1, ss2 - ss1 )
    
    '時間の差を表示
    If tmp = 0 Then
        Messagebox "時間の差はありません。", 0, "時間の差"
    Else
        Messagebox "時間の差は" + Cstr(tmp) + "です。", 0, "時間の差"
    End If
End Sub


Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年12月3日水曜日

JavaでACLの内容を表示する

昔、Javaとノーツの連携を勉強しようと思って作成したサンプル。
自DBのACLを取得して、サーバコンソールに表示するものである。

このサンプルは、Javaエージェントとして作成してある。
DBにボタンを配置して、その中の式を
@Command([ToolsRunMacro];"エージェントの名前")
とする。

後は、このDBに対して、Webブラウザからアクセスして、このボタンをクリックするだけ。
すると、サーバコンソールにACLの一覧が表示される。

とりあえず、Javaを動かしてみたい。という人向きのエージェントかな?

import lotus.domino.*;

public class JavaAgent extends AgentBase {
    public void NotesMain() {
        try {
            Session session = getSession();
            AgentContext agentContext = session.getAgentContext();

            // (Your code goes here)
            Database db = agentContext.getCurrentDatabase();
            ACL acl = db.getACL();
            ACLEntry acle = acl.getFirstEntry();
            do {
                System.out.println(acle.getName());
            } while ((acle = acl.getNextEntry(acle)) != null);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}




Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年12月2日火曜日

不定回数の繰り返し処理その2

不定回数の繰り返し処理で書いたDo~Loopステートメントの異バージョンです。

前回はループ前に処理を行うかどうかを決めることができたが、今回は必ず、1度はループ処理を行うというもの。
Loopの所に、条件を書くことで実現できる。

細かい違いではあるが、処理によって、前判断と後判断を使い分けるようにすると、ソースが見やすくなるので、是非利用してもらいたい。

Sub Click(Source As Button)
    'ループ処理前の条件提示
    flag = Messagebox ( "ここで何を押してもループ処理を行います。", 2 + 48 , "タイトル")

    'ループ後に条件を判断する(必ず一回はループの中の処理を行う)
    Do
        flag = Messagebox ( "「キャンセル」を押すと、ループを抜けます。", 1 + 48, "タイトル" )
    Loop While flag = 1
End Sub




Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年12月1日月曜日

文字列の変換

今回は、StrConv関数を使った文字列の変換のサンプル。
この関数は、変換前の文字列と変換方法を指定するのだが、指定方法は、lsconst.lssに定数として定義してある。
そのため、あらかじめ#include "lsconst.lss"を入力しておけば、それらの定数が利用できる。

SC_UpperCase 1 '大文字に変換
SC_LowerCase 2 '小文字に変換
SC_ProperCase 3 '適切な文字に変換
SC_Wide 4 '半角から全角に変換
SC_Narrow 8 '全角から半角に変換
SC_Katakana 16 'ひらがなからカタカナに変換
SC_Hiragana 32 'カタカナからひらがなに変換
SC_NativeDigit 256 '0 ~ 9 からネイティブの数字に変換
SC_ArabicDigit 512 'ネイティブの数字から 0 ~ 9 に変換

サンプルでは、この定数は利用していないが、ソースがわかりやすくなるので、是非利用してほしい。
ただし、lsconst.lssをincludeしないまま、これらの定数を使うと、図のようなエラーになるので注意してほしい。










Sub Click(Source As Button)
    Dim uiws As New NotesUIWorkspace
    Dim varList( 1 To 9 ) As String
    Dim ret As Variant
    Dim cnvType As Integer
    Dim beforeStr As String
    Dim afterStr As String

    '入力変換前の文字列入力
    beforeStr = Inputbox( "何か文字列を入力してください。", "小文字を大文字に変換する" )

    '変換方法の指定
    varList(1) = "001. 大文字に変換"
    varList(2) = "002. 小文字に変換"
    varList(3) = "003. 適切な文字に変換"
    varList(4) = "004. 半角から全角に変換"
    varList(5) = "008. 全角から半角に変換"
    varList(6) = "016. ひらがなからカタカナに変換"
    varList(7) = "032. カタカナからひらがなに変換"
    varList(8) = "256. 「0 ~ 9」からネイティブの数字に変換"
    varList(9) = "512. ネイティブの数字から「0 ~ 9」に変換"

    ret = uiws.Prompt( PROMPT_OKCANCELLIST, "変換方法の指定", "文字列の変換方法を指定してください。", , Fulltrim(varList) )
    cnvType = Cint(Left( ret, 3 ))

    Messagebox _
    "文字列: " & beforeStr & Chr$(10) & "変換方法: " & Mid( ret, 5, Len(ret) - 4 ) _
    , 0, "変換前の情報"

    '文字列の変換
    afterStr = Strconv( beforeStr, cnvType )

    Messagebox afterStr, 0, "変換後の文字列"
End Sub





Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年11月28日金曜日

条件分岐

条件分岐のサンプルです。
真か偽かだけの条件分岐であれば、If関数を利用するかと思いますが、
複数の条件が存在する場合にはIf関数では分かりづらくなってしまいます。
このような場合、Select Case関数を利用します。

サンプルは、現在の月を取得して、それを日本語で表示するものです。

ところで・・・
Select Caseの条件式は数値であるように記述していますが、どうも数値でなくても良いようです。
ヘルプを見ても、「条件の値と比較するための値を表す式」とあるだけで、データ型は指定されていないのです。
ただし、文字列にすると、完全一致の場合は正常に動作しますが、範囲指定の場合は動きが怪しいので、やはりヘルプの例にあるように、数値で判断する方が良いでしょう。

Sub Click(Source As Button)
    '一つの条件に対し、複数の選択肢がある場合には次のようにする。
    Select Case Month(Today)
    Case 1:
        Messagebox "今日は一月です。" , 0, "結果"
    Case 2:
        Messagebox "今日は二月です。" , 0, "結果"
    Case 3:
        Messagebox "今日は三月です。" , 0, "結果"
    Case 4:
        Messagebox "今日は四月です。" , 0, "結果"
    Case 5:
        Messagebox "今日は五月です。" , 0, "結果"
    Case 6:
        Messagebox "今日は六月です。" , 0, "結果"
    Case 7:
        Messagebox "今日は七月です。" , 0, "結果"
    Case 8:
        Messagebox "今日は八月です。" , 0, "結果"
    Case 9:
        Messagebox "今日は九月です。" , 0, "結果"
    Case 10:
        Messagebox "今日は十月です。" , 0, "結果"
    Case 11:
        Messagebox "今日は十一月です。" , 0, "結果"
    Case 12:
        Messagebox "今日は十二月です。" , 0, "結果"
    Case Else:
        Messagebox "今日は何月なんですか!?" , 0, "結果"
    End Select
End Sub




Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年11月26日水曜日

表示形式の設定

表示形式を設定する関数を紹介する。
具体的には、Format関数を使う。この関数を使うと、数値や文字列、日付/時刻データの形式を変更することができる。
画面に表示する際に利用することもできるし、プログラム中の計算用に形式を変更して使うこともできる。


サンプルは、数値、文字列、日付/時刻をそれぞれ形式を変更して表示するようにしている。
Sub Click(Source As Button)
    Dim suuji As Long
    Dim jikan As Variant
    Dim moji As String
    Dim ret As Variant

    suuji = 1234567
    Messagebox Cstr( suuji ), 0, "表示形式の変更前"
    ret = Format( suuji, "#,###" )
    Messagebox ret, 0, "表示形式の変更後(','付で表示)"

    moji = "abcdefghijklmn"
    Messagebox Cstr( moji ), 0, "表示形式の変更前"
    ret = Format( moji, ">" )
    Messagebox ret, 0, "表示形式の変更後(大文字で表示)"

    jikan = Now
    Messagebox Cstr( jikan ), 0, "表示形式の変更前"
    ret = Format( jikan, "yy/m/d h:m:s" )
    Messagebox ret, 0, "表示形式の変更後(年を下二桁で表示)"
End Sub



Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年11月25日火曜日

エラー処理(On Errorステートメント)

今日はエラー処理について書いてみる。
プログラムを書く際、自分が想定していなかった操作や動作が行われた場合、
何も対処していないと、プログラムが異常終了してしまう。
そういったことが起きないようにするのが、エラー処理である。

Dominoオブジェクトを取得していない(できない)まま、処理を進めるとか、
数値のみの入力領域に、文字列を入力してしまうなどである。

サンプルは、エラー処理なしと、ありの2種類用意した。
ともに、プロンプトを表示して、そこに入力した値をチェックするものである。

'エラー処理なしのサンプル
Sub Click(Source As Button)
    '数値型の変数の定義
    Dim res As Long

    '入力形式のダイアログボックスの表示(数値以外はシステムエラーで処理停止)
    res = Inputbox( "何か入力してください。", "エラー処理" , "" )

    '数値が入力されれば、次のメッセージが表示される
    Messagebox "数字を入力しましたね。", 0, "エラー処理"
End Sub


'エラー処理ありのサンプル
Sub Click(Source As Button)
    '数値型の変数の定義
    Dim res As Long

    'システムエラーが発生したら、InputErrというラベルへジャンプするという定義
    On Error Goto InputErr

    'エラー処理から戻るためのラベル
ValueInput:
    '入力形式のダイアログボックスの表示
    res = Inputbox( "何か入力してください。", "エラー処理" , "" )

    '数値が入力されれば、次のメッセージが表示される
    Messagebox "数字を入力しましたね。", 0, "エラー処理"

    'エラー処理のルーチンへ行かないように、強制終了させる必要がある
    Exit Sub

    'エラー処理のラベル
InputErr:
    Messagebox "数値以外を入力しましたね。ここは数値を入力してください。", 0 + 48, "エラー処理"
    'エラー処理が終わったら処理の流れを元に戻す必要がある
    Resume ValueInput
End Sub




Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年11月21日金曜日

@UserRoles関数の機能強化って・・・

機能強化された@UserRoles関数の不思議の記事で、
Notes8では、ローカルレプリカでも@UserRoles関数が動作するようになった!ということを書いたが、
どうも、そうではないらしい。
というのも、6.5の環境でも、ローカルレプリカであれば、@UserRoles関数は動作するようなのだ。
6.x以前の環境は持ち合わせていないので詳細は不明だが、実はかなり前からローカルレプリカのDBなら@UserRoles関数は動作していたのではないか?

DBの新規開発では、あまり使い途はないかもしれないが、既存のDB修正や、ローカルレプリカでの運用を想定している開発の場合には、良いのではないか?と思う。

もし、このような場面に遭遇した人は試してみてほしい。
もちろん、筆者も直面した場合は、その結果を記事にして報告する。

DB内の文書の検索

以前に、データベース内の検索という記事をいくつか書いた。
良く見返すと、NotesViewクラスのGetDocumentByKeyメソッドについて触れていなかった。

@DbLookUp関数の代わりとしてよく使うのに、書いていなかったのは不覚ですね・・・
ということで、今回はGetDocumentByKeyメソッドのサンプルです。

このメソッドを使う際の注意事項は、ほとんど@DbLookUp関数と同じです。
「ビューは1列目がソートされていること」です。

@DbLookUp関数と違うのは、
・検索キーは複数設定できること(この時、1番目のキーはビューの1列目、2番目のキーはビューの2列目・・・と対応していきます)。
・検索キーが「完全一致」なのか、「部分一致」なのかを選択できること。
・検索結果は、1文書であること(検索結果を全部抽出したい場合は、GetAllDocumentsByKeyメソッドを利用する)。
でしょう(他にも色々とありますが、それはヘルプで確認してください)。


サンプルは、自DBに登録されているCategoriesというフィールドの一覧を作成して、
その中から、検索したい項目を選択します。検索結果のSubjectフィールドの値を表示するものです。

GetDocumentByKey以外にもいくつかテクニック(と呼べるかどうかは微妙・・・)が隠されているので、
良く研究してみてください。
Sub Click(Source As Button)
    '検索するビュー変数の定義
    Dim session As New NotesSession
    Dim db As NotesDatabase
    Dim view As NotesView
    Dim doc As NotesDocument

    '検索キーの選択肢を表示するプロンプト関数を呼び出すための変数の定義
    Dim uiws As New NotesUIWorkspace

    '検索結果をセットする変数の定義
    Dim sdoc As NotesDocument

    '検索キーと検索結果の表示用変数の定義
    Dim tmp(1 To 1) As String
    Dim varList As Variant
    Dim unqList As Variant
    Dim key As String
    Dim sbj As String

    'ビューの取得
    Set db = session.CurrentDatabase
    Set view = db.GetView( "(ByCategory)" )

    'ビューに表示されている文書の大分類を取得
    Set doc = view.GetFirstDocument
    Do While Not ( doc Is Nothing )
        If Isempty( varList ) Then
            varList = Arrayappend( tmp, doc.ColumnValues(0) )
        Else
            varList = Arrayappend( varList, doc.ColumnValues(0) )
        End If
        Set doc = view.GetNextDocument( doc )
    Loop

    'キーの取得
    unqList = Arrayunique( varList, 0 )
    key = uiws.Prompt( PROMPT_OKCANCELLIST, "検索キーの入力", "ビューで検索する大分類を入力してください。", , unqList )

    'keyに基づいてビューを検索
    Set doc = view.GetDocumentByKey( key )

    sbj = doc.Subject( 0 )
    Messagebox sbj, 0, "検索結果"
End Sub




Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年11月20日木曜日

現在の文書の値を取得する

自文書のアイテム値を取得するものである。
今回は、NotesUIDocumentクラスのFieldGetTextメソッドを利用する。

※このメソッドで気をつけるべきなのは、「文字列」で取得されると言うこと。例えば、文書中で複数値を持つアイテムでも一つの文字列として認識されてしまうのだ。
NotesDocumentクラスのGetItemValueメソッドの場合は、アイテムの内容を正確に取得するので、複数値であれば配列として取得する。

サンプルは、自文書にある「Subject」「Categories」「Sections」アイテムの値を取得して、画面に表示するものである。

Sub Click(Source As Button)
    Dim uiws As New NotesUIWorkspace
    Dim uidoc As NotesUIDocument

    'CureentDocumentは今、開いている文書という意味
    Set uidoc = uiws.CurrentDocument

    'FieldGetTextで文書のフィールドの内容を取得する
    Messagebox "タイトルは、【" & uidoc.FieldGetText("Subject") & "】です。", 0, "結果"
    Messagebox "大分類は、【" & uidoc.FieldGetText("Categories") & "】です。", 0, "結果"
    Messagebox "小分類は、【" & uidoc.FieldGetText("Sections") & "】です。", 0, "結果"
End Sub




Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年11月19日水曜日

特定の文字の箇所を知る

文字列内の検索をする関数。
今までにもいくつかのサンプル内で使ってきた関数のInstrを利用する。

サンプルはアルファベットを格納した文字列変数があり、その中に含まれる文字列が何番目にあるのかを検索して、結果を表示するものである。
これとMid関数を組み合わせると、文字列の抽出ができるようになる。

このサンプルを元に、色々と試してみてほしい。
Sub Click(Source As Button)
    Dim STRINGS As String
    Dim ANS As Integer
    Dim inp As String

    '文字列の定義
    STRINGS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

    '文字列内の検索
    inp = Inputbox( "検索したいアルファベットを入力してください。", "検索するアルファベットの入力" )
    If inp = "" Then
        Msgbox "処理を中断しました。", 0, "文字列の検索"
    Else
        ANS = Instr( STRINGS, inp )
        If ANS = 0 Then
            Msgbox "見つかりませんでした。", 0, "文字列の検索"
        Else
            Msgbox ANS & "番目", 0, inp & "の位置"
        End If
    End If
End Sub




Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年11月18日火曜日

ビューに表示させないようにしてしまう

今日はちょっと変わったプロパティを紹介しよう。

ある特定のアイテム(文書に格納されているフィールドのこと)をビューに表示させたり、表示させないようにしたりするものである。
NotesItemクラスのIsSummaryプロパティにTrueもしくはFalseをセットすることで実現できるのだ。
Falseをセットすると、この「アイテム」はビューには表示されなくなる。
ただし、文書そのものが表示されなくなるわけではないので注意してほしい。

サンプルは、自文書のSubjectアイテムをビューに表示させないようにするというものだ。
元に戻したい場合は、サンプルのitem.IsSummary = Falseitem.IsSummary = Trueに変更すれば良いだけである。
Sub Click(Source As Button)
    Dim uiws As New NotesUIWorkspace
    Dim uidoc As NotesUIDocument
    Dim doc As NotesDocument
    Dim item As NotesItem

    '自文書の取得
    Set uidoc = uiws.CurrentDocument
    Set doc = uidoc.Document
    Set item = doc.GetFirstItem( "Subject" )

    'ビューへの表示を許可しないにする
    item.IsSummary = False
    Call doc.Save( True, True )
End Sub




Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年11月14日金曜日

デリミタによる文字列の分割

今日はデリミタ(区切り文字)で文字列を分割してみるというLotusScriptです。

ret = Split( strValue, ",", -1, 5 )
この部分が分割する関数である。
1番目の引数は、分割したい文字列。
2番目の引数は、デリミタ。
3番目の引数は、文字列を何個に分割したいのか、その個数を書く。-1の場合は、デリミタの分だけ全部分割する。
4番目の引数は、デリミタの判別方法。大文字小文字や全角半角を区別するのに使う。5は、両方とも区別しない。
 ここを1とすると、","(半角カンマ)と","(全角カンマ)を区別して、デリミタに指定した文字だけを区切り文字とする。

サンプルは、文字列を","で区切り、それらをプロンプト表示するものである。
※サンプルでは、","(半角カンマ)をデリミタにしているが、","(全角カンマ)でも同じ結果になる。

Sub Click(Source As Button)
    Dim strValue As String
    Dim ret As Variant
    Dim i As Integer

    strValue = |1,"abcdefg",100,150,120,110,300,100,100,100,500,"hijklmn",| & _
    |"192.168.0.1","00:xx:yy:zz:nn:mm","vwxyz",|
    'ブログで表示しきれないので、2行に分けている
    ret = Split( strValue, ",", -1, 5 )
    For i = 0 To Ubound(ret)
        Msgbox ret(i), 0, Cstr(i+1) & "番目のデータ"
    Next
End Sub



Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年11月13日木曜日

機能強化された@UserRoles関数の不思議

DBにおける自分のロールを表示する
では、@UserRoles関数の動きを説明した。
Notes 8になって、この関数が機能強化されたとのことで、試してみた・・・

が、やっぱりローカルでは動作しない。
なぜ???と、よ~くデザイナーヘルプを眺めてみると・・・
「サーバー上のデータベースまたはローカルの複製されたデータベースの場合は、現在のユーザーが持つロールのリストが返されます。ロールは、データベースのアクセス制御リスト内に定義されています。」
とある。

ん?どうやら、レプリカのDBでないと、ローカルでは動作しないようだ。
・・・ということで、早速サーバにあるDBをローカルに複製してみる。

おぉ!@UserRoles関数が動作するではないか!!

ここでちょっと考えてみた。
このDB、サーバにあるDBを削除したらどうなるんだろう?動くのかな?

はい。削除してみました。
結果・・・

サーバ上のDBを削除しても、ローカルレプリカのDBでは、@UserRoles関数は動作しました。
こうなってくると、ローカルに作成したDBとローカルレプリカのDBの違いは何だろう?

データベースのプロパティ、複製の設定を見てみたが、変わったところはない。
うーん。何でだろう???

誰か知ってたら教えて!

新規文書かどうかのチェックその2

新規文書かどうかを判断するLotusScriptの第2弾。

新規文書かどうかのチェック
では、NotesDocumentクラスのプロパティということで、バックエンドで判断していたが、今回は、NotesUIDocumentクラスの場合である。
フォームのPostOpenイベントで使うのが良いだろう。

サンプルは前回と同じく、自文書が新規文書かどうかを判断して、結果を表示するという単純なものだ。
Sub Click(Source As Button)
    Dim uiws As New NotesUIWorkspace
    Dim uidoc As NotesUIDocument

    '自文書の取得
    Set uidoc = uiws.CurrentDocument

    If uidoc.IsNewDoc = True Then
        Messagebox "新規文書です。", 0, "新規文書かどうかのチェック"
    Else
        Messagebox "新規文書ではありません。", 0, "新規文書かどうかのチェック"
    End If
End Sub




Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

新規文書かどうかのチェック

今回は、新規文書かどうかのチェックだ。
文書の状態に応じて処理を分ける際に活用してほしい。


サンプルは、自文書が新規文書かどうかを判断して、結果を表示するという単純なものだ。
Sub Click(Source As Button)
    Dim uiws As New NotesUIWorkspace
    Dim uidoc As NotesUIDocument
    Dim doc As NotesDocument

    '自文書の取得
    Set uidoc = uiws.CurrentDocument
    Set doc = uidoc.Document

    'NotesUIDocumentとはプロパティ名が違うことに注目
    If doc.IsNewNote = True Then
        Messagebox "新規文書です。", 0, "新規文書かどうかのチェック"
    Else
        Messagebox "新規文書ではありません。", 0, "新規文書かどうかのチェック"
    End If
End Sub




Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年11月12日水曜日

ユーザー名の取得その2

ユーザ名の取得の第二弾。
今回は正規化された形に変換してみる。

作成者フィールドを変更するではさらっと流したが、重要なことなので、ここだけ抜き取って説明する。
※「canonical」とは正規のと言う意味である。

 グループ文書のメンバーリストなど、ノーツのユーザー名を格納する場合にはこの形式でないといけません。

今回のサンプルもLotusScriptと@関数の2種類用意する。
フィールドの値に記述しておくときは@関数を使い、バックエンドで処理するときはLotusScriptというように、場合に応じて使い分けてほしい。

Sub Click(Source As Button)
    Dim BeforeName As String
    Dim AfterName As String

    Dim NotesNamae As NotesName

    BeforeName = "Guy Locke/Oyoyo"
    Messagebox BeforeName, 0, "変換前の名前"

    Set NotesNamae = New NotesName( BeforeName )
    AfterName = NotesNamae.Canonical

    Messagebox Aftername, 0, "変換後の名前"
End Sub



BeforeName := "Guy Locke/Oyoyo";
@Prompt([OK];"変換前の名前";BeforeName);

AfterName := @Name([Canonicalize];BeforeName);
@Prompt([OK];"変換後の名前";AfterName)





Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年11月11日火曜日

アクセス5,000件突破!

気がついたら、アクセス件数が5,000を超えました。

3月末に始めてから、早7ヶ月が過ぎました。

飽きっぽい性格の割に、よく続いたなぁと思います。
ここで飽きずに、1年2年と続けていきますので、これからもよろしくお願いします。

ユーザー名の取得

ユーザ名を取得して使いやすい形に変換するという方法です。
LotusScriptの場合、ユーザ名は一旦、NotesNameクラスで定義する必要があります。
その後、各種プロパティを用いて、加工します。

@関数の場合、@UserNameでユーザ名を取得して、@Name関数で加工します。


今回はLotusScriptと@関数のサンプルを用意しました。
場合に応じて、使い分けてください。

※「abbreviate」は省略するという意味です。

Sub Click(Source As Button)
    Dim BeforeName As String
    Dim AfterName As String

    Dim NotesNamae As NotesName

    BeforeName = "CN=Guy Locke/O=Oyoyo"
    Messagebox BeforeName, 0, "変換前の名前"

    Set NotesNamae = New NotesName( BeforeName )
    AfterName = NotesNamae.Abbreviated

    Messagebox Aftername, 0, "変換後の名前"
End Sub


BeforeName := "CN=Guy Locke/O=Oyoyo";
@Prompt([OK];"変換前の名前";BeforeName);

AfterName := @Name([Abbreviate];BeforeName);
@Prompt([OK];"変換後の名前";AfterName)




Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年11月10日月曜日

フォームの再計算

フォームの再計算を行うメソッドとして、Refreshメソッドがある。
文書を開いた状態で、F9キーを押したのと同じ効果がある。

計算結果フィールドの値を更新したい場合や、キーワードフィールドの内容を更新した場合に使える。
@関数では、@Command([ViewRefreshFields])が同じ効果を持つ。

Dim uiws As New NotesUIWorkspace
Dim uidoc As NotesUIDocument

Set uidoc = uiws.CurrentDocument
Call uidoc.Refresh



※スクリプトの場合、フィールドのExitingイベントなどで仕掛けることが出来るので、そのフィールドからカーソルが移動したときに、自動で再計算を行わせることが可能。
 →@関数では出来ないので、ホットスポットボタンを作成して押させるようにするしかない。


Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年11月6日木曜日

書き出しメニューの使いづらいところ

不具合というか仕様というか・・・

ビューから実行できる「ファイル」「書き出し」メニューで、ちょっとした現象に出会った。
実際には以前にも同じ目にあったのだが、忘れていた。
なので、忘れないようにここに書いておく。

ビューに複数値のデータを持った列がある(図を参照)。

この列が、1行で表示しきれない場合、「ファイル」「書き出し」メニューでCSVに書き出しを行う。
すると、書き出されたCSVには、1行分のデータしか書かれないのだ。つまり、2行目以降に押し込まれたデータは書き出しの対象外になってしまうのだ。

CSVに書き出すプログラムを作るのが面倒で、「メニューから実行できるからいいや」と言って、ビューの設定をおざなりにしてしまうと、CSVの書き出しが正しく行われないと言うことになる。
解決するには、
1.列幅を広げて1行で表示できるようにする。
2.自分でCSVに書き出すためのプログラムを作成する。
のどちらかである。
1.の方法が簡単だが、列幅は広げられる最大値が決まっているので(かなり大きいが)、大量のデータを表示している場合は、2.の方をお勧めする。
ファイルの書き出しが参考になるだろう。


Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年11月5日水曜日

メール送信その2

メール送信の応用。
送信先がノーツであれば、Memoフォームで送らなくても良いのだ。
このスクリプトを実行するDBにフォームがあれば、そのフォーム自体をメール文書として送信することが可能である。

さらに、SaveMessageOnSendプロパティをTrueにすることにより、メール送信時に、文書をDBに保存することも可能である。

サンプルは、DBにあるフォーム(DB_Form)で文書を作成して、このフォームごと送信する。その際、文書をDBにも保存するものである。

Sub Click(Source As Button)
    Dim session As New NotesSession
    Dim db As NotesDatabase
    Dim mdoc As NotesDocument
    Dim mritem As NotesRichTextItem

    Set db = session.CurrentDatabase
    Set mdoc = db.CreateDocument
    Set mritem = New NotesRichTextItem( mdoc, "Body" )

    mdoc.Form = "DB_Form"
    mdoc.Subject = "DBのフォームです"
    mdoc.SaveMessageOnSend = True

    Call mritem.AppendText( "とりあえず普通に文字を書きます。" )
    Call mritem.AddNewline( 2 )
    Call mritem.AppendText( "改行した後に文字を書きます。" )
    Call mritem.AppendTable( 2, 2 )
    Call mritem.AppendText( "表を追加した後人文字を書きます。" )

    Call mdoc.Send( True, "xxxx yyyy/zzzz" )
End Sub




Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

メール送信その1

よく使うであろうメール送信のサンプル。
バックエンドで文書を作成して、Sendメソッドを使うだけ。

作成した文書にSendToを追加しない場合、Sendメソッドの2番目の引数に送信先を入力できる。
まぁ、わざわざそんなことをする人がいるとは思えないが・・・
CopyToやBlindCopyToも機能する。ただし、Sendメソッドにはそれを指定する引数はないので、自分でそのアイテムを作成する必要がある。

サンプルでは、Memoフォームの文書を作成して、その文書を送信するものだ。

---------------------------------------------------------
Sub Click(Source As Button)
Dim session As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument

Set db = session.CurrentDatabase
Set doc = db.CreateDocument
doc.Form = "Memo"
doc.Subject = "メール送信サンプル"
doc.SendTo = "xxxx yyyy/zzzz"
Call doc.Send( False )
End Sub


Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年11月4日火曜日

アンケート結果



気まぐれで一週間ほどアンケートを採ってみた。
いったい、どれくらいの人が読者なのか分からないので、この数値をそのまま信用して良いかは分からないが、一応今後の目安にしていこうと思う。

しかし、サンプルの提供が一番なのはやっぱりショックである。
デザイナーヘルプに豊富に出ているのだから、それを見て、自分で理解してもらうのが一番だと考えているからである。
ここにサンプルを載せているのは、参考にしてほしいのはもちろんだが、筆者自身、こうやってサンプルを作りながら覚えてきたからだ。
他人のサンプルを参考にするのはよいが、まるっきりコピーとかはやめてほしい。
(なので、あまり詳しいサンプルは書かないようにしているのだけど・・・)

2008年10月31日金曜日

他のエージェントを実行する

ノーツDBにあるエージェントを呼び出して実行するという方法。
NotesAgentクラスのRunメソッドを使う。これは、実行された場所でエージェントを実行する。
ノーツDBのボタンなどに記述した場合、このエージェントはクライアント側で実行される。

同じようなものでRunOnServerメソッドがある。こちらは、サーバ上でエージェントを実行するものである。
場合によってうまく使い分けてほしい。

サンプルは、ボタンに記述してあるもので、単純に指定したエージェントを実行するだけのものである。

----------------------------------------------------------------------
Sub Click(Source As Button)
Dim session As New NotesSession
Dim db As NotesDatabase
Dim agent As NotesAgent

Set db = session.CurrentDatabase
Set agent = db.GetAgent( "(NotesAgentクラス\他のエージェントを呼び出す)" )

'エージェントを実行する
Call agent.Run
End Sub



Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年10月30日木曜日

メールアドレスの抽出その2

メールアドレスの抽出で書いた記事だが、もっと簡単な方法があったので、掲載しておく。

@Name関数のオプションにある[Address821]を使えば良かったのだ。
これを使うと、メールアドレスから、RFC821形式でアドレスを返してくれるのだ。
しかも、アドレスの所は、複数値であっても有効なのである。

サンプルは、SendToフィールドの値からRFC821形式のアドレスを取得するものである。
CopyToやBlindCopyToからも取得したいなら、SendTo:CopyTo:BlindCopyToとリスト形式にすれば良いだけである。

------------------------------------------------------------------------
tmp := @Name([Address821];SendTo);
@Prompt([Ok];"メールアドレスの抽出";@Implode(tmp))


Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年10月29日水曜日

「ファイルを開く」ダイアログを表示する

ファイルを開くダイアログを表示するという方法を紹介しよう。
@関数で言えば、@Prompt([LocalBrowse]~)に相当するのだが、LotusScriptの方がもう少し便利に使える。
ダイアログに表示するファイルの種類を、好きに指定できるのだ。

今回はサンプルを2つ用意した。
1つは、テキストファイル(拡張子がtxtとcsvのもの)を選択するもので、
もう1つは、ノーツDB(拡張子がnsfとntfのもの)を選択するものだ。

昨日の記事と照らし合わせてみてもらえると面白いだろう。

--------------------------------------------------------------
Sub Click(Source As Button)
Dim uiws As New NotesUIWorkspace
Dim ret As Variant

ret = uiws.OpenFileDialog( False, "ファイルを開く", "テキストファイル|*.txt|CSVファイル|*.csv" )
End Sub


--------------------------------------------------------------
Sub Click(Source As Button)
Dim uiws As New NotesUIWorkspace
Dim ret As Variant

ret = uiws.OpenFileDialog( False, "データベースを開く", "Notes Databases|*.nsf|Notes Templates|*.ntf" )
End Sub



Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年10月28日火曜日

「データベースを開く」ダイアログを表示する

以前に、データベースの選択という記事で、「データベースを開く」ダイアログを表示するというサンプルを示したが、今回はそのLotusScript版である。
効果は同じなので、場面に応じて使い分けてほしい。

ここで気をつけてほしいのが、「PROMPT_CHOOSEDATABAS」という定数。
ヘルプによると、Release 6.0では実装されていないと書いてあるが、筆者の8.0.2の環境でも実装されていないようだ。
なので、PROMPT_CHOOSEDATABASと書いてもコーディングエラーになる。
そこでサンプルでも、13という値を直接書いている。後で分からなくならないように、コメントを記述しておくことをお勧めする。

また、Promptメソッドの2番目以降(4番目と5番目は任意)は、何を書いても無視されるので、""にしておくこと。

-----------------------------------------------------------------------
Sub Click(Source As Button)
Dim uiws As New NotesUIWorkspace
Dim ret As Variant

'PROMPT_CHOOSEDATABASEは、リテラル値で13
ret = uiws.Prompt( 13, "", "" )
If Isempty( ret ) Then
Msgbox "データベースは選択されていません。", 0, "データベースの選択"
Exit Sub
End If
Msgbox ret(0), 0, "サーバ名"
Msgbox ret(1), 0, "データベースファイル名"
Msgbox ret(2), 0, "データベースタイトル"
End Sub



Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年10月24日金曜日

増えたビューアイコン




昔からノーツに携わっている人からしたら、「ずいぶん増えたなぁ」と思えるような画面です。
50個近くアイコンが増えましたね。
それにしても、同じようなアイコンがあるなぁ。なんで使い回ししないんだろ?

ちなみに、ビューのポップアップヘルプを有効にしておくと(ユーザプリファレンスで設定可能)、
アイコンの名前が表示される。
一応、全部違っているようなので、これで「違うアイコンです!」って言い切るつもりなんだろう・・・
プログラマの方は、このメッセージも確認してからビューアイコンを使うようにしてほしい。

Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

フィールドの内容をクリップボードにコピー

Notes/Domino8環境へのバージョンアップに手間取ったので、今日も手抜き。

フィールドの内容をクリップボードにコピーするサンプル。
まぁ、クリップボードを使うから、UIでの利用だな。と覚えておけばよいでしょう。
ということで、NotesUIDocumentクラスのメソッドなのです。

------------------------------------------------------------------------------------------
Sub Click(Source As Button)
Dim workspace As New NotesUIWorkspace
Dim uidoc As NotesUIDocument

Set uidoc = workspace.CurrentDocument

Call uidoc.GoToField( "Subject" )
Call uidoc.SelectAll
Call uidoc.Copy
End Sub


Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年10月23日木曜日

環境のバージョンアップ

筆者の環境は、Lotus Notes/Dominoともに7.0.3であった。そこに、Sametimeをインストールして使っていた。
関わっていたプロジェクトも一段落したので、そろそろ環境をバージョンアップすることにした。

ということで・・・
Lotus Notes/Dominoをともに、8.0.2にしてみた。
Sametimeはインストールする気がなかったので、入れないでおいたら、ノーツクライアントが起動できない。
どうも、Sametimeのパスワードを入力するところで、止まってしまうようだ。

仕方がないので、Sametimeもインストールして、Domino 8.0.2+Sametime8.0というサーバ環境にしてみた。
その状態で、ノーツクライアントを起動すると、見事に起動できた。まさか、これが原因とは思いたくはないが・・・

とりあえず、これで、Windows XPにDomino 8.0.2 + Sametime 8.0 + Domino Designer + Domino Administratorという環境になった。


まだ保有している古いサンプルがいくつかあるが、これからはNotes/Domino 8でのサンプルも交えて記事を書いていけるようにしたい。

2008年10月22日水曜日

ノーツのバージョンを表示する

今回も手抜き。
なかなかネタが・・・

ノーツのバージョンを表示するサンプルです。
バージョンには、リリース番号と言われるものとビルド番号と言われているものがあります。
当然、返ってくる値が違うので、うまく使い分けをすることが必要になります。

開発者のみなさんがよく使うのは、NotesBuileVersionプロパティの方ではないでしょうか?
@Version関数に相当するものです。

サンプルは、実行するノーツクライアントのバージョンを表示するものです。

Sub Click(Source As Button)
 Dim session As New NotesSession
 
 Msgbox "リリース番号:" & Chr$(9) & session.NotesVersion & Chr$(10) & _
 "ビルド番号:" & Chr$(9) & session.NotesBuildVersion, 0, "このクライアントのノーツバージョン"
End Sub


@関数のVersion関数では、NotesBuildVersionの結果と同じものが表示されます。

Notes/Dominoがわからないときはこちらへ!
Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年10月20日月曜日

文書の削除のチェック

文書の削除イベントを拾うというもの。
文書のオープンや書き込みなどはフォーム単位で設定するが、フォームの中に「文書を削除した」というイベントはない。

実は、
設計要素-その他-データベースリソース-データベーススクリプトのQuerydocumentdeleteイベントにセットします。
つまり、各フォームではなく、データベース全体として捉えるのである。
ビューで複数文書を削除する場合など、選択する文書によってフォームが違ったりするし、フォームを開いている状態で、Deleteキーを押しても文書は削除できるし、というように、色々な場面で文書の削除ができるからであろう。
と勝手に推測している。

サンプルは、文書を削除する際に、本当に削除して良いかどうかの確認ダイアログを表示するものである。
Sub Querydocumentdelete(Source As Notesuidatabase, Continue As Variant)
    '削除の確認メッセージ(「はい」「いいえ」のボタンが出る)
    res = Messagebox( "ホントに削除しますか?", 4 + 32, "文書の削除" )
    '6は「はい」を選択、7は「いいえ」を選択、elseはエラー処理
    Select Case res
    Case 6:
        Messagebox "削除フラグをOnにしますが、文書は削除されません。", 0, "文書の削除"
    Case 7:
        Continue = False
    End Select
End Sub


Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年10月17日金曜日

データ型について

前にも書いたと思うが・・・みんなヘルプは読んでるかな?
ノーツは情報が少ない!と言われているけど、大抵のことはヘルプDBを読めば解決してくれるものだ。

ヘルプ、Administratorヘルプ、Designerヘルプ、日本語環境設定ガイド、Notes/Dominoリリース
ノーツDBなんだから、全文索引をつければ検索も快適に行えるし、サンプルコードだって豊富に付いている。

私がここに書いている記事も、ほとんどはヘルプからの引用だ。もちろん、実体験をしたからこそ、書けるものではあるが。
プログラムが動かない、どの関数を使えば良いか分からない!という時こそ、ヘルプを見てほしい。


CCur関数を使うと、小数点4桁以下が切り捨てられるという話があった。
まず、CCur関数ってどんな仕様だっけ?と思い、ヘルプを読んでみた。
そうしたら、
「CCur 関数は、小数 4 桁に丸めて expr の数値を Currency 型の値として返します。」
とあるではないか。
この関数を使う際、ヘルプを見てから使っていれば、このような疑問は起きなかったはずである。
(そもそも、よくこんな関数知っていたなぁ。というのが私の感想である)

では、どんな関数を使えば良いのか?それもヘルプに出ている。
「関連項目」として、関係する関数やクラスなどがリンクとして表記されているのだ。
そこから、探していけば答えはすぐに見つかるはず。

他人に聞くな。とは言わない。もちろん、自分より詳しい人はたくさんいるであろうから、彼らの智恵を借りることは良いことである。
しかし、自分で調べられるなら、その方が早いし、確実である。


まずは、ヘルプを読もう!
それからもで遅くないよ。




Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

文書内のフィールドの値を取得する

やってそうでやってなかったみたいなので・・・
今回は文書内のフィールドの値を取得してみよう。

doc(NotesDocumentクラスの変数)内のSubjectフィールドの値を取得する場合、
サンプル等でよく見かけるのが、
doc.Subject(0)という書式である。
これは、「拡張クラス」構文と言って、NotesDocumentクラスのGetItemValueメソッドと同じ働きをするものである。
なお、(0)はSubjectフィールドの1つめの値という意味である(フィールドは複数値を許可していることがあるので、このような設定が必要になる)。

だったら、GetItemValueメソッドは不要ではないか?と思ってしまうだろう。
ところが、次のような場合は、「拡張クラス」構文は利用できないので、GetItemValueメソッドを使う方が良いのである。
例)Subject_1、Subject_2、Subject_3のフィールドの値をそれぞれ、i(1)、i(2)、i(3)という変数に格納する。
普通なら、
i(1) = doc.Subject_1(0)
i(2) = doc.Subject_2(0)
i(3) = doc.Subject_3(0)
となるのだが、これではSubject_xxが100まであったら、とてもじゃないが書いていられない。
ということで、
For n = 1 to 3
i(n) = doc.GetItemValue( "Subject_" & cstr(n) )
Next
とするのだ。
こうすると、cstr(n)はループの回数に従って、1,2,・・・と増えていき、
結果として、Subject_1,Subject_2・・・としていくことができる。
後は、これをGetItemValueで取得していけば良いのである。

なので、処理の内容によって、うまく使い分けてほしい。



今回のサンプルは、至ってシンプル。ByCategoriesビューで最初に取得した文書のSubjectフィールドを取得して画面に表示するものである。

Sub Click(Source As Button)
    Dim session As New NotesSession
    Dim db As NotesDatabase
    Dim view As NotesView
    Dim doc As NotesDocument
    Dim tmp As Variant
    
    Set db = session.CurrentDatabase
    Set view = db.GetView( "ByCategories" )
    Set doc = view.GetFirstDocument
    
    tmp = doc.GetItemValue( "Subject" )
    Messagebox tmp( 0 )
End Sub






Notes/Dominoで困ったことがあれば、弊社にお問い合わせください。
IBM Championの私が承ります!
Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年10月16日木曜日

アップデート講座を受講してみた

あんなもん受かるかぁ!で書いたが、Notes8のアップデート試験は散々な目にあった。
このままの調子で、再度受験しても受かるわけはないので・・・

IBM Lotus Domino8 アプリケーション開発アップデート
の認定講座を受講してきた。

講習自体はそんなに難しくはなく(1日コースなので、薄っぺらいこと・・・)、もっぱらどのような問題が試験に出たのか、どのような事を学習すればよいのか?ということに重きを置いてみた。
講師の方に色々と聞いてみたが、結局の所、ほぼ丸暗記することをお勧めされたのであった。
ということで、オンラインヘルプの必要箇所を印刷して暗記しよう!

それで、受かるのかなぁ?受験日も決めないといけないし・・・

2008年10月10日金曜日

NotesURLを作成する方法(@関数の場合)

NotesURLを作成する方法(LotusScriptの場合)で紹介したNotesURLを作成する方法の@関数版。


サンプルは自文書のNotesURLを作成するもの。
ポイントは、ノーツDBのレプリカIDを取得するところ。
@ReplicaIDで取得すると、レプリカIDの中に":"が含まれるのだ。NotesURLとして利用する場合、この":"は不要(というか、あるとエラーになる)なので、取り除いておくことが必要になる。

srv := @Name([CN];@Subset(@DbName;1));
svn := @If(srv="";"localhost";srv);
dbn := @ReplaceSubstring(@ReplicaID;":";"");
view := @ViewTitle;
docid := @Text(@DocumentUniqueID);

ret := "Notes://" + svn + "/" + dbn + "/" + view + "/" + docid;

@Prompt([Ok];"NotesURL";ret)


これを覚えておくと、Notes クライアント以外でメールを受け取った時に活用できるので、便利かな。

Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

NotesURLを作成する方法(LotusScriptの場合)

NotesURLとは、Notes://で始まるもので、ノーツDBの固有の文書を表すものである。
IEのアドレス部分に入力したり、「ファイル名を指定して実行」の所に入力したりすると、ノーツクライアントが起動して、指定した文書を開くことができるのである。

他システムからノーツ文書を開くときに便利に使える。

そのNotesURLを作成する方法を考えてみた。
サンプルは、現在の文書からNotesURLを作成するものである。
ビューで実行しても、文書を開いて実行してもできるようにしてある。
ただし、文書を開いて実行する場合、「現在のビュー名」が取得できないため、
"($All)"固定にしている。

Sub Initialize
 Dim uiws    As New NotesUIWorkspace
 Dim uidoc   As     NotesUIDocument
 Dim udoc    As     NotesDocument
 Dim db      As     NotesDatabase
 Dim srv     As     NotesName
 Dim session As New NotesSession
 Dim docs    As     NotesDocumentCollection
 Dim uiview  As     NotesUIView
 Dim view    As     NotesView
 Dim nurl    As     String
 Dim svn     As     String
 Dim vname   As     String
 
 Set uidoc = uiws.CurrentDocument
 If uidoc Is Nothing Then
  Set db     = session.CurrentDatabase
  Set docs   = db.UnprocessedDocuments
  Set udoc   = docs.GetFirstDocument
  Set uiview = uiws.CurrentView
  Set view   = uiview.View
  vname = view.UniversalID
 Else
  Set udoc = uidoc.Document
  Set db   = udoc.ParentDatabase
  vname = "($All)"
 End If
 Set srv = New NotesName( db.Server )
 If srv.Common = "" Then
  svn = "localhost"
 Else
  svn = srv.Common
 End If
 
 nurl = "Notes://" & svn & "/" & db.ReplicaID & "/" & vname & "/" & udoc.UniversalID
 Msgbox nurl
End Sub


Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年10月9日木曜日

スクリプトでテキストリストを操作する

テキストリストを扱ってみよう。
テキストフィールドに複数の値をセットしたいときに便利。

サンプルは、自文書の返答文書として、文書を作成。
その文書のテキストフィールド(複数値可)に値をリストとして追加していくというもの。


Sub Click(Source As Button)
    Dim session As New NotesSession
    Dim db As NotesDatabase
    Dim uiws As New NotesUIWorkspace
    Dim uidoc As NotesUIDocument
    Dim doc As NotesDocument
    
    '返答文書関連の変数の定義
    Dim resdoc As NotesDocument
    Dim item As NotesItem
    Dim subject As String
    
    'DBの全文書関連の変数の定義
    Dim docs As NotesDocumentCollection
    Dim doc2 As NotesDocument
    Dim i As Integer
    
    '自DBを取得する
    Set db = session.CurrentDatabase
    
    '自文書を取得する
    Set uidoc = uiws.CurrentDocument
    Set doc = uidoc.Document
    
    '返答文書の作成(resdocがdocの返答文書になる)
    Set resdoc = db.CreateDocument
    Call resdoc.MakeResponse( doc )
    
    'テキストフィールドをクリアする
    Set item = resdoc.ReplaceItemValue( "TextField" , "" )
    
    'DBの全文書のタイトルを取得して、テキストリスト形式で返答文書に埋め込む
    Set docs = db.AllDocuments
    For i = 1 To docs.Count
        Set doc2 = docs.GetNthDocument( i )
        subject = doc2.Subject( 0 )
        Call item.AppendToTextList( subject )
    Next
    
    'その他の項目を設定
    resdoc.Form = "Response2"
    resdoc.Subject = "バックグラウンドで作成した返答文書"
    
    '返答文書を変更したので保存する
    Call resdoc.Save( True, True )
End Sub





Notes/Dominoで困ったことがあれば、弊社にお問い合わせください。
IBM Championの私が承ります!
Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ


2008年10月8日水曜日

文書のアイテムの名前の一覧

Notes文書のアイテム一覧を表示する方法である。

DB中の各フォームのフィールド一覧で紹介したNotesFormクラスのFieldsプロパティと似ているが、文書内に存在するアイテムが対象となる。従って、フォームにない隠しフィールドも分かるようになる。

Sub Click(Source As Button)
    '自文書を取得するための変数の定義
    Dim uiws As New NotesUIWorkspace
    Dim uidoc As NotesUIDocument
    Dim doc As NotesDocument
    
    '結果表示用変数の定義
    Dim sbj As String
    Dim i As Integer
    
    '自文書の取得
    Set uidoc = uiws.CurrentDocument
    Set doc = uidoc.Document
    
    i = 0
    '文書のアイテム一覧を取得する
    Forall x In doc.Items
        i = i + 1
        sbj = sbj & Cstr( i ) & "." & x.Name & Chr$(10)
    End Forall
    
    Messagebox sbj, 0, "文書のアイテム一覧"
End Sub




Notes/Dominoで困ったことがあれば、弊社にお問い合わせください。
IBM Championの私が承ります!
Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年10月7日火曜日

文書のアイテムの最終更新日

文書にあるアイテムの最終更新日を取得する方法。
これでどのフィールドの値が変更されたかどうかが確認できるかな?

サンプルは、自文書の各アイテムの最終更新日を表示するものである。

Sub Click(Source As Button)
    Dim uiws As New NotesUIWorkspace
    Dim uidoc As NotesUIDocument
    Dim doc As NotesDocument
    
    Dim sbj As String
    Dim i As Integer
    
    '自文書の取得
    Set uidoc = uiws.CurrentDocument
    Set doc = uidoc.Document
    
    i = 0
    sbj = ""
    
    '文書中の全アイテム分繰り返す
    Forall x In doc.Items
        i = i + 1
        'x.Nameがアイテム名で、x.LastModifiedがアイテムの最終更新日
        sbj = sbj & Cstr( i ) & "." & x.Name & "の最終更新日 " & Cstr( x.LastModified ) & Chr$(10)
    End Forall
    
    '結果の表示
    Messagebox sbj, 0, "文書中のアイテムの最終更新日"
End Sub


Notes/Dominoで困ったことがあれば、弊社にお問い合わせください。
IBM Championの私が承ります!
Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ


2008年10月2日木曜日

親文書を検索する

自文書の親文書を検索する方法を紹介する。

サンプルは、ビューから実行する物で、選択した文書の親文書のタイトル(Subjectフィールド)を表示するものである。
親文書が存在しない場合は、その旨のメッセージを表示するようになっている。


Sub Initialize
    '自DBの定義
    Dim session As New NotesSession
    Dim db As NotesDatabase
    Dim docs As NotesDocumentCollection
    Dim doc As NotesDocument
    
    '親文書の定義
    Dim pid As String
    Dim pdoc As NotesDocument
    
    '現在選択されている文書の取得
    Set db = session.Currentdatabase
    Set docs = db.UnprocessedDocuments
    Set doc = docs.GetFirstDocument
    
    '親文書の文書IDを取得する(存在しない場合は、Nullを返す)
    pid = doc.ParentDocumentUNID
    If pid = "" Then
        Messagebox "この文書には親文書は存在しません。", 0 + 16, "親文書の検索"
        Exit Sub
    End If
    
    '取得した親文書のIDを元にDBを検索(実際に親文書があるかどうか)
    Set pdoc = db.GetDocumentbyUNID( pid )
    If pdoc Is Nothing Then
        Messagebox "親文書が存在しません。削除された可能性があります。", 0 + 16, "親文書の検索"
    Else
        '親文書のタイトル(Subjectフィールドの内容)を表示する
        Messagebox "親文書のタイトルは、『" + pdoc.Subject(0) + "』です。", 0 + 64, "親文書の検索"
    End If
End Sub



Notes/Dominoで困ったことがあれば、弊社にお問い合わせください。
IBM Championの私が承ります!
Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2008年10月1日水曜日

メールアドレスの抽出

文書中のメールアドレスから、アドレス部分だけを抽出する方法。

どのアドレスに送信してきたのかを確認するのに使えるかな。
Address821形式であれば、そのまま抽出すればよいのだが、
Address822形式の場合、フレーズパートが付いてくるので、分かりづらい。

サンプルは、そのフレーズパートを除いてしまうものである。

@For(
 i:=1;
 i<=@Elements(SendTo);
 i:=i+1;
 tmp:=tmp:@If(@ValidateInternetAddress([Address821];SendTo[i])="";
    SendTo[i];
    @Right(@Left(SendTo[i];">");"<")
   )
 );
@For(
 i:=1;
 i<=@Elements(CopyTo);
 i:=i+1;
 tmp:=tmp:@If(@ValidateInternetAddress([Address821];CopyTo[i])="";
    CopyTo[i];
    @Right(@Left(CopyTo[i];">");"<")
   )
 );
@For(
 i:=1;
 i<=@Elements(BlindCopyTo);
 i:=i+1;
 tmp:=tmp:@If(@ValidateInternetAddress([Address821];BlindCopyTo[i])="";
    BlindCopyTo[i];
    @Right(@Left(BlindCopyTo[i];">");"<")
   )
 );

@Prompt([Ok];"メールアドレスの抽出";@Implode(@Unique(@Trim(tmp))))


Notes/Dominoについてなんでも聞いてみよう!
Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ