UiPath Blog
前回はSalesforce管理者の方が行うユーザ登録やパスワードリセットといった随時対応のワークフローについてご紹介しました。もし見逃したという方は「ユーザ(User)の操作」も併せてご覧ください。
自社サービスの状況をファイルにまとめ、取引先や顧客に定期的にSalesforceを介して情報公開している。ファイル内容は取引先や顧客ごとに異なるため、ファイル数が多くアップロードに時間と手間がかかっている・・
こういった「ファイルアップロードの手間」に悩まれたことはないでしょうか。 顧客や取引先の数が増えることは会社にとってもちろんよいことですが、その反面、作業の手間が増えるのは困りますよね。
今回はこうしたファイルアップロードまわりの操作方法を中心に、以下の内容をお届けします。
ファイルの主要関連オブジェクト
新規ファイルUpload&商談(Opportunity)への添付
既存ファイル&取引先(Account)への添付
既存ファイルの履歴更新
ライブラリ(フォルダ)への格納
Classic環境でのUpload
読み終わったあと本記事を読みながらワークフローを作成すれば、作業負担を減らしつつ顧客や取引先の増加に柔軟に対応できるようになると思います。
ファイルの主要オブジェクト群を確認しておきましょう。
※本記事から読み始められた方で"オブジェクト"という単語を初めて目にした方は「Salesforce連携ソリューションを活用するための基礎知識1」を先にご覧ください。
ファイルを取り巻くオブジェクトは大きく「ファイル関連オブジェクト」「各種関連先オブジェクト」「ライブラリ&フォルダ関連オブジェクト」の3つに分かれていることがわかります。
「ファイル関連オブジェクト」はファイル本体を管理するオブジェクト群です。「ファイル(ContentDocument)」は新規アップロードのたびに作成されます。既存ファイルを更新した場合は「ファイル履歴(ContentVersion)」が作成され、更新履歴が管理されます。なおファイル履歴は新規アップロードの際も作成されます。
「各種関連先オブジェクト」はファイルを関連付ける各種オブジェクト群です。商談や取引先などのWebページで添付ファイルを表示させるには、これらのオブジェクトと関連付ける必要があります。
「ライブラリ&フォルダ関連オブジェクト」はライブラリおよび配下のフォルダに関するオブジェクトです。ファイルをこれらに配置して管理する場合のみ必要になります。
ここまでの内容に出てきていないオブジェクトが「ContentDocumentLink」と「ファイル(Attachment)」です。
「ContentDocumentLink」は3つのオブジェクト群をつなぐ役割を担うオブジェクトです。
「ファイル(Attachment)」はClassicのみで使用できます。「ファイル関連オブジェクト」と比較すると、ファイルをフォルダに配置できないなど、一部管理情報が制限されています。ご契約環境の運用状況に合わせて「ファイル関連オブジェクト」と使い分ける必要があります。
ライブラリ内のフォルダを階層構造にして管理されている場合もあるのではないでしょうか。ライブラリ内のフォルダ構造とオブジェクトの対応関係を下図に示します。ライブラリとルートフォルダ間や、フォルダとファイル間は専用のオブジェクトがある一方、フォルダ間の階層関係はContentFolderオブジェクトで管理されている点に注意してください。ルートフォルダはWebUI上は表示されませんが、管理上存在しています。
新規にファイルをアップロードし商談に添付するワークフローを作成します。
登録イメージとワークフローの全体像は次の通りです。
なお、商談は予めSalesforceに登録されている必要がありますので、ない場合はWeb画面から準備してください。
Activityの設定方法を中心にお届けしているため、Salesforceアプリケーションスコープの設定やエラー制御は含まれておりません。
個別にプロパティの設定内容を見てみます。
SELECT Id,Name FROM Opportunity WHERE Name = 'サンプル商談' AND Account.Name = 'サンプル株式会社'
Id,Name(商談名)を商談(Opportunity)オブジェクトから取得するSOQLです
レコードの絞込条件として、
特定の商談名であること
特定の取引先名であること
を指定しています。本例では「'サンプル商談'」「'サンプル株式会社'」を設定します。
①-2 Salesforceステータスは必要に応じて設定します。
※本例では設定していますが、後続では使用しません。
①-3 SOQLの結果を格納するため変数を設定します。
変数の型はDataTableです。
DataTable内の列はSELECTの項目名になるため、Id,Nameの2列になります。
②-1 Salesforce上でのファイルのタイトルを設定します。
タイトルは任意でOKです。本例では「"サンプルファイル_20201224-1"」を設定します
②-2 アップロードするファイルのパスを設定します。
パスは任意でOKです。
②-3 必要に応じて変数を設定します。
※本例では設定していますが、後続では使用しません。
②-4 アップロードしたファイルバージョンのIDを格納する変数を設定します。
②-5 アップロードしたファイルのIDを格納する変数を設定します。
③-1 アップロードしたファイルのIDが納された変数を設定します。
③-2 関連付ける商談レコードのIDを設定します。
本例では①で特定した「sfdcOpportunityList(0)("Id").ToString()」を設定します。
③-3 公開範囲を設定します。
本例では「AllUsers」を設定しています。選択肢は次の通りです。
AllUsers: ファイル参照権限を持つ全ユーザ
InternalUsers:ファイル参照権限を持つ内部ユーザ
SharedUsers:フィードを表示できる全ユーザ
③-4 公開ユーザの編集権限を設定します。
本例では「V」を設定しています。選択肢は次の通りです。
V: 閲覧者権限
C: 共同作業
I: 関連レコードに対するユーザの許可から推測
③-5 必要に応じて変数を設定します。
※本例では設定していますが、後続では使用しません。
これで完成です。ワークフローを実行してみてください。ファイルが商談に関連付けられていれば成功です。
別途アップロードされたファイルを取引先に添付するワークフローを作成します。
登録イメージとワークフローの全体像は次の通りです。
なお、取引先とファイルは予めSalesforceに登録されている必要がありますので、ない場合はWeb画面から準備してください。
個別にプロパティの設定内容を見てみます。
①-1 SOQL詳細:
SELECT Id,Name FROM Account WHERE Name = 'サンプル株式会社'
Id,取引先名(Name)を取引先(Account)オブジェクトから取得するSOQLです
レコードの絞込条件として、
特定の取引先名であること
を指定しています。本例では「'サンプル株式会社'」を設定します。
SELECTの項目「Name」は後続で使用しませんが、デバッグ時に確認の補助となるため入れています
①-2 Salesforceステータスは必要に応じて設定します。
※本例では設定していますが、後続では使用しません。
①-3 SOQLの結果を格納するため変数を設定します。
変数の型はDataTableです。
DataTable内の列はSELECTの項目名になるため、Id,Nameの2列になります。
SELECT Id,Title FROM ContentDocument WHERE Title = 'サンプルファイル_20201224-2.txt'
Id,Title(ファイル名)をファイル(ContentDocument)オブジェクトから取得するSOQLです
レコードの絞込条件として、
特定のファイル名であること
を指定しています。本例では固定値「'サンプルファイル_20201224-2.txt'」ですが、変数に置き換えれば任意のファイルに対応可能です。
SELECTの項目「Title」は後続で使用しませんが、デバッグ時に確認の補助となるため入れています
②-2 Salesforceステータスは必要に応じて設定します。
※本例では設定していますが、後続では使用しません。
②-3 SOQLの結果を格納するため変数を設定します。
変数の型はDataTableです。
DataTable内の列はSELECTの項目名になるため、Id,Titleの2列になります。
③-1 アップロードしたファイルのIDが納された変数を設定します。
本例では②で特定した「sfdcContentDocumentList(0)("Id").ToString()」を設定します。
③-2 関連付ける商談レコードのIDを設定します。
本例では①で特定した「sfdcAccountList(0)("Id").ToString()」を設定します。
③-3 公開範囲を設定します。
本例では「AllUsers」を設定しています。選択肢は次の通りです。
AllUsers: ファイル参照権限を持つ全ユーザ
InternalUsers:ファイル参照権限を持つ内部ユーザ
SharedUsers:フィードを表示できる全ユーザ
③-4 公開ユーザの編集権限を設定します。
本例では「V」を設定しています。選択肢は次の通りです。
V: 閲覧者権限
C: 共同作業
I: 関連レコードに対するユーザの許可から推測
③-5 必要に応じて変数を設定します。
※本例では設定していますが、後続では使用しません。
アップロード済みのファイルを更新するワークフローを作成します。
登録イメージとワークフローの全体像は次の通りです。
なお、取引先とファイルは予めSalesforceに登録されている必要がありますので、ない場合はWeb画面から準備してください。本節は前節の続きとなっておりますので、以降で説明していない部分は前節をご参照ください。
個別にプロパティの設定内容を見てみます。
①-1 更新後のSalesforce上のファイルタイトルを設定します。
タイトルは任意でOKです。本例では「"サンプルファイル_20201224-2"」を設定します
①-2 アップロードするファイルのパスを設定します。
パスは任意でOKです。
①-3 既存ファイルのIDを設定します。
本例では説明を割愛していますが、直前に特定したファイルのID「sfdcContentDocumentList(0)("ContentDocumentId").ToString()」を設定します。
①-4 必要に応じて変数を設定します。
※本例では設定していますが、後続では使用しません。
①-5 アップロードしたファイルバージョンのIDを格納する変数を設定します。
①-6 アップロードしたファイルのIDを格納する変数を設定します。
これで完成です。ワークフローを実行してみてください。ファイルの更新履歴が増えていれば成功です。
ファイルをアップロードし、ライブラリ内のフォルダに配置するワークフローを作成します。
登録イメージとワークフローの全体像は次の通りです。
なお、本節は「新規ファイルUpload&商談(Opportunity)への添付」節の続きとなっておりますので、以降で説明していない部分は元の節をご参照ください。
個別にプロパティの設定内容を見てみます。
SELECT Id,Name,RootContentFolderId FROM ContentWorkSpace WHERE Name='サンプルライブラリ'
Id,Name(ライブラリ名),ルートフォルダのID(RootContentFolderId)をライブラリ(ContentWorkSpace)オブジェクトから取得するSOQLです
レコードの絞込条件として、
特定のライブラリ名であること
を指定しています。本例では「'サンプルライブラリ'」を指定します。
①-2 Salesforceステータスは必要に応じて設定します。
※本例では設定していますが、後続では使用しません。
①-3 SOQLの結果を格納するため変数を設定します。
変数の型はDataTableです。
DataTable内の列はSELECTの項目名になるため、Id,Name,RootContentFolderIdの3列になります。
"SELECT Id FROM ContentFolder WHERE Name='子フォルダ' AND ParentContentFolder.Name='親フォルダ' AND ParentContentFolder.ParentContentFolderId='" + sfdcLibraryList(0)("RootContentFolderId").ToString() + "'"
Idをフォルダ(ContentFolder)オブジェクトから取得するSOQLです
レコードの絞込条件として、
フォルダ名、親フォルダ名が特定の名称であること
フォルダが特定のライブラリに属すること
を指定しています。本例ではフォルダ名、親フォルダ名は固定値「子フォルダ」「親フォルダ」ですが、変数に置き換えれば任意のフォルダに対応可能です。
ライブラリは①で特定した「sfdcLibraryList(0)("RootContentFolderId").ToString()」を指定します。
②-2 Salesforceステータスは必要に応じて設定します。
※本例では設定していますが、後続では使用しません。
②-3 SOQLの結果を格納するため変数を設定します。
変数の型はDataTableです。
DataTable内の列はSELECTの項目名になるため、Idの1列になります。
③-1 アップロードしたファイルのIDが納された変数を設定します。
③-2 関連付けるライブラリのIDを設定します。
本例では①で特定した「sfdcLibraryList(0)("Id").ToString()」を設定します。
③-3 公開範囲を設定します。
本例では「AllUsers」を設定しています。選択肢は次の通りです。
AllUsers: ファイル参照権限を持つ全ユーザ
InternalUsers:ファイル参照権限を持つ内部ユーザ
SharedUsers:フィードを表示できる全ユーザ
③-4 公開ユーザの編集権限「I(関連レコードに対するユーザの許可から推測)」を設定します。
ライブラリへの割当では「I」のみ設定可能です
③-5 必要に応じて変数を設定します。
※本例では設定していますが、後続では使用しません。
なぜフォルダに直接関連付けないのかと疑問に思った方もいるかもしれません。ファイルをフォルダに関連付けるにはContentFolderMemberのレコードが必要ですが、このレコードはファイルをライブラリに関連付けたときにのみ生成され直接登録できないという、Salesforceの仕様に則ったものになります。よって、本項でContentFolderMemberのレコードを生成し、後続で目的のフォルダに関連付ける流れになるのです。
また、本項によりファイルはルートフォルダ直下に関連付けられますのでご注意ください(ライブラリ直下にファイルは存在しないためです)。
"SELECT Id FROM ContentFolderMember WHERE ChildRecordId='" + sfdcContentDocumentId + "' AND ParentContentFolderId='" + sfdcRootFolderList(0)("ContentFolderId").ToString() + "'"
IdをContentFolderMemberオブジェクトから取得するSOQLです
レコードの絞込条件として、
関連付けられたファイルID(ChildRecordId)がアップロードされたファイルであること
関連付けられたフォルダID(ParentContentFolderId)がルートフォルダであること
を指定しています。本例では前のステップで得られた値を設定します。
④-2 Salesforceステータスは必要に応じて設定します。
※本例では設定していますが、後続では使用しません。
④-3 SOQLの結果を格納するため変数を設定します。
変数の型はDataTableです。
DataTable内の列はSELECTの項目名になるため、Idの1列になります。
⑤-1 更新対象オブジェクト「ContentFolderMember」を選択します。
⑤-2 更新対象の項目を選択する子ウインドウを開き、次の項目を選択します。
ParentContentFolderId(親コンテンツフォルダID)
⑤-3 各項目に登録する値を設定します。
Id(ContentFolderMember ID)は、更新対象レコードのIDを格納する変数を設定します。本例では⑥で得た「sfdcContentFolderMemberList(0)("Id").ToString()」です
ParentContentFolderId(親コンテンツフォルダID)は、目的フォルダのIDを設定します。本例では④で得た「sfdcSaveFolderList(0)("Id").ToString()」を設定します。
これで完成です。ワークフローを実行してみてください。ファイルが目的のフォルダに登録されていれば成功です。
Salesforceと同じフォルダ構造をファイルサーバにもち、同期させる形でアップロードされるケースもあるかと思います。その場合は、①と②の間に工夫が必要になります。もし情報が必要な方は、弊社営業担当にお声がけください。
Classic環境でのみ使用可能なAttachmentオブジェクトにファイルをアップロードするワークフローを作成します。
登録イメージとワークフローの全体像は次の通りです。
なお商談特定部分については説明を割愛しておりますので、「新規ファイルUpload&商談(Opportunity)への添付」をご参照ください。
個別にプロパティの設定内容を見てみます。
①-1 「Base64形式への変換」「ファイルサイズ算出」「MIMEタイプの算出」を行うコードです。
コード例をコピーしてください。
コード例:
Using fs As New FileStream(filePath, FileMode.Open, FileAccess.Read) 'ファイルサイズ算出 filePlaneSize = CInt(fs.Length) 'Base64変換 Dim buf(filePlaneSize - 1) As Byte fs.Read(buf, 0, filePlaneSize) fileBodyBase64 = Convert.ToBase64String(buf) End Using 'MimeType算出 Dim defaultMimeType As String = "application/octet-stream" Dim regKey As Microsoft.Win32.RegistryKey Dim regMimeType As Object regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Path.GetExtension(filePath)) If (regKey Is Nothing) Then fileMimeType = defaultMimeType Else regMimeType = regKey.GetValue("Content Type") If (regMimeType Is Nothing) Then fileMimeType = defaultMimeType Else fileMimeType = CType(regMimeType, String) End If End If
①-2 引数を定義します。
上から順に次の通り設定してください。
filePath(入力,String), filePlaneSize(出力,Int32), fileBodyBase64(出力,String), fileMimeType(出力,String)
①-3 各引数に対応する値を設定します。
「filePath」はアップロードするファイルのパスです。本例では「"Data\テストメモA1.pdf"」を設定します。
「filePlaneSize」は①のコードで算出したfilePathのファイルサイズを格納する変数名です。変数名は任意でOKです。本例では「filePlaneSize」を設定します。
「fileBodyBase64」は①のコードでBase64形式に変換したfilePathの内容を格納する変数名です。変数名は任意でOKです。本例では「fileBodyBase64」を設定します。
「fileMimeType」は①のコードで算出したfilePathのMIMEタイプです。変数名は任意でOKです。本例では「fileMimeType」を設定します。
※MIMEタイプはデータの種類を表すコードです。
②-1 更新対象オブジェクト「Attachment」を選択します。
②-2 更新対象の項目を選択する子ウインドウを開き、次の項目を選択します。
Body(本文),ContentType(コンテンツタイプ),Name(ファイル名),ParentId(参照先ID)
②-3 各項目に登録する値を設定します。
Body(本文)はBase64形式に変換されたファイルの内容です。本例では①で得た「fileBodyBase64」を設定します。
ContentType(コンテンツタイプ)はデータの種類を表すMIMEタイプを設定します。本例では①で得た「fileMimeType」を設定します。
Name(ファイル名)はSalesforce上でのファイル名です。任意の名称でOKです。本例では「"Classicサンプルファイル_20201224-1.pdf"」を設定します。
ParentId(参照先ID)は関連付ける商談レコードのIDです。本例では①で得た「sfdcOpportunityList(0)("Id").ToString()」を設定します。
これで完成です。ワークフローを実行してみてください。ファイルが商談に登録されていれば成功です。
今回は「ファイルUploadと関連付け」に関するワークフローの作り方をお届けしました。
皆様のワークフロー開発の一助になれば幸いです。
最後に今回の記事の中で取り上げた部品のリンク先などをお知らせします。
Activityの公開先 (UiPathマーケットプレイス):
https://marketplace.uipath.com/ja/listings/salesforce-activity-pack
Salesforce連携ソリューションご案内:
https://www.uipath.com/ja/solutions/technology/salesforce-automation
その他連携ソリューションご案内:
https://www.uipath.com/ja/solutions/application-cooperation-solutions
次回は「ファイルDownload」を行うワークフローをお届けします。お楽しみに。
※SalesforceはSalesforce.com,Incの商標であり、許可のもとで使用しています。
また、UiPathでは、本記事で解説した内容に加えて、CRM/SFAの定着化のためのRPA活用について、実際の事例や、UiPathの連携ソリューションについてご紹介するeBookを無料で公開しています。eBookは下記よりダウンロードください。
詳しくはこちら
Topics:
SalesforceSenior Sales Engineer, UiPath