Start a new topic

Make Phone/Email Primary

Hi,

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!

Thanks,

Lisa Folger

 

W


Hello,


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.


Thanks,


John

Those are methods off the CConstitPhoneClass type. You would invoke them the same way the get_Phones method is off of oRec.

Dim method As System.Reflection.MethodInfo = oRec.GetType().GetMethod ("get_Phones")
Dim phones = method.Invoke(oRec, Nothing)
Thanks Nic. We tried that and got the following error:

Source row 1 produced Excel error row 2: Error in custom code AfterConstituentOpen: Ambiguous match found. Line:0

Here is our code ( we simply want to msgbox the phone/email type )

Public Overrides Sub AfterConstituentOpen(ByVal oRec As CRecord, ByVal Cancel As ImportOM.API.iCancel)
MyBase.AfterConstituentOpen(oRec, Cancel)
Dim method As System.Reflection.MethodInfo = oRec.GetType().GetMethod ("get_Phones")
Dim phones = method.Invoke(oRec, Nothing)

Dim fmethod As system.reflection.methodinfo = oRec.GetType().GetMethod ("get_Fields")
Dim fields = fmethod.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 field = fields.GetType.GetMethod("Item").Invoke(fields, New Object() {i})
field = fields(2)
MsgBox ("Phone type: " & field)
Next i
End sub

Lisa
The fields property exists off of the phone object, so that is the "get_Fields" method you want to retrieve. From there you can invoke the method, passing in the phone and the field number you want to return. I've adjusted your code below.

Public Overrides Sub AfterConstituentOpen(ByVal oRec As CRecord, ByVal Cancel As ImportOM.API.iCancel)
MyBase.AfterConstituentOpen(oRec, Cancel)
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 phoneType = phone.GetType.GetMethod("get_Fields").Invoke(phone, New Object() {2})
MsgBox ("Phone type: " & phoneType)
Next i
End sub
Thanks Nic. We'll give that a try.
All code is in place, but we are still getting the "ambiguous match" error. After some research, my (very novice) guess is that we are trying to use the same fields and return two different things at the same time. We want the phonetype to count so we make sure we get through all of them, but then we actually want the phonetype itself. I commented out part of the code that tries to get the phonetype, and the error disappears, so I think I'm on the right track - but all of my other (again, very novice) guesses, are not helping to get past this.
The issues is that get_Fields has two signatures and the GetMethod call doesn't know which one you want. I've updated the code to specify that you want the get_Fields method that accepts an integer parameter.

Public Overrides Sub AfterConstituentOpen(ByVal oRec As CRecord, ByVal Cancel As ImportOM.API.iCancel)
MyBase.AfterConstituentOpen(oRec, Cancel)
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 phoneType = phone.GetType.GetMethod("get_Fields",New Type() {GetType(Integer)}).Invoke(phone, New Object() {2})
MsgBox ("Phone type: " & phoneType)
Next i
End sub
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 3.2.3.0
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
Barbara,

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!
Barbara,

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.
Thanks for the help Nic. I will play around with this and hopefully get it to work.
Hi Nic,

Here is my code based on your post above. I'm just trying to see what's in the fields so I'm sure that I have the correct fields etc. However, I get an error in the code:
'phone is not declared. It may be inaccessible due to its protection level'

Here is the code I'm using:

Public Overrides Sub AfterConstituentOpen(ByVal oRec As CRecord, ByVal Cancel As ImportOM.API.iCancel)
MyBase.BeforeConstituentSave(oRec, Cancel)
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() {1})
Next i

For Each phone In phones
MsgBox ("Phone type: " & oRec.Fields(Blackbaud.PIA.RE7.BBREAPI.ECONSTITPHONEFIELDS.CONSTIT_PHONES_fld_IS_PRIMARY))
Next phone
End sub

Any ideas?

thanks for any help you can shed on this.

Lisa
Login to post a comment