Salesforceのデータをエクセルやcsvに出力するにはいくつか方法がありますが、DataLoaderや開発者コンソール、WorkbenchなどのWebAPIを実装したツール等を使う必要があったりします。
開発中であったり、使用者が開発者であったりする場合は、比較的自由度の高いその方法を取ることも考えられますが、要件が「営業やマーケティングチームのユーザが毎日の業務のために、Salesforceにある最新のデータを取得したい」といったものである場合は、もう少し、使いやすく、用意しやすい方法がよいですよね。
ひとつのソリューションは、「レポート」にして、実行結果をエクセルやcsv形式で出力するというものです。
ただし、この方法は、少し複雑な結合条件のクエリだと、なかなか定義しづらいという欠点もあります。
それを解消するため、「SFDCのデータをエクセルで参照、加工する」というソリューションもあります。
なかなか良いアイディアですよね。
調べてみるといくつかあるので、興味のある方はサーチしてみてください。
さて、それらのソリューションの多くは、無料ではないので、自作してみました。
同じアプローチを考えていて、自分でコーディングしたいという方の助けになるかもしれませんので、サンプルソースも掲載しておきます。
エクセルでSalesforceのデータを参照する方法
やりたいことは、こうです。
エクセルのマクロで、httpリクエストをgetしたり、postしたりすることができます。
また、Salesforceは、WebAPIを公開していますので、WebAPI経由でデータの取得が比較的容易にできます。通常はJavaなどのプログラミング言語を使ってバッチなどを作成するのですが、エクセル・マクロでそれが行えれば、コンパイルも必要ありませんし、少し修正したりするのも簡単だというわけです。
今回のマクロは、エクセルのセルに、ログインURLとログインID、パスワードを書き込むことで、それを使用して、ログインし、そこで取得したトークンを利用してクエリを投げるシンプルなものにします。画面のイメージはちょうど下のような感じです。
サンプルソース
実際のサンプルソースです。
Public gLoginURL As String
Public gUserName As String
Public gPassword As String
Public gAccessToken As String
Public gServerURL As String
Public gServiceURL As String
Sub btnLogin_Click()
gLoginURL = Worksheets("Setting").Range("cLoginURL").Value
gUserName = Worksheets("Setting").Range("cUserName").Value
gPassword = Worksheets("Setting").Range("cPassword").Value
'MsgBox gLoginURL
Dim targetURL, loginSendData
targetURL = gLoginURL & "/services/Soap/u/40.0"
loginSendData = ""
' POSTで飛ばします
Dim httpReq
Set httpReq = CreateObject("Microsoft.XMLHTTP")
httpReq.Open "POST", targetURL, False
Call httpReq.setRequestHeader("Content-Type", "text/xml;charset=utf-8")
Call httpReq.setRequestHeader("SOAPAction", "login")
Dim postData As Variant
postData = "<!--?xml version=""1.0"" encoding=""utf-8"" ?--><env:envelope xmlns:xsd="" http:="" www.w3.org="" 2001="" xmlschema""="" xmlns:xsi="" xmlschema-instance""="" xmlns:env="" schemas.xmlsoap.org="" soap="" envelope="" ""=""><env:body><n1:login xmlns:n1="" urn:partner.soap.sforce.com""=""><n1:username>" + gUserName + "</n1:username><n1:password>" + gPassword + "</n1:password></n1:login></env:body></env:envelope>"
Call httpReq.Send(postData)
Dim respData As String
If httpReq.Status = 200 Then
respData = httpReq.responseText
End If
MsgBox respData
Dim XDoc As Object, root As Object
Set XDoc = CreateObject("MSXML2.DOMDocument")
XDoc.async = False: XDoc.validateOnParse = False
XDoc.LoadXML (respData)
Set root = XDoc.DocumentElement
Set accessTokenField = XDoc.SelectNodes("//loginResponse/result/sessionId")
gAccessToken = accessTokenField(0).Text
Set serverUrlField = XDoc.SelectNodes("//loginResponse/result/serverUrl")
gServerURL = serverUrlField(0).Text
Set XDoc = Nothing
'MsgBox gServerURL
Dim regEx, Match, Matches As Object ' 変数を作成します。
Set regEx = CreateObject("VBScript.RegExp") ' 正規表現を作成します。
regEx.Pattern = "https://([A-Za-z0-9_\-\.]*)/services" ' パターンを設定します。
regEx.IgnoreCase = True ' 大文字と小文字を区別しないように設定します。
regEx.Global = True ' 文字列全体を検索するように設定します。
Set Matches = regEx.Execute(gServerURL) ' 検索を実行します。
For Each Match In Matches ' Matches コレクションに対して繰り返し処理を行います。
RetStr = ""
RetStr = RetStr & Match.Value
Next
gServiceURL = RetStr
'MsgBox gServiceURL
End Sub
Sub serviceQuery_Click()
Dim restTargetURL
restTargetURL = gServiceURL & "/data/v40.0/query/?q=select%20Id%20From%20Account"
MsgBox restTargetURL
MsgBox gAccessToken
' GETで飛ばします
Set httpObj = CreateObject("Microsoft.XMLHTTP")
httpObj.Open "GET", restTargetURL, False
Call httpObj.setRequestHeader("Content-Type", "application/json; charset=UTF-8")
Call httpObj.setRequestHeader("Authorization", "Bearer " + gAccessToken)
Call httpObj.setRequestHeader("Accept", "application/xml")
httpObj.Send (sendData)
MsgBox httpObj.responseText
End Sub