I have the following scenario (in excel 2010):
- 2 columns, one with a list of User names and the other with their related email addresses (I assigned them the named ranges: UserName and UserEmail).
- a cell ("D2") containing a list of unique usernames (selected by the user) from UserName, separated by "," (ex: "user5, user3, user9").
- The problem I need to solve is to look in UserEmail for the email addresses, corresponding to the users selected, create a string with them, separated by "," and assign it to a cell (ex: "u5@email.com, u3@email.com, u9@email.com" in D5)
Everything seemed to work fine until I tried to pass, to the function I use to merge arrays into a string (function "Merge"), the following array formula:
{=Merge(INDEX(UserEmail,MATCH(TRIM(MID(SUBSTITUTE(D2,",",REPT(" ",199)),(ROW(OFFSET(D2,,,LEN(D2)-LEN(SUBSTITUTE(D2,",",""))+1))-(ROW(D2)))*199+((ROW(OFFSET(D2,,,LEN(D2)-LEN(SUBSTITUTE(D2,",",""))+1)))=(ROW(D2))),199)),UserName,0)))}
I get the #VALUE! error. I checked the formula with shift+Ctrl+Enter in adjacent cells and it gives the correct email addresses. The problem is in the array I'm trying to pass.
Here is the function:
Public Function Merge(arr As Variant) As String
Dim tmpArr
tmpArr = Application.WorksheetFunction.Transpose((arr))
Merge = Join(tmpArr, ", ")
End Function
I've been trying to find out why I get this error and I really have no clue. I wish someone could help me. What really confuses me is that if I pass the array formula until the MATCH part, it works as expected:
{=Merge(MATCH(TRIM(MID(SUBSTITUTE(D2,",",REPT(" ",199)),(ROW(OFFSET(D2,,,LEN(D2)-LEN(SUBSTITUTE(D2,",",""))+1))-(ROW(D2)))*199+((ROW(OFFSET(D2,,,LEN(D2)-LEN(SUBSTITUTE(D2,",",""))+1)))=(ROW(D2))),199)),UserName,0))}
and I get "5, 3, 9" (the correct indexes of the selected users in UserName). So what happens to the array when I add the INDEX part? I also tried to use VLOOKUP and I got the same error:
{=Merge(VLOOKUP(TRIM(MID(SUBSTITUTE(D2,",",REPT(" ",199)),(ROW(OFFSET(D2,,,LEN(D2)-LEN(SUBSTITUTE(D2,",",""))+1))-(ROW(D2)))*199+((ROW(OFFSET(D2,,,LEN(D2)-LEN(SUBSTITUTE(D2,",",""))+1)))=(ROW(D2))),199)),A2:B11,2))}
At the moment I resorted to use a work around, which I don't really like:
{="B" & SUBSTITUTE(Merge(MATCH(TRIM(MID(SUBSTITUTE(D2,",",REPT(" ",199)),(ROW(OFFSET(D2,,,LEN(D2)-LEN(SUBSTITUTE(D2,",",""))+1))-(ROW(D2)))*199+((ROW(OFFSET(D2,,,LEN(D2)-LEN(SUBSTITUTE(D2,",",""))+1)))=(ROW(D2))),199)),UserName,0)+1),", "," & "", "" & B")}
That yields "B6 & ", " & B4 & ", " & B10" (I added 1 to the indexes because in A1 and B1 there are the headers) and then pass it to an Evaluate function:
Function ev(r As String) As Variant
ev = Evaluate(r)
End Function
so that I can use the formula =ev(D4) in "D5" and get the email addresses I need. I really wish someone could tell me a way to pass the initial formula, though, in order to avoid this workaround, or suggest me a more elegant solution. Thank you.