Сопоставить имя пользователя (массив) с электронной почтой (массив)

#excel #vba

#excel #vba

Вопрос:

Использование Excel 2013. Мой первый пост после многих лет поиска и адаптации.

Я пытаюсь сопоставить текущего пользователя приложения, то есть «Джона Смита», с его адресом электронной почты «jsmith@work.com «.

Используя две строки: 1 для пользователей (от 1 до 3), другой электронный адрес (от 1 до 3). Я хочу получить адрес электронной почты текущего пользователя для использования в отдельном подразделении, которое отслеживает текущего пользователя по электронной почте.

Я попробовал For Each i In user и установил eName на eaddress(i) . Это вернуло только последнего указанного пользователя / электронную почту.

 Private Sub (useremail)
Dim user (1 To 3), eaddress (1 To 3), fullName, eName As String

fullName = Application.UserName
user(1) = "John Smith"
user(2) = "Debbie Adams"
user(3) = "Karen Jones"

eaddress(1) = "jsmith@work.com"
eaddress(2) = "dadams@work.com"
eaddress(3) = "kjones@work.com"

For i = 1 To 3
    'For Each i In user
        fullName = user(i)
        eName = eaddress(i)
    'Exit For
    debug.print "User is " amp; fullname amp; "email to " amp; eName
Next i


  

Хотите получить eaddress / eName текущего пользователя (для использования в отдельном вложенном файле электронной почты).

Комментарии:

1. необходимо переместить ваше debug.print внутри вашего цикла.

2. @tigeravatar Хорошо, переместил d.p внутрь, и он правильно соответствует КАЖДОМУ пользователю / адресу. Мне нужно извлечь только 1 совпадение. Я думаю, что мне нужен пользователь IF (i), тогда eName = eaddress, но я не понимаю это правильно.

3. Вы жестко кодируете эти имя пользователя / адреса или они извлекаются из местоположения в файле? ваш код указывает, что они жестко запрограммированы, но это может быть только для примера.

4. @Cyril Имена и электронные письма жестко закодированы. В конечном итоге может переместиться на скрытый лист в рабочей книге, но пока…

5. Я чувствую, что ответы достаточно хороши, это не гарантирует мой вариант. Но в более надежном проекте в будущем вы можете рассмотреть возможность создания собственного класса «User» и создать коллекцию пользователей.

Ответ №1:

Вы можете использовать Dictionary , чтобы упростить это

 Private Sub UsereMail()
    Dim dictInfo, fullName

    fullName = Application.UserName

    Set dictInfo = CreateObject("Scripting.Dictionary")
    dictInfo.Add "John Smith", "jsmith@work.com"
    dictInfo.Add "Debbie Adams", "dadams@work.com"
    dictInfo.Add "Karen Jones", "kjones@work.com"

    If dictInfo.Exists(fullName) Then
        Debug.Print "User is " amp; fullName amp; " email to " amp; dictInfo(fullName)
    End If
End Sub
  

Комментарии:

1. Спасибо @pankaj Jaju! Работает как шарм. Просто нужно добавить всех моих пользователей… но это просто! (Извините, у меня слишком низкая репутация, чтобы мой голос учитывался!)

Ответ №2:

Используя ваш оригинальный подход на основе массива:

 Sub tester()
    Debug.Print "John Smith", UserEmail("John Smith") '>> jsmith@work.com
    Debug.Print "John Brown", UserEmail("John Brown") '>> [blank]
End Sub


Private Function UserEmail(userName As String) As String

    Dim user(1 To 3), eaddress(1 To 3), m

    user(1) = "John Smith"
    user(2) = "Debbie Adams"
    user(3) = "Karen Jones"

    eaddress(1) = "jsmith@work.com"
    eaddress(2) = "dadams@work.com"
    eaddress(3) = "kjones@work.com"

    m = Application.Match(userName, user, 0)
    If Not IsError(m) Then UserEmail = eaddress(m)

End Function
  

Комментарии:

1. Спасибо @Tim Williams! с ошибкой catch тоже отлично!

Ответ №3:

Другой подход, основанный на словаре, при котором список пользователей не обязательно должен располагаться в том же порядке, что и адреса электронной почты.

 Option Explicit

Sub Test()
Dim user(1 To 3)            As String
Dim eaddress(1 To 3)        As String
Dim user_dic                As Scripting.Dictionary

user(1) = "John Smith"
user(2) = "Debbie Adams"
user(3) = "Karen Jones"

eaddress(1) = "jsmith@work.com"
eaddress(2) = "dadams@work.com"
eaddress(3) = "kjones@work.com"

Set user_dic = MatchUsersToEmail(eaddress, user)

Debug.Print eaddress(1), user_dic.Item(eaddress(1))
Debug.Print eaddress(2), user_dic.Item(eaddress(2))
Debug.Print eaddress(3), user_dic.Item(eaddress(3))

End Sub

Public Function MatchUsersToEmail(ByRef email_array() As String, ByRef user_array() As String) As Scripting.Dictionary
' Returns a scripting dictionary where the email address returns the user name
Dim my_users                As Scripting.Dictionary
Dim my_user                 As Variant
Dim my_email                As Variant
Dim my_name()               As String
Dim my_key                  As String
    Set my_users = New Scripting.Dictionary

    For Each my_email In email_array
        ' Add the email address as the key
        my_users.Add Key:=CStr(my_email), Item:=vbNullString

    Next

    For Each my_user In user_array
        my_name = Split(LCase$(my_user))
        my_key = Left$(my_name(0), 1) amp; my_name(1) amp; "@work.com"
        my_users.Item(my_key) = my_user

    Next

    Set MatchUsersToEmail = my_users

End Function