今回の記事では、ガルーンのSOAP APIをVBAやVBScriptから実行して、ガルーンの「ファイル管理」内に登録済みのファイルを上書きでアップロードする処理のサンプルブログラムを紹介します。
尚、当記事のサンプルコードはVBScriptで書きますが、VBAでもほぼコピペで動作します。
簡単に試せるので是非チャレンジしてみてください。
そもそもガルーンのSOAP APIについて基本的な解説が知りたい場合は、以前に掲載した以下のリンク先の記事もご一読ください。
また、ガルーンのSOAP APIを使ってメッセージを送信する記事についても過去に掲載しているので、こちらも興味があればご一読ください。
ファイル管理のファイル更新APIの概要
ガルーンの「ファイル管理」は、ガルーン内で様々なファイルをフォルダで分類し、アクセス権を設けたうえで、ユーザー間で共用できる機能です。
ガルーンで提供されているSOAP APIを利用することで、この「ファイル管理」内のファイル情報を取得したり、ファイルのアップロードやダウンロードを外部のプログラムから実行することが可能になります。
例えば、ファイル管理内の特定のファイルの更新日時を取得して、別のシステムが出力するファイルの更新日時と比較し、別システム側で出力したファイルの更新日時の方が大きければそのファイルをガルーンにアップロードするといったバッチ処理を作ることも可能です。
今回の記事で利用するガルーンのSOAP APIは「CabinetUpdateFile」です。
これは、ファイル管理に登録されているファイル本体を更新するAPIです。
ファイル管理のファイルを更新するAPIの詳しい仕様は以下のリンク先をご確認ください。
尚、今回使用するAPIの「CabinetUpdateFile」では、パラメーターとして、ファイル管理に登録されている更新対象のファイルの「ファイルID」が必要になります。
このファイルIDは、ガルーンの内部で使用されているID番号で、ガルーンの画面上では表示されません。
よって、登録されているファイルのファイルIDを確認するには、同じくファイル管理用のAPIの「CabinetGetFileInfo」を実行して確認する必要があります。
更に、この「CabinetGetFileInfo」ではそのファイルを格納しているフォルダIDをパラメーターで渡して、そのフォルダ内の全てのファイル情報を取得するAPIであり、そのフォルダIDも事前に確認しておく必要があります。
フォルダIDを取得するには、同じくファイル管理用のAPIである「CabinetGetFolderInfo」を実行して、そのレスポンス内のフォルダIDを確認しておかなければいけません。
一度ファイルIDを確認してしまえば、それ以降は同じファイルIDを指定してファイル更新用APIを実行できますが、肝心のフォルダIDを確認するためにはいくつかのAPIを叩く必要があり、そこが実は面倒です。
オンプレガルーンであればデータベースを直接覗いてファイルIDを確認する裏技もあるのですが・・・
サンプルプログラムの処理概要
今回紹介するサンプルプログラムでは、以下の流れで処理を実装します。
- アップロード対象のファイルをBase64でエンコードする
- API「CabinetUpdateFile」にBase64でエンコードしたファイルを渡して実行する
ポイントはアップロードするファイルを「Base64」形式へのエンコードする処理です。
ガルーンでファイルをAPIからアップロードする場合は、バイナリ形式ファイルをウェブの通信でも送れるようにテキスト状態のBase64形式に変換してあげる必要があります。
所謂「Web API」で物理ファイルの転送をする場合にはたいてい必要になる処理なので、ガルーンのAPI以外でも活用する機会はあるかと思います。
こちらも参考にしてください。
ファイル管理のファイルを更新するAPIを実行するサンプルプログラム
当項では、実際にファイル管理のファイルを更新するAPIをVBScriptから実行する際のサンプルプログラムを紹介します。
尚、VBAはVBScriptと言語仕様が共通しており、当サンプルプログラムを一部分を修正したうえでVBAにコピペして実装してもらえれば動きます。
次項からは、当処理で使用するFunctionプロシージャを分割して紹介していきます。
各プロシージャの解説
当サンプルプログラムで使用している各プロシージャの簡単な解説をしていきます。
Base64へエンコードする処理
当記事の冒頭の概要でお伝えした通り、バイナリファイルをBase64へエンコードする処理のFunctionプロシージャです。
VBAで実装する場合もこのコードをコピペしていただければそのまま動きます。
※参照設定をしない遅延バインディングになるので、処理速度は遅くなるかも知れませんが、体感できるほどの差は無いかと思います。
'引数で渡されたファイルパスにあるファイルをBase64にエンコードして返します。 '引数1:エンコード対象ファイルのフルパス '戻り値:Base64文字列 Function ExeEncode_base64(TargetFilePath) Const adTypeBinary = 1 Dim objStream Dim objXML Dim objElm Set objStream = CreateObject("ADODB.Stream") Set objXML = CreateObject("Microsoft.XMLDOM") 'ストリームを開きます。 objStream.Open 'ストリームのタイプを1:バイナリで指定します。 objStream.Type = adTypeBinary objStream.Position = 0 'ストリームにファイルを読み込みます。 objStream.LoadFromFile TargetFilePath Set objElm = objXML.CreateElement("dummy") objElm.DataType = "bin.base64" objElm.NodeTypedValue = objStream.Read ExeEncode_base64 = objElm.Text Set objElm = Nothing Set objXML = Nothing Set objStream = Nothing End Function
リクエストxmlヘッダー作成共通処理
過去のガルーンAPIの記事でも度々使用しているxmlヘッダー部の共通作成処理です。
'リクエストで使用するXMLヘッダーの文字列を生成して返します。 Function Get_CreateXML_Header(API_Name) Dim sEnv sEnv = "<?xml version=""1.0"" encoding=""UTF-8""?>" sEnv = sEnv & "<soap:Envelope xmlns:soap=""http://www.w3.org/2003/05/soap-envelope"">" sEnv = sEnv & " <soap:Header>" sEnv = sEnv & " <Action>" & API_Name & "</Action>" sEnv = sEnv & " <Security>" sEnv = sEnv & " <UsernameToken>" sEnv = sEnv & " <Username>" & LOGIN_USERNAME & "</Username>" sEnv = sEnv & " <Password>" & LOGIN_PASSWORD & "</Password>" sEnv = sEnv & " </UsernameToken>" sEnv = sEnv & " </Security>" sEnv = sEnv & " <Timestamp>" sEnv = sEnv & " <Created>" & Get_forTimestampDate(0) & "</Created>" sEnv = sEnv & " <Expires>" & Get_forTimestampDate(15) & "</Expires>" sEnv = sEnv & " </Timestamp>" sEnv = sEnv & " <Locale>jp</Locale>" sEnv = sEnv & " </soap:Header>" Get_CreateXML_Header = sEnv End Function
リクエストxmlのパラメーターに指定するセッション有効期間を生成する処理
過去のガルーンAPIの記事でも度々使用しているセッション有効期間の文字列(ISO 8601形式)の共通作成処理です。
'xmlに設定するセッション有効期間の文字列を生成して返します。 '引数に与えた数値で生成する時間を調整します。値が0の場合は現在の日時 Function Get_forTimestampDate(add_Minutes) Dim wkNow 'yyyy-mm-ddThh:mm:ssZの書式に変換します。 wkNow = Year(Dateadd("n",add_Minutes,Now())) wkNow = wkNow & "-" & Right("0" & Month(Dateadd("n",add_Minutes,Now())) , 2) wkNow = wkNow & "-" & Right("0" & Day(Dateadd("n",add_Minutes,Now())) , 2) wkNow = wkNow & "T" & Right("0" & Hour(Dateadd("n",add_Minutes,Now())) , 2) wkNow = wkNow & ":" & Right("0" & Minute(Dateadd("n",add_Minutes,Now())) , 2) wkNow = wkNow & ":" & Right("0" & Second(Dateadd("n",add_Minutes,Now())) , 2) wkNow = wkNow & "Z" Get_forTimestampDate = wkNow End Function
CabinetUpdateFileを実行してファイルをアップロードする処理
当記事のメインのFunctionプロシージャであるAPIの「CabinetUpdateFile」を実行する処理です。
CabinetUpdateFileでは、レスポンスとして更新が成功した場合はそのファイル情報すべてを返します。
その返されたファイル情報からファイルIDを取得して戻り値としてセットしています。
'ガルーンのAPI「CabinetUpdateFile」を実行してファイル管理のファイルを更新します。 '引数1:ガルーン内のファイルID '引数2:ガルーン内のファイル名 '引数3:BASE64に変換したバイナリデータ '戻り値:アップロードしたファイルID※失敗した場合は0 Function ExeAPI_CabinetUpdateFile(file_id,file_name,base64_file) Dim objHTTP Dim Full_URL Dim sEnv Dim ReqXML Dim objXML Dim elm Dim rtnVal Dim attr sEnv = sEnv & " <soap:Body>" sEnv = sEnv & " <CabinetUpdateFile>" sEnv = sEnv & " <parameters file_id=""" & file_id & """ name=""" & file_name & """>" sEnv = sEnv & " <content xmlns="""">" & base64_file & "</content>" sEnv = sEnv & " </parameters>" sEnv = sEnv & " </CabinetUpdateFile>" sEnv = sEnv & " </soap:Body>" sEnv = sEnv & "</soap:Envelope>" Full_URL = BASE_URL & ACTION_API_DIR Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP") objHTTP.Open "POST", Full_URL, False ReqXML = Get_CreateXML_Header("CabinetUpdateFile") & vbcrlf & sEnv 'パラメーターを渡します。 objHTTP.send ReqXML If objHTTP.Status <> 200 Then 'httpレスポンスコードが異常な場合は戻り値に0を返します。 ExeAPI_CabinetUpdateFile = 0 Set objHTTP = Nothing Exit Function End If 'XML解析用のオブジェクトを生成します。 Set objXML = CreateObject("MSXML2.DOMdocument") 'レスポンスをxmlで読み込みます。 objXML.LoadXML(objHTTP.ResponseText) rtnVal = 0 'レスポンスxmlの要素thread内の属性idの値を取得して戻り値にセットします。 For Each elm In objXML.getElementsByTagName("file") For Each attr In elm.attributes If attr.name = "id" Then rtnVal = attr.text End If Next Next ExeAPI_CabinetUpdateFile = rtnVal Set objHTTP = Nothing Set objXML = Nothing End Function
ファイル管理にファイルを更新するサンプルプログラム全体
前項で紹介した各Functionプロシージャを使用し、ガルーンのファイル管理に対してアップロード済みのファイルを更新する一連の処理のサンプルプログラムを紹介します。
Option Explicit CONST BASE_URL = "http://example.com/scripts/cbgrn/grn.exe/" CONST LOGIN_USERNAME = "Administrator" CONST LOGIN_PASSWORD = "xxxxxxxx" CONST ACTION_API_DIR = "cbpapi/cabinet/api?" CONST TARGET_FILE_ID = 123 CONST TARGET_FILE = "更新対象ファイル.pdf" CONST TARGET_FILE_PATH = "C:¥Upload¥" 'VBAの場合は以下の12行目は削除してください。 Call GaroonAPI_Executor 'メイン処理 Sub GaroonAPI_Executor() 'ファイルをアップロードします。 If ExeAPI_CabinetUpdateFile(TARGET_FILE_ID,TARGET_FILE,ExeEncode_base64(TARGET_FILE_PATH & TARGET_FILE)) = 0 Then 'ExeAPI_CabinetUpdateFileの戻り値が0なら処理が失敗とします。 Msgbox("ファイルのアップロードに失敗しました。") Else 'ExeAPI_CabinetUpdateFileの戻り値が0以外なら処理が成功とします。 Msgbox("ファイルのアップロードに成功しました。") End If End Sub 'ガルーンのAPI「CabinetUpdateFile」を実行してファイル管理のファイルを更新します。 '引数1:ガルーン内のファイルID '引数2:ガルーン内のファイル名 '引数3:BASE64に変換したバイナリデータ '戻り値:アップロードしたファイルID※失敗した場合は0 Function ExeAPI_CabinetUpdateFile(file_id,file_name,base64_file) Dim objHTTP Dim Full_URL Dim sEnv Dim ReqXML Dim objXML Dim elm Dim rtnVal Dim attr sEnv = sEnv & " <soap:Body>" sEnv = sEnv & " <CabinetUpdateFile>" sEnv = sEnv & " <parameters file_id=""" & file_id & """ name=""" & file_name & """>" sEnv = sEnv & " <content xmlns="""">" & base64_file & "</content>" sEnv = sEnv & " </parameters>" sEnv = sEnv & " </CabinetUpdateFile>" sEnv = sEnv & " </soap:Body>" sEnv = sEnv & "</soap:Envelope>" Full_URL = BASE_URL & ACTION_API_DIR Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP") objHTTP.Open "POST", Full_URL, False ReqXML = Get_CreateXML_Header("CabinetUpdateFile") & vbcrlf & sEnv 'パラメーターを渡します。 objHTTP.send ReqXML If objHTTP.Status <> 200 Then 'httpレスポンスコードが異常な場合は戻り値に0を返します。 ExeAPI_CabinetUpdateFile = 0 Set objHTTP = Nothing Exit Function End If 'XML解析用のオブジェクトを生成します。 Set objXML = CreateObject("MSXML2.DOMdocument") 'レスポンスをxmlで読み込みます。 objXML.LoadXML(objHTTP.ResponseText) rtnVal = 0 'レスポンスxmlの要素thread内の属性idの値を取得して戻り値にセットします。 For Each elm In objXML.getElementsByTagName("file") For Each attr In elm.attributes If attr.name = "id" Then rtnVal = attr.text End If Next Next ExeAPI_CabinetUpdateFile = rtnVal Set objHTTP = Nothing Set objXML = Nothing End Function '引数で渡されたファイルパスにあるファイルをBase64にエンコードして返します。 '引数1:エンコード対象ファイルのフルパス '戻り値:Base64文字列 Function ExeEncode_base64(TargetFilePath) Const adTypeBinary = 1 Dim objStream Dim objXML Dim objElm Set objStream = CreateObject("ADODB.Stream") Set objXML = CreateObject("Microsoft.XMLDOM") 'ストリームを開きます。 objStream.Open 'ストリームのタイプを1:バイナリで指定します。 objStream.Type = adTypeBinary objStream.Position = 0 'ストリームにファイルを読み込みます。 objStream.LoadFromFile TargetFilePath Set objElm = objXML.CreateElement("dummy") objElm.DataType = "bin.base64" objElm.NodeTypedValue = objStream.Read ExeEncode_base64 = objElm.Text Set objElm = Nothing Set objXML = Nothing Set objStream = Nothing End Function 'リクエストで使用するXMLヘッダーの文字列を生成して返します。 Function Get_CreateXML_Header(API_Name) Dim sEnv sEnv = "<?xml version=""1.0"" encoding=""UTF-8""?>" sEnv = sEnv & "<soap:Envelope xmlns:soap=""http://www.w3.org/2003/05/soap-envelope"">" sEnv = sEnv & " <soap:Header>" sEnv = sEnv & " <Action>" & API_Name & "</Action>" sEnv = sEnv & " <Security>" sEnv = sEnv & " <UsernameToken>" sEnv = sEnv & " <Username>" & LOGIN_USERNAME & "</Username>" sEnv = sEnv & " <Password>" & LOGIN_PASSWORD & "</Password>" sEnv = sEnv & " </UsernameToken>" sEnv = sEnv & " </Security>" sEnv = sEnv & " <Timestamp>" sEnv = sEnv & " <Created>" & Get_forTimestampDate(0) & "</Created>" sEnv = sEnv & " <Expires>" & Get_forTimestampDate(3) & "</Expires>" sEnv = sEnv & " </Timestamp>" sEnv = sEnv & " <Locale>jp</Locale>" sEnv = sEnv & " </soap:Header>" Get_CreateXML_Header = sEnv End Function Function Get_forTimestampDate(add_Minutes) Dim wkNow 'yyyy-mm-ddThh:mm:ssZの書式に変換します。 wkNow = Year(Dateadd("n",add_Minutes,Now())) wkNow = wkNow & "-" & Right("0" & Month(Dateadd("n",add_Minutes,Now())) , 2) wkNow = wkNow & "-" & Right("0" & Day(Dateadd("n",add_Minutes,Now())) , 2) wkNow = wkNow & "T" & Right("0" & Hour(Dateadd("n",add_Minutes,Now())) , 2) wkNow = wkNow & ":" & Right("0" & Minute(Dateadd("n",add_Minutes,Now())) , 2) wkNow = wkNow & ":" & Right("0" & Second(Dateadd("n",add_Minutes,Now())) , 2) wkNow = wkNow & "Z" Get_forTimestampDate = wkNow End Function
当サンプルプログラムを簡単に解説します。
3行目の定数BASE_URLは仮のURLを指定しています。
実際に使用しているガルーンのURLにドメイン部分を変更してください。
4行目の定数LOGIN_USERNAMEには、API実行可能権限のあるユーザーを指定します。
また、ここで指定したユーザーの権限でファイル管理へファイルをアップロードしにいくことになるため、ファイル管理内の対象のファイルが配置されているフォルダにも同じユーザーでアクセス権が必要です。
6行目の定数の指定では「ACTION_API_DIR = “cbpapi/cabinet/api?”」としています。
今回操作するファイル管理関連のSOAP APIはこのURLに入っています。
7行目のTARGET_FILE_IDは仮の値であり、実際に使用する環境のファイルIDを指定してください。
8行目と9行目はアップロードするファイルのファイル名とパスを指定します。
コメントにも書いてありますが、VBAで実装する場合は、12行目は削除してください。
例えば、空の「標準モジュール」を作成して、上記サンプルプログラムの12行目を除いた全行を貼り付けて、URL、ユーザー名やパスワード、ファイルIDやアップロードするファイルの指定を書き換えてあげれば動きます。
最後に
今回の記事では、ガルーンのSOAP APIを利用して、ガルーンの機能の「ファイル管理」に登録されているファイルを上書きで更新するサンプルプログラムを紹介しました。
因みに、私は自社の売上データを元にExcelの集計表を日次処理で自動作成しており、それをガルーンのファイル管理の特定のフォルダ内に当APIを使って毎日自動的に更新する処理を自作しています。
今回紹介したAPIも工夫次第で色々な活用方法があるので、是非機会があれば試してみてください。
今回も読んでいただきましてありがとうございました。
それでは皆さまも良い自動化ライフを!