2009年11月30日月曜日

ビューの選択式で日付関数を使う


What's New のようなビューでは @Today や @Now といった日付関数を使うことがあります。

その場合はビューの利用頻度や文書数を考慮することが必要です。

特に使用頻度が高いDBで日付関数を使ったビューをトップ画面で必ず表示するといった場合、誰かがトップ画面を開くたびにサーバー側で行われるビューの再構築によりアクセス遅延が発生するなどパフォーマンスに大きく影響することがあります。

下手すると多くのユーザーへ一斉にデータベースリンクを付けたメールを送付した直後に「DBが開かない」といった電話がジャンジャン鳴り、こうなると不具合調査どころの騒ぎではありません...

ただしクレームが多いからといって便利なビューの使用をやめてしまうのは避けるべきです。

日付関数に変わる方法として @ToTime("Today") がよく例として挙げられます。

こうするとNotesを騙すことができるわけです。

ただこのように変更した場合、新規文書はビュー索引にきちんと追加されるのですが、期限を過ぎた文書がビュー索引から消えないといった不具合が発生することがあります。
この不具合を解消するには、ドミノディレクトリのプログラム文書を利用してビューを再構築するコマンド(updall -r -t )を発行するといった対応が必要になります。

下記のリンクには日付ビューを使う場合の考慮点などが分かりやすく掲載されています。

(参考)Lotus Notes の時刻/日付ビューのオプション
(参考)Notes ビュー索引の更新に関する基本
http://www-06.ibm.com/jp/domino04/lotus/support/faqs/faqs.nsf/all/731830

2009年11月29日日曜日

競合文書は一人で作れる


Notes/Dominoの特徴のひとつである競合文書は、複数のユーザーが同時期に同一文書を編集するなどの操作によって作成されます。

そもそもNotes/Dominoではレプリカといった機能がある関係からか厳密な排他制御は期待できません。云わば「お気楽な排他制御」ですね。
(というとお叱りをうけそうですが...)

そのため一つの文書を皆で編集するような仕様のアプリケーションの場合は「競合文書の削除」が定形業務になっていたりします。

でも、文書の作成者だけがその文書を編集できる仕様のアプリケーションでも競合文書ができることが時々あるのです。

実は次の3つの手順を踏むことで簡単に競合文書を作成できてしまいます。

1. ビューで競合文書にしたい文書を選択してEnterあるいはダブルクリックで開きます。これを表示モードのまま開いておきます。
2. ビューへ戻り、競合文書にしたい文書を選択した状態で Ctrl + E を押して編集モードで開き、保存して閉じます。
3. 1で開いておいた文書へ戻り、編集モードにして、編集、保存します。

3で保存するとき、メッセージ「編集しているときに文書のコピーが保存されています。競合文書として保存しますか?」が表示されますから[はい]をクリックします。

「知らない間に競合文書ができている」と言われることが時々ありますが、実は前出のメッセージがよくわからずに[はい]を押しちゃう人も多いようですね。

2009年11月27日金曜日

レプリカを一括で作るには


一度にたくさんのDBを検証環境や新規サーバーへ持っていきたい、といった要望はときどきあります。
このような時にNotesのレプリカを利用すると、サーバー稼働中でも比較的安全に持っていくことができます。

今回紹介するのは新規のローカルDBにフォームとアクションボタンをひとつ作るだけの簡単設計です。

フォームには、持っていきたいDBのファイルパスを入力するための複数値可のテキストフィールド "targetlist" と、下のLotus Scriptを実行するアクションボタンを作成します。
Dim ws As New NotesUIWorkspace
Dim ss As New NotesSession
Dim db As NotesDatabase, rep As NotesDatabase
Dim doc As NotesDocument

Set doc = ws.CurrentDocument.Document
If doc Is Nothing Then Exit Sub
On Error Resume Next

Forall target In doc.targetlist
 Set db = ss.GetDatabase("SERVERNAME/ORG/JP", target)
 Set rep = db.CreateReplica("", |sample\\| & target)
 If rep Is Nothing Then
  Print Cstr(target) & "...NG"
 Else
  Print Cstr(target) & "...OK" & " 「" & rep.Title & "」"
  Set rep = Nothing
 End If
End Forall
Print "処理終了"

上のLotus Scriptを実行すると、レプリカをローカルの "sample" フォルダ内へ作成します。

例として "targetlist" フィールドへ次のように入力した場合、
help\help65_admin.nsf
prod\phonebook.nsf
names.nsf

ローカルPCへ作成したレプリカのファイルパスは次のようになります。
sample\help\help65_admin.nsf
sample\prod\phonebook.nsf
sample\names.nsf


もしレプリカの作成先としてローカルPCの外付けHDDを指定したい場合、Notes\Dataフォルダへ予めディレクトリリンク"sample.dir"を作成するなどして、異なるドライブへ直接書き込めるよう工夫することもできますね。

この"sample.dir" とは「X:\SAMPLE (※Xドライブは外付けHDDのドライブレター)」とだけ書かれた(テキストエディタで編集できる)ファイルで、SAMPLE ディレクトリとして見せたい実態(ドライブとフォルダ)を指し示します。

なお、アクセス権が無いなどできちんとレプリカが作成されないとつまらないので、Domino Administrator でフルアクセスアドミニストレータ権限を有効にしておくのがお勧めです。

また、状況は Print でステータスバーに表示していますが、ステータスバーの情報をローカルのログ(log.nsf)へ残すようnotes.iniへ次の2行を加えておくと、後で確認しやすいと思います。
LogStatusBar=1
Console_Log_Enabled=1
状況の記録は Print でなくてもいいと思います。

2009年11月26日木曜日

Error locating a Domino Directory entry for certifier /O=ORG/C=JP


サーバー再起動を境に次のメッセージが昼夜を問わず日に数回、ログ(log.nsf)に記録されるようになりました。

Error locating a Domino Directory entry for certifier /O=ORG/C=JP: エントリが索引に見つかりません

メールとアプリケーションはドメインを分けて設置している環境であり、アプリケーションドメインではディレクトリアシスタンスを利用して二次ディレクトリとしてメールドメインのドミノディレクトリを指定してある。

前出のメッセージはアプリケーションのドメインにあるサーバーで記録された。

そこでメールドメインのドミノディレクトリにあるCertifier(Notes認証者)文書 "ORG/JP" をアプリケーションドメインのドミノディレクトリへコピーしてみたところ、それ以後記録されなくなった。

どうして再起動前まで発生しなかったのか、なにが起こったときにCertifier文書が参照されたのか、1日の利用者は数百人なのにどうして時々しか発生しなかったのか....謎はまだ残る...

2009年11月25日水曜日

テキストフィールドの32KB制限で文書が保存できない


フォーム上に表示用の計算結果として設置している非表示のフィールドがあり、その式に @DbColumn を利用してビューから値のリストを抽出するアプリケーションがありました。

@DbColumn により抽出するテキストのサイズは、設計当初は数KB程度と見積もっていたのですが、とうとうオーバーフローしてしまったようで、フォームを保存するときに次のメッセージが表示され保存できなくなったと報告がありました。

Only plain text can be used in this type of field.

(利用者が外国人のため英語です)

上記メッセージにOKボタンを押してもどのフィールドにもカーソルが移動しないのでドキドキしましたが、すべての非表示フィールドを表示してみたところ、テキストサイズがやたら大きいのでメモ帳へコピペして保存したところサイズが32KB付近まで膨れ上がっていました。

そこで @DbColumn の式を削除して "" としてみたところ、メッセージが表示されずに保存できるようになりました。

上記はテキストフィールドのサイズ制限に起因する不具合でしたが、メッセージがとてもわかりづらかったです。


ところで @DbColumn や @DbLookup はフォームを開くときに式を評価するため、パフォーマンスが悪くなりやすいのをご存じでしょうか。

このフォームにはコード選択用のダイアログボックス・フィールドが10個あり、どのフィールドも同じキーワードリストから1つだけ選択させるのですが、このキーワードリストの値を導き出すための式として前出の表示用の計算結果フィールド名を設定しています。

こうすることで @DbColumn を多用しない工夫をしていました。

この不具合が発覚したため、結局のところ10個の @DbColumn を書くハメになりました。

トホホ

2009年11月24日火曜日

半角英数字以外の文字が入力されたらエラーにする

テキストフィールドにおいて半角英数字以外をエラーとする場合、フィールドの「入力の確認」へ次の式を設定します。

@If(@Matches(@ThisValue; "+{a-zA-Z0-9}"); @Success; @Failure("エラーです"))

半角英数字と半角記号の場合半角カナを含む場合などはこちらを参照してください。

2009年11月19日木曜日

懇談室よいとこ、一度はおいで

Lotus Notes には R4.6J が出る少し前から関わっていますので、もう12年も触っていることになります。

この12年で得られたノウハウが少しでも誰かの役に立てばいいなと思うし、やっぱりわかんない事は誰かに相談したいと考えて、ときどき訪問するサイトがあります。

ドミノ懇談室

日々の投稿数はさびしい感じがしなくもないですが、システムが安定していることの裏がえしですかね。

手順と質問の仕方を誤らなければ多くの経験者から的確なアドバイスがもらえます。
ただし「すぐに」という保証はありません。
ですが困っているときなどはすごく救われた気分になれます。

過去の質問と返答を見ると事象が似ているものがあったりするので、質問する前には必ず検索したいですね。

質問する場合のコツは、とにかく詳しく書くこと。
大雑把な質問だと期待した回答がすぐに得られないかもしれません。

事の経緯や現象、何がしたいか、どうなってほしいか、どんなコードを書いたらどんなエラーがどこに出たとか、どんなキーワードで検索したといったことでもいいと思います。

返答する側が答えやすいよう質問する側も工夫したいですね。