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

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

2009年5月28日木曜日

各種関数による時間の取得

今日は切ない事があった(ローカルDBを暗号化しないようにするには・・・に書いてあることをやっちまった)ので、
面白くも何ともない記事です。

ノーツを使って、時刻を取得するにはいくつものの方法があります。
それぞれどのように表示されるのかを知っておくと、実際にプログラムを組むときの目安になると思います。
そう言ったサンプルです。

-----------------------------------------------------------
Sub Click(Source As Button)
Dim scriptVar As Variant
Dim jikan As NotesDateTime
Dim formulaVar As Variant
Dim msg As String

scriptVar = Now()
Set jikan = New NotesDateTime( Now )
formulaVar = Evaluate( "@Now")

msg = _
"Now()関数で取得した時間:" & Chr$(9) & scriptVar & Chr$(10) & _
"NotesDateTimeのローカル時間:" & Chr$(9) & jikan.LSLocalTime & Chr$(10) & _
"@Now関数で取得した時間:" & Chr$(9) & formulaVar(0) & Chr$(10) & _
"Time関数で取得した時間:" & Chr$(9) & Cstr(Time) & Chr$(10) & _
"今日1日の経過時間(秒):" & Chr$(9) & Timer

Msgbox msg, MB_OK, "各種関数による時間の取得"
End Sub


このサンプルを実行したのが、以下の画面です。


なぜか、Evaluate( "@Now")の結果が1秒進んでますね。
実際には1秒未満でしょうが(何度か実行すると、同じ時刻にもなる)、遅れるなら分かるのですが、なぜ進むのでしょう?
ちょっと不思議です。


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

2009年5月27日水曜日

文字列の右からx番目までを取得する

今日も忙しいので、簡単なものにします。

Right関数の紹介です。
ある文字列の右側の一部が欲しいんだ!という時に使いますね。

Right関数の場合、「右側からxx文字分、抽出する」という使い方だけです。
なので、文字列の右側xx文字というのが分かっていないと使えないですね。

気をつけましょう。

サンプルは、自分で入力した文字列からxx文字抽出するというものです。



---------------------------------------------------------
Sub Click(Source As Button)
'変数の定義
Dim STRINGS As String
Dim NUM As String
Dim AFTER As String

STRINGS = Inputbox( "抽出したい文字列を入力してください。", "Rightを使った文字列の抽出", "abcdefghijklmnopqrstuvwxyz" )
NUM = Inputbox( "元の文字列から抽出したい文字数を入力してください。", "Rightを使った文字列の抽出" )

If STRINGS = "" Or Isnumeric(NUM) = False Then
'データがないので処理を中止
'数値以外が入力されたら処理を中止
Exit Sub
End If
If Cint(NUM) < 0 Then
'抽出するのに0未満の数値はNGなので、処理を中止
Exit Sub
End If

'文字列の抽出
AFTER = Right( STRINGS, Cint(NUM) )
Messagebox "元の文字列:" & Chr$(9) & STRINGS & Chr$(10) & "抽出した数:" & Chr$(9) & Cstr(NUM) & Chr$(10) & "抽出した文字列:" & Chr$(9) & AFTER, MB_OK, "Right関数を使って文字を抽出する"
End Sub


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

2009年5月23日土曜日

リスト変数と配列の違い

リストと配列の違いって分かりますか?
どちらも、一つの変数の中に複数の値を持つことができる。
という意味では同じものだと思いますが、実際はどうなんでしょう?

式言語(@関数)では、配列はなく、すべてリストとして処理をするようです。
しかし、LotusScript言語では、全く別のものとして扱われています。

デザイナヘルプを読んで、違いを簡単にまとめてみました。
詳しくはデザイナヘルプを読んでください。
それぞれの特性を活かして、よりよいプログラムを作成するようにしましょう。
【リスト】
 1次元の要素しか持たない
 要素数は動的に変化する
 ユーザ定義のデータ型内(Type内)では宣言できない
 リスト内の要素リストタグというものを利用してアクセスする
 リストタグは、リスト内の要素を表す一意の文字列である(数値でも良い)
【配列】
 複数次元の要素を持てる(最大で8次元まで可能)
 固定配列と動的配列の2種類があるが、利用前に要素数を決める必要がある
 ユーザ定義のデータ型内(Type内)では宣言できる
 配列内の要素は、「変数名(index)」のようにアクセスする
 indexは配列内の要素の順番を指す


サンプルは、リスト変数と配列を定義して、それぞれの値を表示するだけのものです。
IsList関数やIsArray関数で本当にリストなのか配列なのかをチェックしています。

Sub Click(Source As Button)
    Dim listText List As String
    Dim arrayText(2) As String
    Dim cnt As Integer
    
    listText("AA") = "1番目の値"
    listText("BB") = "2番目の値"
    listText("CC") = "3番目の値"
    
    arrayText(0) = "0番目の配列値"
    arrayText(1) = "1番目の配列値"
    arrayText(2) = "2番目の配列値"
    
    cnt = 1
    If Islist( listText ) Then
        Forall x In listText
            Msgbox "リストタグ【" & Listtag( x ) & "】: " & x, MB_OK, "リスト変数の" & Cstr(cnt) & "番目"
            cnt = cnt + 1
        End Forall
    End If
    
    cnt = 1
    If Isarray( arrayText ) Then
        Forall y In arrayText
            Msgbox y, MB_OK, "配列の" & Cstr(cnt) & "番目"
            cnt = cnt + 1
        End Forall
    End If
End Sub




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

2009年5月20日水曜日

ODSバージョンが変更できない!?

これって当たり前のこと?それともやり方が間違ってる?
というようなことが起きたので、書いておく。

筆者のNotes/Domino環境は、このブログの読者であればご存じのように8.5です。
しかし、ちょっとした事情により、R4.xやR5.xでも動作するノーツDBを作成することになりました。
まぁ、テストで利用する程度だったので、わざわざNotes R4.xやR5.xを用意するのも面倒だし、8.5のデザイナで開発しました。
その際、念のためにノーツDBファイルの拡張子をns4としたのが、そもそもの始まりです。

ns4はODSを20にする効果があります。
こうしてできあがったノーツDBをR4.xの環境に持って行ったところ、期待通りに動作しました。
さて、次はR5.xの環境です。
NoteIDやUNIDはそのまま使いたかったので、OSレベルでコピーしました。
OSレベルでコピーすると、ODSもそのままになります。
せっかく、R5.xの環境に持ってきたので、ODSを41に変更しようとしました。
管理者ヘルプに従って、
load compact -c ファイル名
を実行しました。が・・・ODSは20のまま。

あれ?おかしいな?と思いつつ、何度も実行しましたが、結果は変わりません。

ということで、8.5の環境で同じ事をしてみました。
サーバコンソールから
load compact -c ファイル名
を実行。が・・・やっぱりODSは20のまま。

えーっ!?なんでぇ。

どうも、拡張子をns4(ns5、ns6、ns7等)にしてしまうと、ODSが固定されてしまうようです。

このようにして作成したノーツDBを別のODSバージョンにするためには、
OSレベルでコピーをするのではなく、ノーツクライアントからデータベースのコピーもしくは複製で新しいノーツDBを作成する必要があります。
その際、拡張子は「nsf」にしておかないと、意味がありませんので注意しましょう。


ちなみに、8.5で作成したノーツDBをR5.xのデザイナで確認したところ、
「build.properties」「plugin.xml」「WEB-INF/classes/plugin/Activatorcl.」「.classpath」「.project」というフォームが見つかりました。
ファイル名から想像すると、JAVA関連のファイルのように見えますね。
上位バージョンで作ったノーツDBを利用すると、こういったことも起きるので、やはりそれぞれのバージョンで作るのが良さそうです。

2009年5月19日火曜日

タイムゾーン付の日付/時刻フィールドの値を取得する

テスト用のノーツDBを作っていたら、奇妙な現象が起きたので、ちょっと調べてみました。

奇妙な現象とは、日付/時刻フィールドについてで、値がなぜか標準時のタイムゾーンで保存されていたのです。
フィールドの設定は、「ローカルのタイムゾーンにあわせる」だったため、フォームを通して見たときは、日本時間になっていました。

この場合、@関数やLotusScriptはどのように時間を取得するのかきになったので、まずは@関数で取得してみました。
サンプルは、「datetimeF」という日付/時刻フィールドの値を@Promptで表示するものです。
@Promptはテキストしか表示できないので、datetimeFの値をテキストに変換しています。

datetimeFの実際の値は下図の通りです。


この状態で、サンプルを実行してみたら、こんな感じになりました(下図)。


どうやら、@Textで、テキストに変換する限りでは、自動でローカルのタイムゾーンにあわせてくれるようです。
LotusScriptで取得した場合にどうなるか?というのは次回にします。

@Prompt([Ok];"PCのタイムゾーン";@Text(@Zone));
@Prompt([Ok];"日付フィールドのタイムゾーン";@Text(@Zone(datetimeF)));

tm := "オプションなし: " + @Text(datetimeF) + @NewLine;
z0 := "オプション[Z0]: " + @Text(datetimeF;"Z0") + @NewLine;
z1 := "オプション[Z1]: " + @Text(datetimeF;"Z1") + @NewLine;
z2 := "オプション[Z2]: " + @Text(datetimeF;"Z2");

@Prompt([Ok];"日付フィールドの取得";tm+z0+z1+z2)


Notes/Dominoのアプリ開発ならこちらまで!
Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

2009年5月15日金曜日

他人のメールDBの所有者フィールドの内容を調べる

昔、メールDBのトラブルで、スケジュールが正しく反映されないということに遭遇したことがありました。
結局、その人のメールの所有者が誤っていたため、と言うことが分かり、強引に修正(*1)して、事なきを得ました。
ちなみに所有者というのは、下図の赤丸部分のことですね。


*1 その時のバージョンでは、メールの所有者は手動では変更することができず、LotusScriptを使いました。

その時に、他のユーザでも発生したら困るな。ということで緊急チェック用に作ったものが今回のサンプルです。
調査委したいユーザのメールDBファイル名を入力すると、所有者名称を表示してくれるというものです。
ユーザに確認すれば良いのですが、手順を教えるのもなかなか面倒(別の原因かもしれない)なので、こういったもので作業を簡略化していました。

ただし、調査したいユーザが、自分のカレンダーを公開しておく必要があります。

------------------------------------------------------------------------------
Sub Click(Source As Button)
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim res As String

res = Inputbox ( "調査する人のメールDBファイル名を入力してください。", "調査する人のメールDBファイル名", "" )
If res = "" Then
Messagebox "入力されていませんので、処理を中断します。", 0, "調査する人のメールDBファイル名"
Exit Sub
End If

Set db = New NotesDatabase( "EFMIYOSV/EFMIYO", res )
If db.IsOpen = False Then
Messagebox "DBファイル名が誤っています。処理を中断します。", 0, "メールDBの所有者を調べる"
Exit Sub
End If

'カレンダープロフィール文書を取得する
Set doc = db.GetProfileDocument( "CalendarProfile" )

If doc Is Nothing Then
Messagebox "このメールDBはカレンダーが公開されていません。", 0 + 16, "メールDBの所有者を調べる"
Else
'カレンダープロフィールの所有者欄を表示する
Messagebox "このメールDBの所有者は" & doc.Owner(0) & "になっています。", 0, "メールDBの所有者を調べる"
End If
End Sub



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

2009年5月14日木曜日

配列をサブルーチンに渡す

当たり前と言えば当たり前のことだけど、書いておきます。

自分でサブルーチンを作成して、そのサブルーチンを呼ぶ際に、引数を設定して、渡すことが可能なのは知っているかと思う。

引数には、普通の変数だけでなく、配列も渡せるというだけのことである。


サンプルは、aという配列の変数をSub2というサブルーチンに渡して、その中身を表示しているだけである。
サンプルでは、引数は、a()として渡しているが、aとしても構わない。
ただし、サブルーチンの方はa()としておかないといけない。

同じような分類の複数の値を渡すときは、配列にしておくとすっきりするかもしれない。
試してみて欲しい。

---------------------------------------------------------------------
Sub Click(Source As Button)
Dim a(2) As String

a(0)="りんご"
a(1)="イチゴ"
a(2)="マンゴー"

Call Sub2(a())
End Sub

Sub Sub2(a As Variant)
Dim i As Integer
Dim msg As String

i = 1
msg = ""
Forall x In a
msg = msg & Cstr(i) & "番目" & x &Chr$(10)
i=i+1
End Forall

Msgbox msg, MB_OK, "配列の内容"
End Sub

<サンプルの実行結果>



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

2009年5月13日水曜日

このブログの訪問者って?

このブログでは、色々なアクセス解析ツールを置いています。
筆者は、ブログをやるのは初めてだったので、面白くてついつい置いてました。
本当は、アクセス解析の結果を業務に活かしたいところなのですが・・・

さて、このアクセス解析ツールの中に、なかのひとというのがあります。

筆者のブログにアクセスしてくる年代が調査できるので、確認してみました。
(性別の比率も分かるそうだが、このブログではまだ算出できませんでした)


・・・筆者のブログは、当然Lotus Notes/Dominoに関するものなので、20未満はないだろう。とは予想していましたが、まさか40前後(筆者の実年齢ですな)がピークとは思いませんでした。
やっぱりノーツはおじさんやおばさん(失礼!)にしか人気がないのでしょうか。
ちょっと悲しいですね。

もっと若い人にもノーツを広めていかないといけないですね。

データベースのオープン

データベースのオープンについてです。
今更な感じはしますが、初めてLotusScriptを記述すると言う方もいるかもしれませんので。

通常、LotusScriptでノーツDBを取得すると、自動でオープンされた状態になっています。
よく使うのが、
Set curdb = NotesSession.CurrentDatabase
ですね。
これは、現在、アクセスしているNotes DBをオープンするというものです。

ですが、NotesDbDirectoryクラスを使ってNotes DBを取得した場合、そのNotes DBは閉じられた状態になっています。
この場合、Notes DBは明示的にオープンする必要があります。
それには、NotesDatabaseクラスのOpenメソッドを利用します。


サンプルは、Notes DBを指定せずにNotesDatabaseオブジェクトを作成(このとき、NotesDatabaseオブジェクトは閉じたままです)した後、そのオブジェクトをオープンする際に、Notes DBファイル名を指定するというものです。
ここで、注意して欲しいのは、
Set db = New NotesDatabase("","names.nsf")
としてしまうと、このdbオブジェクトはオープンされてしまい、Openメソッドを利用すると
実行エラーになってしまうと言うことです。

------------------------------------------------------------
Sub Click(Source As Button)
'指定したデータベースをオープンする
Dim db As NotesDatabase

'ここでいうNewとは、スクリプトでこれから使用するという宣言である
Set db = New NotesDatabase("","")
Call db.Open("","names.nsf")

'データベースのタイトルを表示する
Messagebox db.Title, 0, "データベースのタイトル"
End Sub


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

2009年5月11日月曜日

でかっ!

今回はLotus Notes/Dominoには一切関係ありません。
期待していた方々、ごめんなさい。

最近、週末は自宅で仕事をしており、疲れていました。
そんな私を気遣ってくれたのか、嫁様がお茶しに行こうと誘ってくれました。

場所は埼玉県の某市にある珈琲屋です。
嫁様は、店に入る前に「絶対に周りのテーブルを見ないこと!」と釘を刺されて、おそるおそる店内に入り、注文したのが下の画像・・・


普通に「アイスティー」を注文したんですよ。
なんでしょう。これ・・・金魚鉢って。

珈琲屋 OBという
結構有名なお店みたいですね。筆者は知りませんでした。



頑張って飲み干しましたが、しばらくはアイスティーはいらないと思った今日この頃です。

2009年5月7日木曜日

SF9(シフトエフナイン)プロジェクトの8.5対応

タイトルを見て、「あっ!」と思った方もいるのではないでしょうか。

そうです。ノーツのフィールドに@関数/@コマンドを記述して、Shift+F9を押すと、それが実行されると言うものですね。(詳しくは、SF9(シフト・エフ・ナイン)プロジェクト 始動!!を参照してください)

この機能、とても便利で、よく使っていたのですが、Lotus Notes 8.5になったら使えなくなっていたんですね。
Eclipseベースになったからかなぁ・・・とあきらめていたのですが。

やり方を見つけました。ヤッタ-!

ずばり。
フィールドに@関数/@コマンドを記述して、
Shift + Ctrl + F9をクリックするのです。
SF9ならぬSCF9ですかね?

ただし、これには条件があります。
1.ノーツのバージョンが8.5であること。
2.フィールドのタイプが「ノーツスタイル」であること。
3.スタンダードモードで起動すること。



ここで、それぞれのフィールドにカーソルを配置して、Shift+Ctrl+F9を押すと・・・



と、計算されます。
しかし、見て分かるように、ネイティブOSスタイル形式のフィールドは計算されていません。

このため、メールの件名では計算ができずに、8.5以降はできなくなったんだと思っていたのでした。

ちなみに、8.5でもベーシックモードの場合は、従来通りにShift + F9が動作します。

また、8.0ではどうかというと・・・
スタンダードモードでも、ノーツスタイルのフィールドならShift + F9が動作します。



さぁ、これからはShift + Ctrl + F9を押して、関数を計算しまくりましょう!!

メンバー内での位置

ゴールデンウィーク。終わっちゃいましたね。今年は長期休暇ということで、週末までお休みの人もいるかもしれませんが・・・
筆者はカレンダー通りの出勤。ということで今日からお仕事です。

さてさて・・・

今日は、ある特定の値がリストの中のどの位置にあるのかを調べるというものです。
自分が作成したリストなんだからどの位置にあるかなんて、最初から分かってるよ!
なんて思いがちですが、そこはノーツなので、何が起きるか分かりません。

実際にサンプルを見てください。
リストの並び順と画面に表示される順番が違います。
どうも、@Prompt([OKCancelList])コマンドはリストを自動でソートしてしまうようです。
これでは、元の並び順が分かりません。

この時、元の位置を把握するのが@Member関数です。
選択したメンバーがリスト内にあれば、その位置を返します。
存在しない場合は、0(ゼロ)を返します。




------------------------------------------------------------------
mval := "メロン":"いちご":"みかん":"すいか":"バナナ":"りんご";

REM {メンバーは自動でソートされるので、元の位置は分からない};
stxt := @Prompt([OkCancelList];"メンバーの選択";"検索したいメンバーを選択してください。";"";mval:"なし":"もも":"ぶどう");

REM {リストから何も選択しないで、[OK]をクリックすると、1が返ってくる};
@If(stxt=1;@Return("");"");

tmp := @Member(stxt;mval);
@If(tmp=0;@Prompt([Ok];"メンバー内での位置";"選択したものはメンバー内にはありませんでした。");@Prompt([Ok];"メンバー内での位置";@Text(tmp)+"番目にありました。"))


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