2017-11-30 10 views
1

가장 좋은 제목을 지정하는 방법이 확실하지 않지만 각 행을 반복하고 각 행마다 전자 메일을 만드는 시트가 있습니다. 첨부 파일은 Division 이름을 기반으로합니다. 현재, 모든 행에 대해 전자 메일을 생성하므로 Name 아래에있는 한 사람이 8 개의 부서를 갖고 있으면 각각 다른 첨부 파일을 가진 8 개의 전자 메일을 받게됩니다. 이것은 짜증나는 사람들입니다. 그래서 지금 루프가 되길 원합니다 (아마도 중첩 된 것입니까?). 같은 이름을 찾으면, 그 이름에 대한 하나의 이메일을 만들고 모든 부서 보고서를 첨부하십시오.각 행에 일치하는받는 사람을 기준으로 첨부 파일이있는 행별로 Excel에서 전자 메일 만들기

더 쉽게하려면 모든 중복 이름이 모두 그룹화되도록 목록을 설정했습니다. 이 예제에서는 Widgets 및 Doorknobs 첨부 파일과 함께 Name Sample Sample1에 하나의 전자 메일을 생성하려고합니다. 나머지는 보통 이메일을 하나씩받습니다. 이 작업을 수행하는 데 몇 시간 씩 노력했지만이 작업을 수행하는 데 필요한 VBA 지식이 충분하지 않습니다. 공식적으로 Excel 자체에서 할 수 있습니다. 기본적으로 A2 = A3이면 다음과 같이 말합니다. 그러나 VBA에서이 문제가 발생하려면 도움이 필요합니다. 이미지를 참조하십시오.
업데이트 : Vityata로 표시된 인수 분해 방법을 사용하여 작성한 아래 코드를 업데이트했습니다. 그것은 실행되지만 각 이메일의 속임수를 만듭니다.

Sheet Example

Option Explicit 

Public Sub TestMe() 

Dim name   As String 
Dim division  As String 
Dim mail   As String 
Dim dict   As Object 
Dim dictKey   As Variant 
Dim rngCell   As Range 

Set dict = CreateObject("Scripting.Dictionary") 

For Each rngCell In Range("b2:b4") 
    If Not dict.Exists(rngCell.Value) Then 
     dict.Add rngCell.Value, rngCell.Offset(0, -1) 
    End If 
Next rngCell 

For Each dictKey In dict.keys 
    SendMail dictKey, dict(dictKey) 
Next dictKey 

End Sub 

Public Sub SendMail(ByVal address As String, ByVal person As String) 
Dim OutApp As Object 
Dim OutMail As Object 
Dim cell As Range 
Dim strdir As String 
Dim strFilename As String 
Dim sigString As String 
Dim strBody As String 
Dim strName As String 
Dim strName1 As String 
Dim strDept As String 
Dim strName2 As String 

Application.ScreenUpdating = False 
Set OutApp = CreateObject("Outlook.Application") 

sigString = Environ("appdata") & _ 
      "\Microsoft\Signatures\Test.htm" 

      If Dir(sigString) <> "" Then 
    signature = GetBoiler(sigString) 
    Else 
    signature = "" 
    End If 


strdir = "z:\" 


strBody = "<Font Face=calibri>Please review the attached report for your department." 

For Each address In Columns("B").Cells.SpecialCells(xlCellTypeConstants) 

    If cell.Value Like "?*@?*.?*" And _ 
     LCase(Cells(cell.Row, "C").Value) = "yes" Then 
     Set OutMail = OutApp.CreateItem(0) 


    With OutMail 
     strName = Cells(cell.Row, "a").Value 
     strName1 = Cells(cell.Row, "d").Value 
     strName2 = Left(strName, InStr(strName & " ", " ") - 1) 
     strFilename = Dir("z:\*" & strName1 & "*") 

      .To = cell.Value 
      .Subject = "Monthly Budget Deficit Report for " & strName1 
      .HTMLBody = "<Font Face=calibri>" & "Dear " & address & ",<br><br>" 
      .Attachments.Add strdir & strFilename 
      .Display 'Or use Send 
    End With 

     Set OutMail = Nothing 
    End If 
Next cell 

End Sub 



Function GetBoiler(ByVal sFile As String) As String 
Dim fso As Object 
Dim ts As Object 
Set fso = CreateObject("Scripting.FileSystemObject") 
Set ts = fso.GetFile(sFile).OpenAsTextStream(1, -2) 
GetBoiler = ts.ReadAll 
ts.Close 
End Function 
+0

엑셀 테이블을 [ADO 데이터 소스] (https://stackoverflow.com/questions/2484516/vba-create-adodb-recordset-from-the-contents-of- 스프레드 시트)를 작성한 다음 각각의 사람과 전자 메일 주소를 선택하고 해당 항목과 일치하는 모든 부서를 선택하고 적절한 첨부 파일을 추가하는 루프를 작성하십시오. 엑셀에 머무르는 것이 요구됩니까? –

답변

0

이 같은 질문은 다음과 같이 요약 될 수있다 : 어떻게, VBA에서 중복 값을 방지 할 멀리 당신이 두 번 같은 전자 메일을 보내려고하지 않는 같은 주소. 당신은 씨 테스트 씨와 Test2를 두 번 이메일을 보내지 않으

enter image description here

:

따라서, 다음과 같은 데이터를 상상한다. 대안은 무엇입니까? 고유 한 메일 열을 키로하여 사전을 작성하십시오. 그런 다음 코드를 리팩터링하여 사전에 '만든'사람에게만 코드를 보냅니다.

Mr./Mrs. Test, here is your email -> [email protected] 
Mr./Mrs. Test2, here is your email -> [email protected] 
Mr./Mrs. Test3, here is your email -> [email protected] 

리팩토링의 아이디어, 당신은 "독서를 분리한다는 것입니다 :

Option Explicit 

Public Sub TestMe() 

    Dim name   As String 
    Dim division  As String 
    Dim mail   As String 
    Dim dict   As Object 
    Dim dictKey   As Variant 
    Dim rngCell   As Range 

    Set dict = CreateObject("Scripting.Dictionary") 

    For Each rngCell In Range("C2:C6") 
     If Not dict.exists(rngCell.Value) Then 
      dict.Add rngCell.Value, rngCell.Offset(0, -1) 
     End If 
    Next rngCell 

    For Each dictKey In dict.keys 
     SendMail dictKey, dict(dictKey) 
    Next dictKey 

End Sub 

Public Sub SendMail(ByVal address As String, ByVal person As String) 
    Debug.Print "Mr./Mrs. " & person & ", here is your email -> " & address 
End Sub 

이것은 당신이 무엇을 얻을 수 있습니다 : 당신은 당신이 이런 식으로 뭔가를 얻을 수 끝에 따라서, 코드를 리팩토링 할 필요가 "전자 메일 보내기"논리에서 "Excel에서"논리를 선택합니다. "Excel에서 읽는 중"논리에서는 고유 한 부분 만 읽고 "읽음"을 전달한 사람에게 전자 메일을 보냅니다.

+0

감사합니다, 당신은 내 머리 위로 길을갔습니다! 즉각적인 창에서 실행되도록 했으므로주의를 기울였습니다. 내가 잃어버린 곳에서, 내가 이미 가지고있는 코드에이 코드를 어떻게 통합 할 것인가? 그래서 모든 텍스트, 첨부 파일 등으로 전자 메일을 생성한다. 나는 원래 if/then stmts를 사용할 수 있다고 생각했지만, 그렇게 할 수는 없었다. 또한 정상적인 매크로 버튼에서 실행되도록하려면 어떻게해야합니까? 죄송합니다. 아직까지는 새것입니다! – learningthisstuff

+0

@learningthisstuff - 아이디어는 코드를 두 부분으로 나누는 것입니다. 분명한 해결책은 아니지만 일단 경험이 있으면 자연스럽게 나옵니다. 메일을 보내는 부분에서 'With OutMail'에 대한 논리를 넣어야합니다.그것은 쉽지 않을 것입니다, 당신은 아마 그것을 달성하기 위해 1-2 일 필요합니다. VBA의 함수 및 매개 변수에 대해 자세히 읽어보십시오. – Vityata

+0

대단히 감사합니다. 그러나 이것에 대해 아주 새로운 것으로, 코드를 보면 전혀 이해가 안되네요. 나는 다른 접근법을 찾아 vba 아이디어를 포기할 것입니다. 어떻게 든 혼합 될 것이라고 생각했습니다. 나는 당신이 모두 할 수있는 무엇이 굉장하기 때문에, 나는이 재료를 알고 있거나 이해했으면한다! 어쨌든 Vityata 고마워! – learningthisstuff