狠狠撸

狠狠撸Share a Scribd company logo
LotusScript TTiippss aanndd TTeecchhnniiqquueess 
ロータス株式会社、開発本部 
小峯 宏秋
今日のお話
LLoottuussSSccrriipptt のちょっとしたテクニック
文字列の扱い方、日付の扱い方
プラットフォーム依存の机能を使う
スクリプトライブラリの利用
エージェント
RRuunnOOnnsseerrvveerr 
デバッグ
日本語別名
LLoottuussSSccrriipptt 
蔼蔼関数
文字列の扱い方
文字定数
リテラル文字の文字区切り
" "" ((二重引用符)) 
|| || ((縦棒)) 
{{ }} ((中カッコ)) 
文字列の中に区切り文字を使うときは...... 
22回繰り返す 
""これは """" 引用文 """" です。"" 
{{これは {{ 引用文 }}}} です。}} 
または、別の文字区切りを使う 
||これは "" 引用文 "" です。||
利用例 ((11)) 
スクリプト内での式の利用
EEvvaalluuaattee (( ffoorrmmuullaa$$,, [[oobbjjeecctt]] )) 
nnootteessDDaattaabbaassee..SSeeaarrcchh(( ffoorrmmuullaa$$,, 
nnootteessDDaatteeTTiimmee,, mmaaxxDDooccss%% )) 
Dim db As New NotesDatabase( "Server", "sample.nsf" ) 
Dim collection As NotesDocumentCollection 
..... 
formula$ = "Form = ""Project"" ReminderDate = @Today" 
Set collection = db.Search( formula$, NotesDateTime, 0 )
利用例 ((11)) 
スクリプト内での式の利用
EEvvaalluuaattee (( ffoorrmmuullaa$$,, [[oobbjjeecctt]] )) 
nnootteessDDaattaabbaassee..SSeeaarrcchh(( ffoorrmmuullaa$$,, 
nnootteessDDaatteeTTiimmee,, 
mmaaxxDDooccss%% )) 
Dim db As New NotesDatabase( "Server", "sample.nsf" ) 
Dim collection As NotesDocumentCollection 
..... 
formula$ = "Form = ""Project"" ReminderDate = @Today" 
formula$ = {Form = "Project" ReminderDate = @Today} 
Set collection = db.Search( formula$, NotesDateTime, 0 )
文字定数 ((22)) 
|| ((縦棒)) や {{ }} ((中カッコ)) には複数行の文字
列が書ける
"" ((二重引用符)) でもできますが...... 
ファイル出力などで問題が出るかも
msgtext$ = "文書の情報" & Chr$(10) & _ 
"作成者 = " & authorName$ & Chr$(10) & _ 
"作成日 = " & creationDate$ & Chr$(10) & _ 
"文書タイトル = " & subject$
利用例 ((22)) 
フォーマットした文字列の出力
Sub Click(Source As Button) 
... 
msgtext$ = |文書の情報 
作成者 = | & authorName$ & | 
作成日 = | & creationDate$ & | 
文書タイトル = | & subject$ & | 
"OK" ボタンを押してください。 
処理を続行します。| 
Messagebox msgtext$ 
End Sub 
文書の情報 
作成者 = Hiroaki Komine 
作成日 = 00/10/25 
文書タイトル = 原稿 
"OK" ボタンを押してください。 
処理を続行します。 
OK
文字列の演算
""++"" それとも ""&&"" を使うべきか
演算子によって結果が違う......?????? 
&& ...... 22つのを文字列を連結
オペランドが数値なら、まず文字に変換
+ ...... はオペランドによって動きが変わる !!!! 
オペランドがどちらも数値なら加算
どちらも文字列なら連結
文字列の演算 ((22)) 
もしオペランドが数値と文字列だったら 
vvaarr11==55,, vvaarr22==""112233"" 
vvaarr11 ++ vvaarr22 == ?????? 
結果は
あるときは ""55112233"" 
またあるときは 112288 
不安定な結果を生まないために
文字列の連結には ""&&"" を使う
数値計算では明示的にデータ型の変換
を 
CCiinntt,, CCllnngg,, CCssnngg,, CCddbbll
文字列の演算 ((33)) 
Dim num1 As Integer 
Dim num2 As Variant 
Dim st As String 
num1 = 5 
num2 = 5 
st = "123" 
Messagebox num1 + num2 ' 10 
Messagebox num1 & num2 ' "55" 
Messagebox num1 & st ' "5123" 
Messagebox num2 & st ' "5123" 
Messagebox num1 + st ' 128 
Messagebox num2 + st ' "5123"
文字演算の関数
LLeefftt,, RRiigghhtt,, MMiidd,, LLeenn,, IInnSSttrr 
目的に応じて44種類
LLeefftt -- 文字数
LLeeffttBB -- ユニコードバイト数
LLeeffttBBPP -- プラットフォーム数
LLeeffttCC -- 表示上の文字数 
-- RR55 からの新関数
文字演算の関数 ((22)) 
Left("ABCあいうえお", 6) => "ABCあいう" 
LeftB("ABCあいうえお", 6) => "ABC" 
LeftBP("ABCあいうえお", 6) => "ABCあ" 
LeftC("ABCあいうえお", 6) => "ABCあいう"
文字演算の関数 ((33)) 
LLeeffttBB vv..ss.. LLeeffttBBPP 
BBPP はプラットフォーム依存のバイト 
VViissuuaall BBAASSIICC の LLeeffttBB と互換
しかし、動きはプラットフォーム依存 
((ノーツ//ドミノにはお薦めしません!!)) 
LLeeffttCC 
RR55 の新しい関数
CC はカラム ((CCoolluummnn)) -- 表示上の文字数
タイ語やインド語のための関数
パフォーマンス......
同じく日付//時刻の演算
日付?時刻の内部形式は DDoouubbllee の浮動小
数点数
データ宣言には VVaarriiaanntt 
MMssggBBooxx 関数やデバッガでは SSttrriinngg に自動
変換
フォーマットは OOSS の設定に依存
OOSS:: コントロールパネル→→地域設定
日付?時刻の加減算
Sub Click(Source As Button) 
Dim vdate As Variant 
Dim ival As Integer 
vdate = Today 
ival = 5 
Messagebox "vdata + ival = " & Cstr(vdate + ival) 
Messagebox "vdata - ival = " & Cstr(vdate - ival) 
End Sub 
5日進める 
5日遅らせる
日付?時刻の加減算 ((22)) 
デモ
日付の加減算
時刻の加減算
同じく日付//時刻の演算 ((22)) 
SSttrriinngg を使うと日付が変わる......???? 
日付?時刻の受渡しには SSttrriinngg 変数は使
わない
特に和暦のときに注意 
1122年 ?? 平成1122年 oorr 西暦22001122年 ?????? 
日付?時刻へのデータ変換には CCddaatt 
DDaatteeVVaalluuee//TTiimmeeVVaalluuee に注意
日付?時刻の変数 (1) 
Variant (Double) 
日付?時刻の変数 (2) 
Variant (Double) 
DateValue() 
String 
CDat()
SSttrriinngg を使ったときの問題
Dim vDate As Variant 
Dim sDate As String 
vDate = Today 
sDate = Today 
コントロールパネル/地域設定 
和暦 - y/m/d 
平成12年10月9日 
Messagebox "vDate = "& vdate ' 12/10/25 
Messagebox "sDate = "& sdate ' 12/10/25 
Messagebox "CDat(vDate) = " & Cdat(vdate) ' 12/10/25 
Messagebox "CDat(sDate) = " & Cdat(sdate) ' 24/10/25 
Messagebox "DateValue(vDate) = " & Datevalue(vdate) ' 24/10/25
日付?時刻定数は ?? 
日付?時刻を文字列で定義しない
文字列の解釈は OOSS の設定に依存
年月日の並び
元号の解釈
日付?時刻を埋め込むときは...... 
DDaatteeNNuummbbeerr // TTiimmeeNNuummbbeerr 
Dim dt As Variant 
dt = DateNumber (1969,7,20) + TimeNumber (20,17,40) 
西暦1969年7月20日 
午後8時17分40秒
プラットフォーム依存の机能を使う
プラットフォーム依存の机能を使う
ロータススクリプトはマルチプラットフォーム
対応
コンパイルされたスクリプトは複製される
もしプラットフォームに依存する機能を使
うなら .......... 
たとえば
IIMMEE 関連関数
ファイル操作関数
WWiinn3322 AAPPII コール
LLSSXX
プラットフォーム依存の机能を使う ((22)) 
IIssDDeeffiinneedd 関数 -- ランタイム関数
実行時にプラットフォーム情報を取得
プラットフォーム識別定数はデザイナーヘ
ルプの %%iiff の項目に記載
LLIINNUUXX -- RR55..0022 より
WWIINN9988//WWIINN22KK -- RR55..0033 より
ノーツ//ドミノのスクリプトはコンパイルされ
た中間コードが複製されるので、%%iiff でコン
パイル時の切り替えはできない
プラットフォーム依存の机能を使う ((33)) 
Sub Click(Source As Button) 
Dim cdrive As String 
Dim cdir As String 
If (isdefined("WIN32")) Then 
cdrive$ = Curdrive$() 
Else 
If (isdefined("MAC")) Then 
cdir$ = Curdrive$() 
cdrive$ = Left$(cdir$, Instr(1, Dir$, ":")) 
End If 
End If 
Messagebox ("ドライブ名 : " & cdrive$) 
End Sub
LLSSXX ロードの問題
LLSSXX -- LLoottuussSSccrriipptt eeXXtteennssiioonn 
CC//CC++++ で作成されるユーザー定義のクラス
CC//CC++++ のアプリケーションモジュール ((..ddllll 
oorr ..ssoo)) でノーツプログラムディレクトリに提供
モジュールは OOSS 毎にビルド
ノーツデータベースとともに複製されない
スクリプトは複製されるので
スクリプト実行開始時にロードしようとする
OONN EERRRROORR では処理できない 
-- ""UUsseellssxx eerrrroorr""
オプショナル LLSSXX 
NNootteess RR55..0033 からの新機能
UUSSEELLSSXX ""??YYoouurrLLssxx"" 
LLSSXX モジュールがなくとも、元のスクリプト
は実行可能
LLSSXX 内のクラス//関数が呼ばれたときに
実行時エラー
EErrrrUUnnkknnoowwnnCCllaassssIIdd((223300)) 
EErrrrEErrrroorriinnLLooaaddiinnggDDllll((4488))
スクリプトライブラリの利用
スクリプトライブラリ
ノーツの設計要素の一つ
いろいろな設計要素から呼び出せる
エージェント、フォーム、ボタン
他のスクリプトライブラリ
ユーザー定義の関数やサブルーチンのセット
たとえば...... 
ソートや検索
高度な文字列比較
ビット演算
スクリプトライブラリ -- 使い方
作成
ドミノデザイナー
[作成]] -- [[設計]] -- [[スクリプトライブラリ]] 
関数やサブルーチンの作成
ライブラリ名を付けて保存
呼出し
スタッティック ((普通の呼出し方)) 
((OOppttiioonnss)) セクションで
UUssee ""lliibbrraarryy__nnaammee"" 
ダイナミック
EExxeeccuuttee || UUssee ""lliibbrraarryy__nnaammee"" ...... ||
スクリプトライブラリ -- スタティック
プログラムの保存時
参照されたすべてのスクリプトライブラリがロード
呼出し元スクリプトのコンパイルのために参照
SSuubb,, FFuunnccttiioonnss,, CCoonnsstt,, TTyyppee,, CCllaassss 
ライブラリに問題があれば、コンパイルエラーを
表示してコンパイル中止
スクリプトライブラリ -- スタティック ((22)) 
プログラム実行時
参照されるクリプトライブラリがロード
すべてのライブラリが正しくロードされなく
てはならない
すべての外部参照を検証
SSuubb,, FFuunnccttiioonn ...... 
エラーがあれば実行されない
スクリプトライブラリ -- ダイナミック
UUssee 文と処理内容を文字列としてを 
EExxeeccuuttee に渡す
if condition=True then 
Execute | Use "MyLibrary" 
Call MySub ( ... ) 
val = MyFunc( ...) | 
Else 
... 
End If
スクリプトライブライブラリ -- ダイナミック
必要なときに必要なライブラリがロードされる
注意!! 
保存時のコンパイルチェックはされない
利点
不要なライブラリはロードされない
再起呼出しのチェックもパス
Main 
Sub01 Sub02
スクリプトライブライブラリ -- ダイナミック
便利ですが......制限があります
コンパイルエラーは実行時に発生
デバッグできない
実行時にコンパイルされ、終了後に
ただちに捨てられる 
?? パフォーマンスは悪い
スクリプトライブラリで良くある問題
スクリプトライブラリの定数
定数は呼出し元のオブジェクトに保存される
呼出しもとの再コンパイル忘れ
AAとBBがスクリプトライブラリCCを利用
CCを編集してAAを再コンパイル
BBはそのままで、実行時エラー
NNootteess UUII クラスの使用
開発::クライアント側
運用::サーバエージェント
エージェント利用とデバッグ
リモートエージェント
NNootteessAAggeenntt..RRuunnOOnnSSeerrvveerr -- RR44..6622 から
分散環境でのスクリプトの実行
重い作業、特殊な作業での
エージェントの利用
クライアント//サーバーモデル
ノーツIIDDによるデータ交換 -- RR55..0022 から
リモートエージェントの呼出し例
Set agent = db.GetAgent("LoadEmployeeAgent") 
Set doc = db.CreateDocument 
Set item = doc.AppendItemValue("HR_ID", hr_id) 
Call doc.save(True, False) 
paramDocID = doc.NoteID 
Call Agent.RunOnServer(ParamID) 
データ交換する文書の 
ノーツ ID 
Delete doc
リモートエージェントのコード例
Set agent = session.CurrentAgent 
' データ受け渡し用の文書 ID を取得 
NotesID$ = agent.ParameterDocID 
' 文書のデータを参照 
Set doc = db.GetDocumentById(NotesID$) 
Set item = doc.GetFirstItem("HR_ID") 
hr_id = item.text 
...
リモートエージェントのコード例 ((22)) 
' サーバーでの処理を実行 
' - ノーツデータベースの検索 
' - SQL コマンドの実行 
' などなど 
Set item = doc.AppendItemValue("FirstName", FIRST) 
Set item = doc.AppendItemValue("LastName", LAST) 
Set item = doc.AppendItemValue("Division", DIVISION) 
Call doc.save(True, True)
呼出しコードの注意
バックエンドで文書が更新される
スクリプトで保持している文書オブジェクト
は古くなっている
' 呼出し元コードのつづき 
' 既存の文書オブジェクトは削除 
Delete Doc 
' 文書オブジェクトの再取得 
Set doc = db.GetDocumentByID(ParamDocID) 
FIRST = doc.GetItemValue("FirstName")
スクリプトデバッグのヒント
スクリプトアプリケーションの実行時の情報
をどのようにとるか?? 
たとえば...... 
作成したアプリケーションがスクリプトエラー
を起こしている...... 
しかし、その関数がどのように呼ばれてい
るかわからない......
スクリプトのデバッグのヒント ((22)) 
GGeettTThhrreeaaddIInnffoo -- RR55 からの新しい関数
例 
%Include "lsprcval.lss" 
GetThreadInfo ( LSI_THREAD_VERSION) 
ロータススクリプトのバージョンを文字列で返す 
"4.0.0.21"
GGeettTThhrreeaaddIInnffoo のパラメータ
ID 意味 
LSI_THREAD_LINE 現在の行番号 
LSI_THREAD_PROC 現在のプロシージャの名前 
LSI_THREAD_MODULE 現在のモジュールの名前 
LSI_THREAD_VERSION ロータス スクリプトのバージョン番 
号 
LSI_THREAD_LANGUAGE 各国語設定 
LSI_THREAD_COUNTRY 国別設定 
LSI_THREAD_TICKS 国別設定 
LSI_THREAD_TICKS_PER_SEC 秒ごとのクロックの刻みを取得
日本语别名の使用
日本語別名
日本語別名の処理のための拡張
NNootteessSSeessssiioonn..UUsseerrNNaammee 
←← ユーザー名 ((基本名のみ)) 
NNootteessSSeessssiioonn..UUsseerrNNaammeeLLiisstt 
←← NNootteessNNaammee クラスのリスト 
UUsseerrNNaammeeLLiisstt((00)) -- 基本名
UUsseerrNNaammeeLLiisstt((11)) -- ((日本語))別名
日本語別名処理のコード例
Dim session as new NotesSession 
Dim namelist as variant 
Dim nname as NotesName 
namelist = session.UserNameList 
forall nname in namelist 
print "Common name =" & nname.common 
print "Language =" & nname.language 
end forall
@@関数での日本語別名の処理
ユーザ名と言語情報
@UUsseerrNNaammee((11)) -- ユーザーの日本語別名
@UUsseerrNNaammeeLLaanngguuaaggee((11)) -- 別名の言語 
日本語なら ""jjaa"" 
言語タグの文字列への変換
@LLooccaallee 
@Locale ([LocaleName]; "ja-JP") ? "日本語(日本)" 
@Locale ([LanguageName]; "ja-JP") ? "日本語" 
@Locale ([CountryName]; "ja-JP") ? "日本"
@@関数での日本語別名の処理
他のユーザの別名((基本名))の検索
@NNaammeeLLooookkuupp 
ドミノディレクトリを検索する。
@NameLookup([Exhaustive];"Hiroaki Komine/TYO/Lotus"; 
"AltFullName") 
? "小峯 宏秋/東京/ロータス"
NNeexxtt RReelleeaassee での計画
コア機能の追加
データタイプの追加 -- BBYYTTEE//BBOOOOLLEEAANN 
ビルトイン関数の追加
JJaavvaa オブジェクトの参照
外部オブジェクトとの接続
JJSSPP との統合
SSOOAAPP 
リモート?デバッグ
データベース?リコンパイル

More Related Content

Lotus DEvCon 2000 - LotusScript Tips and Techniques