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

テクてく 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 カスタマイズとセキュリティ強化 - 株式会社エフ