Start a new topic

Make Phone/Email Primary


We are trying to add API code to determine if an incoming phone or email should be marked Primary or not depending on the status of the constituents current phones or emails.

We have upgraded to RE 7.95 and this upgrade changed how phones are stored so we are having some confusion.  In order to familiarize ourselves with the new phone fields we have written some code to view the Phone Type in a MsgBox.  This way we can be sure that we are accessing the correct fields.  However, we are still having some problems as there as still fields marked PreferredAddress.Phones (which isn't where phones are stored anymore so it's confusing).

Here is the code we've started with which is returning a "blank" even though our constituent has a Preferred Email and a Home phone.

Dim oPhones as CConstitPhones

Dim oPhone as IBBPhone

For each oPhone in oRec.PreferredAddress.Phones

MsgBox ("Here is the current phone code: " & oRec.Fields(Blackbaud.PIA.RE7.BBREAPI.EPhonesFields.Phone_fld_PhoneType))

Next oPhone

Any help would be greatly appreciated!


Lisa Folger



I am one very excited API "coder"! And we're off and running again. Thank you very much!
This thread was extremely helpful in understanding how to access the phone records for a constituent using VB after the 7.95 changes. I need to search through the phone records for a constituent and then change the phoneType and/or comments when a match is found from the incoming import data. I assume that the set_fields method needs to be used to be able to change field values, but I am at a loss as to how to make this work using the GetMethod/Invoke syntax.

IOM version
RE version 7.96

Below is my basic code which produces the error "Object variable or With block variable not set"
What I don't understand is the format of the method returned with set_Fields. Do I pass the new field values in as a parameter or does this method return an object that can then be modified.

Dim phoneSetField = phone.GetType.GetMethod("set_Fields",New Type() {GetType(Integer)})
Dim returnValue = phoneSetField.Invoke(phone, New Object() {3, "6125551212"})

Is there anyone that could share an example of how this is done?

Public Overrides Sub AfterConstituentOpen(ByVal oRec As CRecord, ByVal Cancel As ImportOM.API.iCancel)
MyBase.AfterConstituentOpen(oRec, Cancel)

Dim sNumber As String
Dim sType As String
Dim bMatched As Boolean

sNumber = Import.Fields.GetByName(“PhoneNumber”).Value
sType = "Phone"
bMatched = false
'Dim phoneNum As String

Dim method As System.Reflection.MethodInfo = oRec.GetType().GetMethod ("get_Phones")
Dim phones = method.Invoke(oRec, Nothing)
Dim iPhoneCount As Integer = phones.GetType().GetMethod("Count").Invoke(phones, Nothing)
For i As Integer = 1 To iPhoneCount
Dim phone = phones.GetType.GetMethod("Item").Invoke(phones, New Object() {i})
Dim phoneGetField = phone.GetType.GetMethod("get_Fields",New Type() {GetType(Integer)})
Dim phoneSetField = phone.GetType.GetMethod("set_Fields",New Type() {GetType(Integer)})
Dim phoneID = phoneGetField.Invoke(phone, New Object() {1})
Dim phoneType = phoneGetField.Invoke(phone, New Object() {2})
Dim phoneNum = phoneGetField.Invoke(phone, New Object() {3})
phoneNum = phoneNum.Replace("(", "")
phoneNum = phoneNum.Replace(")", "")
phoneNum = phoneNum.Replace("-", "")
phoneNum = phoneNum.Replace(".", "")
phoneNum = phoneNum.Replace(" ", "")
MsgBox("ID:" & phoneID & "Import:" & sNumber & " Record:" & phoneNum)
If String.Compare(phoneNum, sNumber) = 0 Then
MsgBox ("Matched Phone type: " & phoneType & " Number: " & phoneNum )
bMatched = True
Dim returnValue = phoneSetField.Invoke(phone, New Object() {3, "6125551212"})
End If
Next i

End Sub

Your error is coming from this line:

Dim phoneSetField = phone.GetType.GetMethod("set_Fields",New Type() {GetType(Integer)})

When using GetMethod, the second parameter "New Type() {GetType(Integer)}" helps determine which signature of the set_Fields method to get. In this case, there is only one signature and it takes 2 parameters, Integer and Object. Integer being the enum for the field you want to change and Object being the value you want to set.
Thanks Nic. This helped tremendously. I was able to get the first part working, and now (of course) I have another question...

Can you tell me what additional methods are available to interact with the phone records? I am specifically interested in adding and deleting records through the API. If this is documented somewhere, a pointer to those details would be great.

I am envisioning the following, but have no idea of the syntax.

Dim method As System.Reflection.MethodInfo = oRec.GetType().GetMethod ("get_Phones")
Dim phones = method.Invoke(oRec, Nothing)
Dim phone = phones.GetType.GetMethod("Add").Invoke(phones)

Dim iPhoneCount As Integer = phones.GetType().GetMethod("Count").Invoke(phones, Nothing)
For i As Integer = 1 To iPhoneCount
Dim phone = phones.GetType.GetMethod("Delete").Invoke(phones, New Object() {i})

Thanks for your help!

You are looking for "Remove" not delete. Remove takes an object as its parameter and based on the type of that parameter will affect what is removed. You can pass in the actual phone object, or the ID of the phone as a string.


We have a different but related issue. If we would like to mark all phones and emails being imported from the source data as primary when there is data in that field (not the blanks). How can this be accomplished via IOM? Regular expression?

Hi hyimam,

This could be accomplished through a virtual field and a dictionary.  Map the virtual field to "Is primary", set the function to copy field, and the seed to whichever field contains the phone number or email.  Then apply a dictionary to that virtual field that has a value to match on of ^.+$ and a replacement value of Yes and turn on regular expressions.  This dictionary only populates "Yes" if there is a value in the cell that contains the email address or phone number.



This thread has been useful for me, but being that I haven't had much practice with object oriented programming, I'm stuck trying to get the set_Fields part to work.  I understand that I need something to specify what I want to update, but I'm not sure how.

I also am getting the Object or With block not set error.  This is what I have at the moment:

    Dim phoneSetField = phone.GetType.GetMethod("set_Fields", New Type(){GetType(Integer), GetType(Object)})

    Dim retVal1 = phoneSetField.Invoke(phone, New Object() {2, "<set phone type here>"})

Is there a chance that a future update to Omatic might make it easier to reference elements of the phone grid?

Login or Signup to post a comment