Looking for help?
< All Topics
Print

VBA Interface

You can use VBA to work with the underlying SFDC database access functions of XL-Connector. You can’t record macros with XL-Connector buttons  so you have to work with VBA code in order to do automation with the SFDC data.

Before you start, you have to get the XL-Connector COM addin properly instantiated in your worksheet’s memory space. And that means putting this code at the top of your VBA module or function:

Dim automationObject As Object
Set automationObject = Application.COMAddIns("TaralexLLC.SalesforceEnabler").Object

If you will be calling the plug-in functions from multiple places in your code, it’s a good practice to have a global variable that is only assigned once and then access it by calling a function:

Global automationObject As Object
Function GetXLC() As Object
    If automationObject Is Nothing Then
        Set automationObject = Application.COMAddIns("TaralexLLC.SalesforceEnabler").Object
    End If
    Set GetXLC = automationObject
End Function

Before you begin writing code…

  • The easiest way to automate is to use VBA to run Flow Steps that have been saved in your worksheet(s).
  • When you’re working with queries, remember it’s only SOQL syntax, not full SQL. Use XL-Connector’s query-builder window to test any query string that you have.
  • You’d think that the catch-all “Variant” array data type would be fine swallowing a string array… but it isn’t. So pay attention when a method’s return array is shown as being strings.
  • When you get a dateTime string from a query, it will be in this format: YYYY-MM-DD HH:MM:SS, but when you want to query based on a dateTime, you need to use this one: YYYY-MM-DDTHH:MM:SSZ.
  • If your query has an empty result set, you will not get an array back from SFDC: you’ll get a null object that will cause error messages in your code if you try to do anything with it.

Here are the calls available to your VBA code:

Get current plug-in version

Version

Example:

Set automationObject = Application.COMAddIns("TaralexLLC.SalesforceEnabler").Object
res = automationObject.Version
MsgBox (res)

Log in to Salesforce.com

LogIn (username, password+securityToken, host, errorText)

Returns true or false, in case of false – examine the error text

Example:

Public Function testLogin() 
  Dim automationObject As Object 
  Set automationObject = Application.COMAddIns("TaralexLLC.SalesforceEnabler").Object
  Result = automationObject.LogIn("test@xappex.com", "PasswordSecurityToken", "https://login.salesforce.com", Error)
End Function

Log in to Salesforce.com using a previously saved login (by alias)

LogInWithAlias(alias, errorText)
Returns true or false, in case of false – examine the error text

Example:

Public Function testLoginWithAlias() 
  Dim automationObject As Object 
  Set automationObject = Application.COMAddIns("TaralexLLC.SalesforceEnabler").Object
  Result = automationObject.LogInWithAlias("Xappex Dev", Error)
End Function

Show the Web and SSO Login Window

ShowSSOLogin([optional] url)

If the optional url parameter is passed – the window will open and automatically go to that url. Use it to specify your custom SSO page address, for example https://myDomain.my.salesforce.com

Log out of SFDC instance

LogOut ()

Returns true or false

Check if the user is currently logged in to Salesforce

IsLoggedIn ()

Returns true or false

Put XL-Connector in Safe Mode (Read Only, disabling insert/update/delete buttons but NOT VBA actions)

 SetReadOnly (True)

Return from Safe Mode

SetReadOnly (False)

Get the URL of the instance you are grabbing data from

string GetServerURL()

Get the login name of the currently logged in user
string GetLoggedInUserName()

Get the Salesforce Id of the currently logged in user
string GetLoggedInUserId()

Get the Salesforce Profile Id of the currently logged in user
string GetLoggedInUserProfileId()

Get the Salesforce UserRole Id of the currently logged in user
string GetLoggedInUserRoleId()

Get all the objects in the system

string[,] GetObjects(errorText))

Get all the field names from an object

string[,] GetObjectFields(objAPIName, out string errorText)

Get all the picklist values names for a field

string[,] GetPickListValues(string objectName, string fieldName, out string errorText)
///returns three columns: value, label, isActive

Retrieve data

object[,] RetrieveData(string query, bool label, bool queryAll, out string errorText, [bool toolingAPI])

Update records

string[,] UpdateData(variant data, string objName, bool useAssgnRule, string assignmentRuleId, bool ignoreNativeDuplicateChecks, out string errorText)

The data parameter can be either a 2-dimensional array (see samples below), or a Range object. , there must be a flow step with correct mappings present in the sheet.

Insert records

string[,] InsertData(variant data, string objName, bool useAssgnRule, string assignmentRuleId, bool ignoreNativeDuplicateChecks, out string errorText)

The data parameter can be either a 2-dimensional array (see samples below), or a Range object. If you choose to use the range, , there must be a flow step with correct mappings present in the sheet.

Upsert records

string[,] UpsertData(variant data, string objName, string extIdColumn, bool useAssgnRule, string assignmentRuleId,bool ignoreNativeDuplicateChecks, out string errorText)

The data parameter can be either a 2-dimensional array (see samples below), or a Range object. If you choose to use the range, there must be a flow step with correct mappings present in the sheet

Delete records

public string[,] DeleteData (variant Ids, out string errorText)

The data parameter can be either an array of Ids, or a Range object. If you choose to use the range, there must be a flow step with correct mappings present in the sheet.

Example:

Public Function testDelete() 
  Dim xlObj As Object 
  Set xlObj = Application.COMAddIns("TaralexLLC.SalesforceEnabler").Object
  Dim xlResult As Variant 
  Dim xlArr() As Variant 
  Dim xlErr As String 
  Dim listObj As ListObject 
  Dim listCol As ListColumn 
  Set listObj = Range("Opportunities").ListObject 'Excel table named "Opportunities"
  Set listCol = listObj.ListColumns("Id") '"Id" column from that table
  Dim i As Long Dim rowCount As Long
  rowCount = listCol.DataBodyRange.Rows.Count 
  If (rowCount = 0) Then Return 
  ReDim xlArr(0 To rowCount - 1) As Variant 
  For i = 1 To rowCount 
    xlArr(i - 1) = listCol.DataBodyRange.Cells(i, 1).value
    Next i 
  xlResult = xlObj.DeleteData(xlArr, xlErr) 
End Function

Pull report from SFDC by Id – returns a path to the saved CSV file. Please note that it does not put it into the open Excel worksheet. You will need to read the file, parse the CSV file and process the data with your own VBA code. If you want to trigger a report refresh from VBA, pull it manually first and then use the Refresh VBA command to repopulate the report data in your spreadsheet.

string RunReport(string id, out string errorText)

Refresh the data in the active worksheet

string Refresh(False)

Returns an empty string in case of success, otherwise – error text.

Refresh the data all worksheets

string Refresh(True)

Returns an empty string in case of success, otherwise – error text. Example:

Sub test()
   Dim automationObject As Object
   Set automationObject = Application.COMAddIns("Salesforce Enabler for Excel").Object
   error_msg = automationObject.Refresh(True)
End Sub

Run the Flow in a given worksheet

bool RunFlow(Worksheet ws, out error)

This function will run all active Flow steps in a given worksheet. If there’s an error, the function will return False and the error text will be in the ‘error’ output variable.
Example:

Dim automationObject As Object 
Set automationObject = Application.COMAddIns("TaralexLLC.SalesforceEnabler").Object
run_result = automationObject.RunFlow(Worksheets("Sheet1"), errorText)
if not run_result then
   msgbox (errorText)
end if

Run all Flows in the active workbook

bool RunAllFlows(out error)

Run a single Flow Step 

bool RunFlowStep(Worksheet ws, string flowStepName, out string errorText)

This function will run the specified Flow Step in the specified worksheet. If there’s an error, the function will return False and the error text will be in the ‘errorText’ output variable.

Example:

Dim automationObject As Object 
Set automationObject = Application.COMAddIns("TaralexLLC.SalesforceEnabler").Object
run_result = automationObject.RunFlowStep(Worksheets("Sheet1"), "MyFlowStep", errorText)
if not run_result then
msgbox (errorText)
end if

Run anonymous Apex code in Salesforce:

string RunApexCode(string apexCode)

This function will run the specified Apex code in Salesforce and return the result. ‘success’ is returned if the code ran successfully, otherwise – you’ll get the error description.

Retrieve metadata files from Salesforce.com

This command will download all metadata files (the XML goodies you can see in Eclipse) of the specified object type and put them into the specified folder. Be careful, if you pull the same metadata files twice, the second time will overwrite the files pulled during the first time. Please note that if you are specifying standard object types, you will need to have “*” as the first item in the array (which gets you all the custom object definitions… don’t ask me why the SFDC guys did it that way…). The array that is returned by this call will contain the names of every metadata file pulled during the call.

 GetMetadata(Array type, string folderName, out string errorText, [Array additionalTypes])

The additionalTypes parameter is optional, if it’s omitted – Array(“*”) will be used.

Here’s a snippet of how to use this call:

Dim sObjects()
Dim sTypes()
sTypes = Array("CustomObject") 
sObjects = Array("*", "Task", "Event", "Campaign", "CampaignMember", "Lead", "Account", "Contact", _
 "Opportunity", "OpportunityLineItem", "Case", "Entitlements", "Contract", _
 "Solutions", "Product", "Pricebook", "Ideas", "Question", "Reply", "Asset", "User")
 ' this is the list of standard objects, after the first * which indicates "get all custom objects"
 Dim MDfiles() as String
 MDfiles = automationObject.GetMetadata(sTypes, "C:\Temp", error, sObjects)
 ' MDfiles() is the array of file names that will be created, in this case, in the C:\Temp\Object directory
 Dim fso As New FileSystemObject
 Dim fname As TextStream
 ' do NOT use VBA's internal "Open File for Input" method, as the Input Line statement will draw in the 
 ' entire file as a single line of text. Yes, really.
 ' Instead use the Microsoft Scripting Library methods that do more sensible things...you may need to add
 ' it to your References for the project.
 Set fname = fso.OpenTextFile(MDfiles(0)) ' this is just an example of opening the first file in this list
 Do While Not fname.AtEndOfStream ' this is fancy-talk for EOF
 debug.print (fname.ReadLine) ' pull in the first line of text, as terminated by an LF (ASC-10) character
 Loop
 fname.Close ' do your housekeeping to avoid messes!

And here’s a sample of usage of most of the calls above:

Sub Button1_Click()
   Dim automationObject As Object 
   Set automationObject = Application.COMAddIns("TaralexLLC.SalesforceEnabler").Object
   Dim error
   result = automationObject.LogIn("my@login.com", "password+token", "https://login.salesforce.com", errorText)   
   If result = False Then
       MsgBox errorText
       End
   End If
   
   'getting information about object fields
   fieldinfo = automationObject.GetObjectFields("Account", errorText)
   If Not error = Empty Then
       MsgBox errorText
       End
   End If
   numberOfFields = UBound(fieldinfo, 2)
   field1Name = fieldinfo(0, 0)
   field1Label = fieldinfo(1, 0)
   field1Type = fieldinfo(2, 0)
   field2Name = fieldinfo(0, 1)
   field2Label = fieldinfo(1, 1)
   field2Type = fieldinfo(2, 1)
   'fieldNName = fieldinfo(0, N - 1)
   'fieldNLabel = fieldinfo(1, N - 1)
   'fieldNType = fieldinfo(2, N - 1)
   
   ar = automationObject.RetrieveData("SELECT Id,name FROM Car_Order__c", False, False, errorText)
   If Not error = Empty Then
       MsgBox errorText
       End
   End If
   'the result table is a 2-dimensional array with the first row as column headers
   NumberOfRows = UBound(ar, 2)
   NumberOfColumns = UBound(ar, 1)
   For Column = 0 To NumberOfColumns
       ColumnName = ar(Column, 0)
       For Row = 1 To NumberOfRows
           CellValue = ar(Column, Row)
       Next Row
   Next Column
   
   'Now let's update some data in Salesforce
   Dim MyArray(1, 3) As Variant
   MyArray(0, 0) = "Id"
   MyArray(1, 0) = "Name"
   MyArray(0, 1) = "a03E0000007igvaIAA"
   MyArray(1, 1) = "MyName"
   MyArray(0, 2) = "a03E0000009HszSIAS"
   MyArray(1, 2) = "It Works!"
   MyArray(0, 3) = "a03E0000007igvbIAA"
   MyArray(1, 3) = "Another Record"
   
   result = automationObject.UpdateData(MyArray, "Car_Order__c", False, Nothing, false, errorText)
   If Not error = Empty Then
       MsgBox errorText
       End
   End If
   UpdatedRecord1Id = result(0, 0) 'first record Id
   UpdatedRecord2Id = result(0, 1) 'second record Id
   UpdatedRecord3Id = result(0, 2) 'third record Id
   'UpdatedRecordNId = result(0, N - 1) 'Nth record Id
   Record1UpdateResult = result(1, 0) 'first record update status ("OK" or error message)
   Record2UpdateResult = result(1, 1) 'second record update status ("OK" or error message)
   Record3UpdateResult = result(1, 2) 'third record update status ("OK" or error message)
   'RecordNUpdateResult = result(1, N - 1) 'Nth record update status ("OK" or error message)
End Sub
Table of Contents