SalesforceのSOAP APIを使ってVB.NETでSalesforce組織のレコードを参照・更新・削除したりする方法を説明します。Enterprise WSDLを使います。
1. SalesforceからWSDLを取得する
Salesforceにログインし、画面右上の歯車マークから[設定]を開く
設定画面左側の[クイック検索]から[api]を検索し、赤枠のリンクを押下する
※[設定]-[インテグレーション]-[API]
API画面の[Enterprise WSDLの生成]リンクを押下する
Enterprise WSDLの作成画面の[Generate]ボタンを押下する
ブラウザの別タブにXMLファイルが展開表示されるので、URLを控えておく
2. VB.NETプロジェクトを作成する
Visual Studioを起動し、新規プロジェクトを作成する
※今回はコンソールアプリ(.NET Framework)を選択していますが、デスクトップアプリを作成したい場合は、Windowsフォームアプリ(.NET Framework)を選択してください
任意のプロジェクト名を入力し、[作成]ボタンからプロジェクトを作成する
※今回は、.NET Framework4.8を使用
正常にプロジェクトが作成されると、右図のような画面に切り替わる
3. Salesforceから取得したWSDLをVB.NETプロジェクトに設定する
メニューから、[プロジェクト]-[サービス参照の追加]を開く
サービス参照の追加画面下部にある[詳細設定]ボタンを押下する
サービス参照設定画面下部の[Web参照の追加]ボタンを押下する
Web参照の追加画面のURL欄に「1. SalesforceからWSDLを取得する」で取得したWSDLリンクを入力し、URL欄右側の[→]を押下する
正常に動作した場合は、Salesforceへのログイン画面が表示されるので、認証を行う
Salesforceへの認証に成功した場合、WSDLを参照可能な状態になるので、[Web参照名]に任意の名前を入力し、[参照の追加]ボタンを押下する
4. WSDLファイルのプロパティを設定する
メニューから、[プロジェクト]-[(プロジェクト名)のプロパティ]を選択する
プロパティ画面の[参照設定]を開く
[インポートされた名前空間]にインポートしたいファイルが選択されていない場合、チェックを入れて保存をすることでビルド参照ができるようになる
チェックを入れたものが上記の参照確認ボックスにあることを確認する
5.Reference.vbのエラーを修正する
WSDLを取り込むと、Reference.vbというクラスやプロパティを定義しているファイルをVisual Studioが生成します。
この生成されたファイルがビルド時に一部エラーとなるので、修正する必要があります。
- エラー箇所を修正する
- 属性’〇〇’を複数回適用することはできません。
こちらのエラーでは該当属性が複数定義されているため、いずれかを残すように修正すればOKです。今回は、該当箇所をコメントアウトしました。
- class’〇〇’に同じ名前のメンバーが多種類存在するため、’△△’があいまいです。
こちらも〇〇が該当箇所のコードで複数定義されているため、いずれかを残すように修正すればOKです。今回も同様、該当箇所をコメントアウトしました。
- ‘〇〇’は、このclassで’△△’として既に宣言されています。
こちらも〇〇が該当箇所のコードで複数定義されているため、いずれかを残すように修正すればOKです。今回も同様、該当箇所をコメントアウトしました。
- ‘()’が二重になっている変数がある(ListViewRecordColumn型)
下記のように2か所が()()というように()が重複しています。()()は構文エラーなので一つ消せばOKです。2枚目の画像は修正後になります。
6. プロジェクトをビルドする
「5.Reference.vbのエラーを修正する」で修正した内容をもとにビルドに成功するか確認します。
メニューから、[プロジェクト]-[(プロジェクト名)のプロパティ]を選択する
プロパティ画面の[コンパイル]を開き、[XMLドキュメントファイルを生成する]をオフにする
プロパティ画面の[詳細コンパイルオプション]ボタンを押下する
コンパイラの詳細設定画面の[シリアル化アセンブリの生成]をオンに設定し、[OK]ボタンを押下する
メニューから、[ビルド]-[ソリューションのビルド]を押下し、ビルドしてみる
下記のように出力結果でビルドに成功していることを確認する
ビルドに成功した場合は、プロジェクトフォルダ>bin>DebugにSalesforceSampleApp.exeが生成されます。(Releaseビルドの場合は、プロジェクトフォルダ>bin>Releaseに実行ファイルが生成される)まだ、処理を実装していないのでexeファイルを実行しても何も起きません。
6.Salesforceユーザのシークレットキーを取得する
SalesforceへSOAP APIを使用してアクセスする際に、該当ユーザのシークレットキーが必要になるので取得しておきます。
Salesforce画面右上のユーザアイコンを押下し、[設定]リンクを開く
[私のセキュリティトークンのリセット]画面の[セキュリティトークンのリセット]ボタンを押下する
Salesforceへログインしているユーザに設定されているメールアドレスにセキュリティトークンが記載されたメールが届く
メール本文に記載されているセキュリティトークンを控えておく(第三者に漏れないように)
7. VB.NETでSOAPクライアントを使う
以下は、SalesforceのSOAP APIを使ってオブジェクトレコードを参照・更新・削除したりするVB.NETの基本的なコードです。認証情報はハードコーディングを避けるため、App.Config(設定ファイル)に記述しています。
ブログ執筆用に非常に簡素なコード(かつ非効率)になっているため、こちらのコードを参考に実際の環境に合わせて適切に変えてビルドしてください。
1. まずVB.NET全体のコード
Imports SalesforceSampleApp.sforce
Imports System.Web.Services.Description
Imports System.Web.Services.Protocols
''' <summary>
''' SalesfroceとVB.NET連携
''' </summary>
Module Module1
' SFに接続するためのインスタンス
Dim SFDCBinding As New SforceService()
''' <summary>
''' メインコントローラ
''' </summary>
Sub Main()
SFDCBinding.Timeout = 30000
Dim loginResult As Boolean = Login()
If loginResult Then
' 取引先情報取得
getAccounts()
' 取引先作成
createAccounts()
getAccounts()
' 取引先名更新
updateAccountByName("取引先001", "取引先(変更001)")
getAccounts()
' 取引先削除
deleteAccount("取引先(変更001)")
getAccounts()
' ログアウト
Logout()
Console.ReadLine()
End If
End Sub
''' <summary>
''' Salesfroceへログイン
''' </summary>
''' <returns>ログイン成功=True/ログイン失敗=False</returns>
Function Login() As Boolean
Console.WriteLine("=== Salesforceへログイン[開始] ===")
' SFのユーザ名
Dim userName As String = My.Settings.Salesforce_UserName
' SFのパスワード
Dim password As String = My.Settings.Salesforce_Password
Dim loginResult
Try
' ログイン
loginResult = SFDCBinding.login(userName, password)
Catch e As SoapException
Console.WriteLine("ログイン失敗")
Return False
End Try
' パスワード失効している場合
If loginResult.passwordExpired Then
' SFDCBinding.setPassword(userId, newPassword) で更新が必要
Return False
End If
' エンドポイント更新
Dim authEndPoint As String = SFDCBinding.Url
SFDCBinding.Url = loginResult.serverUrl
' セッションヘッダ追加
SFDCBinding.SessionHeaderValue = New SessionHeader()
SFDCBinding.SessionHeaderValue.sessionId = loginResult.sessionId
' 結果表示
Dim userInfo As GetUserInfoResult = loginResult.userInfo
Dim msg As String = ""
msg += "UserID: " & userInfo.userId & vbCrLf
msg += "User Full Name: " & userInfo.userFullName & vbCrLf
msg += "User Email: " & userInfo.userEmail & vbCrLf
msg += vbCrLf
msg += "SessionID: " & loginResult.sessionId & vbCrLf
msg += "Auth End Point: " & authEndPoint & vbCrLf
msg += "Service End Point: " & loginResult.serverUrl & vbCrLf
Console.WriteLine(msg)
Console.WriteLine("=== Salesforceへログイン[終了] ===")
Return True
End Function
''' <summary>
''' Salesfroceからログアウト
''' </summary>
Sub Logout()
SFDCBinding.logout()
End Sub
''' <summary>
''' Salesfroceから取引先情報を取得
''' </summary>
Sub getAccounts()
Console.WriteLine("=== 取引先情報取得[開始] ===")
' 取引先レコードを取得
Dim soql As String = "SELECT Id, Name FROM Account"
Try
' SOQL実行
Dim qr As QueryResult = SFDCBinding.query(soql)
Dim msg As String = ""
' レコードの数分処理を繰り返す
While True
Dim records As sObject() = qr.records
For i As Integer = 0 To records.Length - 1
' 取引先レコード取得結果をmsgへ格納
Dim acc As Account = CType(records(i), Account)
msg += "ID: " & acc.Id & ", Name: " + acc.Name & vbCrLf
Next
If qr.done Then
' レコード数分全て処理ができた場合、処理終了
Exit While
Else
' レコード数分全処理が全て処理できていない場合、処理を繰り返す
qr = SFDCBinding.queryMore(qr.queryLocator)
End If
End While
' コンソールに取得したレコード情報を表示する
Console.WriteLine(msg)
Console.WriteLine("=== 取引先情報取得[終了] ===")
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Sub
''' <summary>
''' Salesfroceから取引先レコードを作成
''' </summary>
Sub createAccounts()
Console.WriteLine("=== 取引先レコード作成[開始] ===")
Dim result As String() = New String(1) {}
Dim account1 As Account = New Account()
account1.Name = "取引先001"
account1.BillingStreet = "403 McAdoo St"
account1.BillingCity = "Truth or Consequences"
account1.BillingState = "NM"
account1.BillingCountry = "US"
Dim accounts As Account() = {account1}
Try
Dim saveResults As SaveResult() = SFDCBinding.create(accounts)
For i As Integer = 0 To saveResults.Length - 1
If saveResults(i).success Then
Console.WriteLine("Successfully created Account ID: " & saveResults(i).id)
result(i) = saveResults(i).id
Else
Console.WriteLine("Error: could not create Account " & "for array element " & i & ".")
Console.WriteLine(" The error reported was: " & saveResults(i).errors(0).message & vbLf)
result(i) = saveResults(i).id
End If
Next
Catch e As SoapException
Console.WriteLine("An unexpected error has occurred: " & e.Message & vbLf + e.StackTrace)
End Try
Console.WriteLine("=== 取引先レコード作成[終了] ===")
End Sub
''' <summary>
''' Salesfroceから取引先レコードを更新
''' </summary>
Sub updateAccountByName(oldAccName As String, newAccName As String)
Console.WriteLine("=== 取引先レコード更新[開始] ===")
Try
' 取引先1件取得(汎用性は持たせていない)
Dim soql As String = "SELECT Id, Name FROM Account WHERE Name = '" & oldAccName & "' LIMIT 1"
Dim qr As QueryResult = SFDCBinding.query(soql)
Dim acc As New Account
While True
Dim records As sObject() = qr.records
' 取引先レコード取得
acc = CType(records(0), Account)
If qr.done Then
' レコード数分全て処理ができた場合、処理終了
Exit While
Else
' レコード数分全処理が全て処理できていない場合、処理を繰り返す
qr = SFDCBinding.queryMore(qr.queryLocator)
End If
End While
' 取引先名更新
acc.Name = newAccName
Dim updateAcc As Account() = {acc}
Dim saveResults As SaveResult() = SFDCBinding.update(updateAcc)
For Each saveResult As SaveResult In saveResults
If saveResult.success Then
Console.WriteLine("Successfully updated Account ID: " & saveResult.id)
Else
Dim errors As [Error]() = saveResult.errors
If errors.Length > 0 Then
Console.WriteLine("Error: could not update " & "Account ID " & saveResult.id & ".")
Console.WriteLine(vbTab & "The error reported was: (" & errors(0).statusCode & ") " + errors(0).message & ".")
End If
End If
Next
Catch ex As SoapException
Console.WriteLine("An unexpected error has occurred: " & ex.Message & vbLf + ex.StackTrace)
End Try
Console.WriteLine("=== 取引先レコード更新[終了] ===")
End Sub
''' <summary>
''' Salesfroceから取引先レコードを削除
''' </summary>
Sub deleteAccount(accName As String)
Console.WriteLine("=== 取引先レコード削除[開始] ===")
Try
' 取引先1件取得(汎用性は持たせていない)
Dim soql As String = "SELECT Id, Name FROM Account WHERE Name = '" & accName & "' LIMIT 1"
Dim qr As QueryResult = SFDCBinding.query(soql)
Dim acc As New Account
While True
Dim records As sObject() = qr.records
' 取引先レコード取得
acc = CType(records(0), Account)
If qr.done Then
' レコード数分全て処理ができた場合、処理終了
Exit While
Else
' レコード数分全処理が全て処理できていない場合、処理を繰り返す
qr = SFDCBinding.queryMore(qr.queryLocator)
End If
End While
' 取引先を削除処理
Dim accId As String = acc.Id
Dim ids As String() = {accId}
Dim deleteResults As DeleteResult() = SFDCBinding.delete(ids)
Dim msg As String = ""
For Each result As DeleteResult In deleteResults
If result.success Then
msg += "Delete Successfull! Deleted Record ID: " & result.id & vbCrLf
Else
Console.WriteLine("Error!: " & result.errors(0).message)
End If
Next
Console.WriteLine(msg)
Catch ex As SoapException
Console.WriteLine("An unexpected error has occurred: " & ex.Message & vbLf + ex.StackTrace)
End Try
Console.WriteLine("=== 取引先レコード削除[終了] ===")
End Sub
End Module
2. Salesforceへログイン
Login()の部分です。実行結果は以下のようになるはずです。
3. Salesforceの取引先情報の取得
getAccounts()の部分です。実行結果は以下のようになるはずです。
4. Salesforceの取引先情報の作成
createAccounts()の部分です。実行結果は以下のようになるはずです。
5. Salesforceの取引先情報の更新
updateAccountByName()の部分です。実行結果は以下のようになるはずです。
6. Salesforceの取引先情報の削除
deleteAccount()の部分です。実行結果は以下のようになるはずです。
以上です。少しでもお役に立てれば