ページビューの合計

ラベル Lotusscript の投稿を表示しています。 すべての投稿を表示
ラベル Lotusscript の投稿を表示しています。 すべての投稿を表示

2023年12月26日火曜日

【 #電帳法対策 】メールの添付ファイルを一気に保存したい

This time I would like to report on the handling of attachments in accordance with the revised Japanese law.

This is a case where you want to save a large number of email attachments received in large quantities to a local location on your computer at one time.


みなさま、こんにちは。

かなり久しぶりになります・・・申し訳ございません。

まずはこの時期気になる #HCLAmbassador について少しだけ・・・。
まだ正式リリースにはなっていませんが、ノミネートしたメンバーへは通知が届いているようです。
詳細は正式リリース後と致しますが、大阪から新任も現れましたので、ぜひ来月のテクてくLotus技術者夜会をご視聴ください。

さて今回はタイトルにも記載しましたが、弊社の電子帳簿保存法(電帳法)の対応で、少しご紹介したい内容が発生しましたので、その内容と解決策をご紹介致します。


【背景】

電帳法の対応として、各取引先から受け取る請求書、納品書の電子化が進みました。
請求書はともかく、納品書は日々かなりの枚数を処理していますが、さらに先方のシステムによっては1点1葉に細分化した例も現れ、1日200本ちかくの添付ファイル付きのメールを受けるような例が複数生じました。

※1点1葉化
従来、単品ごとに消費税を計算していたところが、根本的なシステム変更を行うことなく、単純に請求単位を1点ずつにすることで完了されるような例がありました。

弊社の電帳法対策(検索性)からその添付ファイルをリネームして保存することとなったのですが、ひとつひとつメールを開き、添付ファイルを保存するだけでも相当の労力が必要であり、その部分を改善できないかと考えたのがスタートです。

なお今回の内容ではファイル名の変更は対象としていません。



【改善案】

受信したメールはルールで指定したフォルダに振り分けられているため、対象となるメールを選択してエージェントを実行することで添付ファイルをローカルフォルダに保存する機能をメールテンプレートに追加する。

万が一同名のファイルがあった場合は、後ろに連番を付与して保存する。



【対応】


まずは自力でなんとかできないかと、以前「#期日管理 アプリについて」で作って頂いたスクリプトとにらめっこ。
しかしながら同一ファイル名の処理や、私の理解でできるものではなく・・・

さらに今回案件は1月スタートと期日が皆無のため、最後の砦・・・ノーツコンソーシアム大阪研究会の浜さんへ問い合わせ・・・

すると間もなくしてスクリプトの書かれたテキストファイルが届きました。

少し設定してエージェントを実行すると・・・

おおー、うまくいきました。

こちらの詳細はお手数ですが、浜さんのブログ「リッチテキスト:#15)添付ファイルのダウンロード」で解説頂けておりますので、ご覧ください。



【結果】


180件のメールを選択してエージェントを実行したところ、ほんの数秒で添付ファイルがパソコンの指定フォルダの中に保管されていました。

手作業でひとつずつ保存していくと、その作業時間は小一時間掛かります。

しかしながらこのツールで数秒という飛んでもなく作業時間の短縮につながりました。

担当者からは「感動した」とまで!!

みなさまの会社でもお困りではありませんか?
ぜひ、この恩恵を受けてください!!


2023年6月22日木曜日

#期日管理 アプリについて

 I would like to introduce another finished application for a project that occurred within our company.

It will be a kind of centralized management of task due dates.


みなさま、こんにちは。
今回も弊社内で発生した案件からリリースしたアプリを紹介致します。

【要件】
・社内で管理する必要のある取引先の許可証を一元管理する
・期日が近づいたら、担当者(グループ)にメールで通知する

弊社の例では、医薬品や毒劇物などを販売するには、それぞれ期日の決まった許可を更新する必要があります。
販売先がさらに販売(再販)する場合、その許可を弊社が管理することが法的に定められています。

従来は取引先から提出頂いた許可証のPDFをファイルサーバーに保存。
必要に応じて、「個人のタスク」や「スケジュール」で通知設定を実施していました。
ファイル名に期日を指定し、随時こちらが近づいてくると更新された最新版の提供を依頼するという形でした。

また対象の法律により管理者が複数おり、それぞれ別で管理していたり、営業担当変更や退職で内容が引き継がれなかったりした場合など、万が一の確認もれを防ぐ意味でも、一元化を実施することとなりました。



上記を踏まえ、アプリを作るのですが、基本は簡単なフォームとビュー、メニューやフレームセットだけで終わります。

【フォーム設計画面】

【起動時のフレームセット】


ここでキーになるのが、自動で通知を送信する機能になります。
ちなみに「期日順」ビューは以下のようになっています。

期日昇順で表示されており、切れたものは"タイガースカラー(笑)"になっていることがわかるかと思います。
・・・余談ですが、弊社は重要で目立たせる必要のあるビューの行はこの"タイガースカラー"で統一しています。

通知はエージェントを使用して、スケジュール実行をさせています。
本エージェントは、ノーツコンソーシアム 大阪研究会 の浜さん

にお願いして作って頂いたものになります。


Option Public
Option Declare

Sub Initialize
Dim ns As New NotesSession
Dim ndb As NotesDatabase
Dim nv As NotesView
Dim nd As NotesDocument
Set ndb = ns.Currentdatabase
Set nv = ndb.GetView("LTerm")
nv.Autoupdate = False
Set nd = nv.GetFirstDocument()
While Not (nd Is Nothing)
If CStr(nd.EndDate(0)) <> "" Then
If nd.EndDate(0) - Today <= 7 Then
'期日まで7日以下のものがメール送信対象
Call SendMail(ndb, nd)
End If
End If
Set nd = nv.getnextdocument(nd)
Wend
End Sub


Function SendMail(vndb As NotesDatabase, vnd As NotesDocument)

Dim ndMail As NotesDocument
Dim nrti As NotesRichTextItem
Set ndMail = vndb.CreateDocument
ndMail.Form = "Memo"
ndMail.SendTo = vnd.GetItemValue("Contact")(0)
ndMail.CopyTo = vnd.GetItemValue("Manager")(0)
ndMail.Subject = "許可証等更新日接近のお知らせ"
Set nrti = ndMail.CreateRichTextItem("Body")
Call nrti.AppendText("許可証等の更新時期が近づきました、")
Call nrti.AddNewline(1)
Call nrti.AppendText("期日までに更新してください。")
Call nrti.AddNewline(2)
Call nrti.AppendDocLink(vnd, vndb.Title) '文書リンクつけるなら 
Call ndMail.Send(False)
End Function


スケジュールは以下のように毎週月曜の9:00としてあります。

以上で完成です。
これにより各自のタスクやスケジュールに依存するのではなく、会社としてのルールに従った管理作業が行えることとなりました。

弊社の場合は許可証がトリガーでしたが、期日管理を個人まかせにできないことっていくつかあるのではないでしょうか。

ぜひそのような内容が必要でしたら、本アプリをダウンロードしてご使用ください。
以下よりダウンロード可能です。




2022年12月28日水曜日

#Magic #xpi を介した #Notes / #Domino と #IBMi の連携

Finally, the year is just a few days away.

I recently wrote an article about converting IBMi data to JSON with Magic xpi for use in DominoLeap.
This time, I report that the data is now available in Notes client using Lotusscript.
There were a few things to note in the JSON specification, which I hope will be helpful.

みなさま、こんにちは。
いよいよ今年もあとわずかですね。

早速ですが、先日

#Magic #xpi を介した #DominoVolt ( #DominoLeap ) と #IBMi の連携

という記事で、IBMiにあるデータをMagic xpiを経由することでJSON化して、DominoVolt(DominoLeap)に取得するという内容を紹介しました。

もちろん弊社にとって、要求された内容ではあったのですが、現状ノーツクライアントに依存している環境から、LeapでなくNotes側でも利用したいということは言うまでもありません。

ノーツクライアントでのREST APIについては、

#郵便番号 から #住所 を取得しよう( #鬼わか の #REST #API を適用したサンプル)

こちらの記事で、提供されたサンプルを紹介しましたので、こちらに割り当てていくことで簡単にできるのではと安易に考えていたのです。

ということで、いざ!!
とまずは鬼わかで利用したフォームごとコピーしてきてテストを開始しました。

ここで今更ながら前段・・・
私はLotusscriptをほとんど使用していない、未熟者になります。

そんな私が、鬼わかのコードを読んでいくと、いろいろと丁寧な処理が含まれていることに気づきました。

私なりにその「丁寧な部分」を外していき、シンプルな構成にしていけるだろうと実行してみたのですが結果はNG。

NotesJSONNavigatorにセットしたいのですが、以下エラーが発生しました。

「JSON 文字列を解析できません: Invalid value. offset 0」

デバッガーで見てもわからず、今回もまたサポートの方の手を煩わせることになってしまいました。

まず指摘があったのが、「レスポンスはバイト配列にはなっていない」との事でした。

そこでChromeの開発者ツールを使用して情報提供の依頼があり、対応しました。
ちなみにこの部分については、以下記事を紹介頂きました。

https://support.hcltechsw.com/csm?id=kb_article&sysparm_article=KB0039010

指示されたデータを提出すると、「レスポンスヘッダが、「Content-Type: text/html」となっている」との指摘がありました。
レスポンスヘッダの「Content-Type」に「application/json」をセットしてくださいとの指示を頂きました。

こちらはMagic側の問題と考え、マジックソフト社のサポートへ連絡して指示を仰ぎました。
そもそもJSONとしてデータを取得しているので、デフォルトでそうなっていないのが少し疑問・・・といいますか、先のDominoLeapは解釈してくれてたんだぁ・・・と違和感の残る結果ではありますが、無事サポートの指示により「Content-Type=pplication/json」をセットすることができました。

その後、再度実行したのですが、今度は以下エラーが表示されました。

「HTTP 応答コンテンツタイプはサポートされません」

上記を報告したところ、テスト用のスクリプトを提供頂き、試すこととなりました。

ここで私のミス1回目

Magic xpi ですが、開発用のサーバーでテストを行っております。
開発用の制限として、プロジェクトは24時間で自動終了するという仕様があることを忘れておりました。
つまり・・・「応答なし」状態で問い合わせを継続していたということです。

・・・申し訳ありません・・・

再度テストを行う際に、Wireshark を使ってネットワークキャプチャしたデータの提供ができないかとの相談がありました。

現時点で私のクライアントにインストールしたV12.0.2(64bit)でテストしていたため、こちらも問題なく対応し、データを提供したところ。

「Content-Type:」 と「application/json」の間に半角スペースが2つあります

との事。
あわててMagicの設定を見ると、確かにスペースが入っています。
私がどこかでコピペしたのですが、そもそもそちらに入っていたようです。

またヘッダ部分とBody部分の間に不要な文字が含まれていることも判明しました。

この文字列については再度マジック社に問い合わせたところ、BOM付きのデータになっているとの事でした。

この時点でBOMは外せなかったので、そのままテストし、Wiresharkのデータを解析して頂きました。

しかしながらやはり、BOMが邪魔のようで、Lotusscript側で外すスクリプトの提供を頂きました。

' BOM 除去
 i=0
 ReDim json(UBound(returnValue)-3)
 ForAll x In returnValue
 If i > 2 Then
 json(i-3) = x
 End If
 i = i + 1
 End ForAll

その後、幾度かのやりとりがあったのですが・・・

ここで私のミス・・・2回目

先とまったく同じミス、プロジェクトが停止していました。
何度も申し訳ございません orz   お恥ずかしい限りで・・・

それでも意味の不明な動きなどもあり、最終的に以下スクリプトを頂きテストすることになりました。

Sub Initialize
 Dim ws As New NotesUIWorkspace
 Dim uidoc As NotesUIDocument
 Dim session As New NotesSession
 Dim http As NotesHTTPRequest
 Dim url As String
 Dim returnValue As Variant
 Dim i As Integer
 Dim json As string

 Set uidoc = ws.CurrentDocument
 url = "URLを指定する"
 Set http = session.CreateHTTPRequest()
 Call http.SetHeaderField("Accept", "application/json")
 http.Preferstrings=true
 returnValue = http.Get(url)
 json = Mid(returnValue,2,Len(returnValue))

 Dim jsonNav As NotesJSONNavigator
 Dim jsonElement As NotesJSONElement

 Set jsonNav = session.CreateJSONNavigator(json)
 Set jsonElement = jsonNav.Getelementbyname("JSONのKEY")
 msgbox "value=" + jsonElement.Value + " type=" + CStr(jsonElement.type)
 End Sub

こちらを実行すると、想定されたメッセージボックスが表示されました!!

ここまでくれば、あとはJSONのデータを必要なフィールドに割当てるだけ。

Sub Click(Source As Button)
 Dim ws As New NotesUIWorkspace
 Dim uidoc As NotesUIDocument
 Dim session As New NotesSession
 Dim http As NotesHTTPRequest
 Dim url As String
 Dim returnValue As Variant
 Dim textCode As String
 Dim json As String

 ' "zip"フィールドの値を取得して、リクエストURIを生成
 Set uidoc = ws.CurrentDocument
 textCode = uidoc.FieldGetText("zip")

 url = "REST接続するURLを記述"
 url = url + textCode

 ' Getリクエストを実行し、結果を取得
 Set http = session.CreateHTTPRequest()
 Call http.SetHeaderField("Accept", "application/json")
 http.Preferstrings=True
 returnValue = http.Get(url)
 json = Mid(returnValue,2,Len(returnValue))

 'JSON パース
 Dim jsonNav As NotesJSONNavigator
 Dim jsonElement1 As NotesJSONElement
 Dim jsonElement2 As NotesJSONElement
 Dim jsonElement3 As NotesJSONElement

 ' JSON データを JsonNevigator 型にデータにセットする
 Set jsonNav = session.CreateJSONNavigator(json)
 Set jsonElement1 = jsonNav.Getelementbyname("JSONの値1")
 Set jsonElement2 = jsonNav.Getelementbyname("JSONの値2")
 Set jsonElement3 = jsonNav.Getelementbyname("JSONの値3")

 Call uidoc.FieldSetText("address", jsonElement1.Value)
 Call uidoc.FieldSetText("address_1", jsonElement2.Value)
 Call uidoc.FieldSetText("address_2", jsonElement3.Value)
 Call uidoc.Refresh()
 End Sub

以上で指定した値をそれぞれ準備したaddressフィールドにセットすることができました。

ちなみに今回サポートの方とのやり取りは、約2週間。38回にもわたりました。

・・・本当に申し訳ございません。

ただおかげ様で、やりたかった事が無事実現できました。

ので、正月休みに作業します(汗


長くなりましたが、LotusscriptでJSONを扱い場合、今回の経験で判明した内容です。

-----まとめ-----

  • JSONのレスポンスはバイト配列の必要がある
  • レスポンスヘッダの「Content-Type」は「application/json」であること
  • 文字コードはUTF-8であること
  • (現時点で)BOM付きはエラーになるため、外すこと

単にJSONと侮っていたら、こんなことになるんですね。
皆様もお気をつけください!!