VBAでLotus NotesのDB内ビュー全データを引き抜く

以前、NotesのNSFファイルからEML変換してOutlookへ突っ込むプログラムをAccessで作成しました。同様にNotes内のアプリで使ってるデータベース内のビューで表示されてるデータを引っこ抜く必要があった為に、ウェブ上の情報を元に構築してみました。

その内容はメール変換同様にNotesのCOMを使ってDBに接続し、Lotus Scriptで引き抜くコードがそのまま利用できる感じです。今回はExcelで作成し64bitコードで記述してあります。

Lotus NotesのメールをOutlookに変換して移行する

今回使用するファイル

今回はDBと繋がってるビューのデータを引き抜いています。処理はリボンにメニューを作って使いやすく仕立ててあります。

※2023年8月23日、リッチテキストフィールドのデータ、添付ファイル、Wordへの変換ができるようになりました

ExcelとAccessに独自のリボンを追加する

事前準備

サーバー・DB情報を用意する

このアプリを使う為に必要なNotesサーバの情報とデータを引っこ抜く対象のDBファイル名が必要です。

  • Dominoxxxx/hogeというドミノサーバの名前が必要になります。
  • hogehoge.nsfというファイル名が必要です。データを引き抜きたいアプリ等に連結されてるハズです(Notes Administratorなどでは簡単に見つかります)

これらの情報を次項のセットアップで入力する必要があります。

※nsfについて、リッチテキストフィールドの引き抜きはdbディレクトリ以下に対象のnsfファイルがいることが前提になります。(前述の場合はnsfも他のディレクトリにいる場合には例えば、db\hoge.nsfといった指定が必要です。)

セットアップ

ダウンロードしたExcelを開き、以下の手順でサーバー名とDB名を登録します。

  1. リボンにNotesというタブがあるので開く

  2. 設定をクリックする

  3. 設定ダイアログが出るので、サーバー名とDB名を指定して保存をクリック

Excelファイルと同じ場所にsetting.iniというファイルに設定が書き込まれます。

図:独自のリボンをつけてあります

図:ダイアログにサーバ名とDBファイル名を入れる

アプリの仕様

NotesのDBには様々なビューが含まれていますが、ユーザが作成したものでは無い管理用のビューなども含まれています。このアプリでは()から始まる管理用のビューについては処理をスルーするようにしています。

また、ビューの名前でシートを生成するようにしていますが、¥マークについてはシート名に使えないのでアンダーバーで代替しています。また、一度取得したのち再度実行すると、シートが既に作成済みということでエラーとなるので、作成されたシートを全削除してから利用する必要があります。

使い方とソースコード

使い方

利用方法は簡単です。前述の設定が完了していれば、「データ取得」ボタンを実行するだけです。ビューの数だけシートが生成されて、ビューの中のデータを引き抜きます。タイトル行などは自動で取得してセットされます。よって、サーバとDBだけ変更すれば汎用的にデータを引き抜くことが可能です。

処理中は左下のステータスバーに進捗率が表示されるようになっています。Notes接続時にはパスワード入力欄が出てきますので、パスワードを入れるとデータ取得開始です。

VBA警告が出ている場合実行許可をしてあげる必要があります。

図:ログインダイアログが出てくる

コードと解説

参照設定

遅延バインディングだと、コード補完が効かないので、今回は参照設定から「Lotus Domino Objects」を追加しています。これがないと、コードが動きませんので当然ですが、利用するPCではNotesクライアントがインストールされている必要性があります。

図:今回のコードは参照設定を加えています

データを取得するメイン関数

データエクスポートを管理するメインで実行される関数です。後述の関数を随所で呼び出して全体を制御しています。

  • 後述のメソッドでも利用する各種グローバル変数をGeneralプロシージャの中で宣言しておきます。
  • メール移行のプログラムと違い、Lotus.NotesSessionで動かしてるのでCall session.initializeが必要です。また、Call session.initialize(password)とすると自動でログインするようになります。
  • setting.iniからサーバ名とDBファイル名を取得してGetDatabaseで接続しています。
  • NotesViewList関数を実行して、DB内のビューの一覧を配列で取得しています。
  • ループで配列を回し、ビューの名称を取得したらgetNotesViewData関数でシート作成とデータ引き抜きを行っています。
  • 最後にsessionとdbのオブジェクトを開放しています(でないとnotesプロセスが残る可能性がある)

ビューの一覧を取得して配列で返す

前述のメイン関数から呼び出されて、指定のDB内にあるビューの一覧を取得して配列で返す関数です。但し、管理用ビューについては処理をスルーするようにフィルタしています。

  • 動的配列とするため、Redim Preserveで逐一配列を拡張しながらビューの名称を1次元配列で追加しています。
  • 配列で返すために関数の戻り値の型はVariantとしています。

対象DBからデータを引き抜いて書き出す

ビューの名称を元にシートを新規追加し、そこにタイトル行とビューの実際のデータを書き出す関数です。

  • データが無いビューの場合は処理をスルーしています
  • ビュー名に於いてシート名に使えない文字はアンダーバーにreplaceさせています。
  • 列見出しを作成した後、2行目以降からentry.ColumnValuesにて列のデータを書き出しています。
  • ステータスバーに進捗率の値を表示させています。
  • 最後に処理が終わったらメイン関数に戻し、次のビューの処理を行っていきます。

リッチテキストフィールドの引き抜き

いわゆるNotes文書と呼ばれるリッチテキストな内容で、添付ファイルなどが付いてるような1つ1つのページのデータで、テキストデータだけをrichtextシートに一気に書き出します。本体自体はRTF形式でのエクスポートも出来るのですがメソッドは存在しないようで、後述のWord変換を利用して取得可能です。。

リボンのリッチテキスト取得を実行すると抜き出しが出来ます。

  • db以下に対象のnsfファイルがいることが前提です。
  • 引き抜いたデータはテキスト形式で、richtextシートにID, タイトル, カテゴリ, 投稿日, 最終更新日, 本文で書き出します。
  • 文書内の添付ファイルの取り出しは未実装です。

リッチテキストの添付ファイルを取り出す

前述のリッチテキストフィールドのデータには、ExcelやWordといった添付ファイルが付いてる場合があります。これらはバイナリデータであるため、前述のテキスト抜き出しでは取得されることがありません。それでは困るので、1ドキュメントのテキストを抜いた後にこのバイナリデータを取り出すコードを追加し、attachmentシートにuniversalidを元にデータを書き出しするコードを追加します。

あとはPowerQuery等を利用すればrichtextシートとuidを基準に連結する事が可能です。以下は前述の「ドキュメント本文を取得する」に追記するコードになります。

  • このVBAファイルがある場所にtempというディレクトリを作って添付ファイルの解凍先として指定してる(destDrive)
  • GetFirstItemにてBodyを取得した後に、EmbeddedObjectsにて添付ファイルの配列を取得する事が可能です
  • doc.HasEmbeddedにて添付ファイルがあるかどうかを判定可能です。但し、jpgなどの画像ファイルは添付ファイルとみなされないので取得できません。
  • atfile.typeが1454(EMBEDDED_ATTACHMENT)だったら添付ファイルなので処理を続行する
  • ファイル名が無いものは処理をスルーする
  • 添付ファイルはループで回してExtractFileにて取り出すことが可能。この時、atfile.Nameでファイル名も取得しておいて、カレントディレクトリ内のtempフォルダ内にファイルを生成する
  • 最後にシートにuniversalid、ファイル名、フルパスを記述して完了

Notesのリッチテキストフィールドに添付されてるファイルはとてつもなく古いファイルも残ってる可能性があります。それは古いコンピュータウイルスが潜んでいる可能性もあるため、一部のファイルはウイルスチェッカーに引っかかり動作が阻害されExcelが落ちる場合もありますので要注意。

リッチテキストをWordファイルに変換して出力

Lotus NotesのScriptにはFileExportというものでボタンに割り当てて使うコマンドにてリッチテキストをRTF形式で保存する機能があります。しかし、VBAから叩く場合のメソッドにRTFとして保存する為のものがなく、また前述の方式では添付ファイルとして画像の取り出しも出来ません。

そこで、Lotus NotesのUI自体を操縦して、リッチテキストをクリップボード経由でWordファイルにコピペし連続保存する方式が確立できました。前述までのNotessessionとして行う方法ではなく、Notes自体を起動して行いますので、ファイル生成中はPCは弄ってはいけません(またクリップボードを何度も書き換えていますので、別の作業でコピペをすると阻害したり、別のものが貼り付けられたりするので要注意)。

初回実行時のみ、確認のダイアログが出るので、「今回のLotus Notesセッションでこのアクションを実行するために署名者を信用する」にチェックを入れてOKをクリックする必要があります。

※文書タイトルにファイル名につけられない環境依存文字がある場合、名前を付けて保存ダイアログが出てしまうことがあるので、その場合はそのまま前述のtempディレクトリを指定してOKをクリックすれば処理が継続されます。コード内だと「fncSheetNameModify関数」に対象の文字を追加することで、これらは空文字に置き換わるので、追加していくとスムーズに処理が行われると思います。

※またNotesが起動していて何かの文書を開いてる状態の場合は必ず全部閉じてから実行が必要です。

図:初回起動だけチェックが必要

  • Notes自体を操縦する場合には「NotesUIWorkspaceクラス」を使うのですが、遅延バインディングでなければ使えないので注意
  • universalidが無いものは処理をスルーするようにしています。
  • 用紙サイズは、wdPaperA3をもってA3サイズを指定してる(A4だと文書の内容によっては、はみ出す場合があるため)
  • 操縦中に「別のプログラムでOLEの操作が完了するまで待機をつづけます」というメッセージが出る場合があるので、これを封じるために「Application.DisplayAlerts = False」を加えています。
  • 同名タイトルの文書対策として、ファイルのタイトルを取得したらカウンタの値をつなげてファイル名としています。
  • Body部分をコピーするには編集モードをTrueにする必要があるので、「ws.EDITDOCUMENT(True, doc2, False)」として有効化しuidocとして取得しています。
  • uidocにてBodyに移動=>全部選択=>コピーしてドキュメントを自動で閉じるようにしています。
  • WordオブジェクトにDocument.addにて新しい文書を追加してコピペ、保存、文書を閉じるを繰り返し作業で行っています。
  • Wordファイルは添付ファイルと同様に、Bookのあるディレクトリ以下のtempディレクトリ内に自動で保存されていき、スプレッドシートのwordfileシートに情報が記述されていきます。
  • fncDeleteStrings関数でSubjectの環境依存文字を除外してファイル名として返します。
  • Notesリンクオブジェクトや、添付ファイルオブジェクトは処理をスルーします。添付ファイルが欲しい場合は前述の機能をご利用ください。

動作はそこまで早くは無いですが、放置しておけば全ドキュメントを回して逐一Word化していきますので、画像も取得可能です。画像の幅があっていないものもありますが、これでほぼNotesのドキュメント類をエクスポートする事が可能です。

関連リンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)