gpt4 book ai didi

excel - 从 Excel Loop 创建电子邮件

转载 作者:行者123 更新时间:2023-12-02 11:04:09 25 4
gpt4 key购买 nike

我有这个样本表:
SheetSample

我的代码当前会根据 H 列中的姓名进行检查并创建电子邮件。因此 Approver1 会收到一封针对其所有人员的电子邮件。我已经用它来消除重复的员工姓名。示例:审批者 1 收到一封电子邮件,内容为“请批准以下所有员工的时间:”,然后有一个姓名列表...Sample1、Sample2 和 Sample3。该工作表通常会为每个审批者提供欺骗员工,如上面我的工作表所示。

该代码对于第一组重复名称效果很好(连续最多可能有 10 个相同的批准者,所有批准者都收到一封电子邮件),然后在任何单个名称中都可以正常运行。

当它遇到下一组重复批准者时,它会跳过该组中的第一行,然后为每个其他部门创建电子邮件;因此它会跳过一行,直到到达欺骗批准者部分的末尾。因此,从工作表中,批准者 1 会收到他的电子邮件,然后批准者 2 会收到她的电子邮件,但随后批准者 3 就会变得一团糟。

如何让它正确循环整个列表,为每个审批者创建一封电子邮件,并且其人员的所有相应姓名仅列出一次?

Sub DivisionApprovals()
Dim OutApp As Object
Dim OutMail As Object
Dim cell, lookrng As Range
Dim strdir As String
Dim strFilename As String
Dim sigString As String
Dim strBody As String
Dim strName As Variant
Dim strName1 As Variant
Dim strDept As Variant
Dim strName2 As String
Dim strbody2 As String
Dim strName3 As Variant

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

Set rng = ActiveSheet.UsedRange

r = 2

Do While r <= rng.rows.count
Set OutMail = OutApp.CreateItem(0)

Set strName = rng.Cells(r, 1)
Set strName3 = rng.Cells(r, 3)
strName2 = Trim(Split(strName, ",")(1))

strBody = "<Font Face=calibri>Dear " & strName2 & ", <br><br> Please approve the following divisions:<br><br>"

With OutMail
.To = rng.Cells(r, 2).Value
.Subject = "Please Approve Divisions"
List = strName3 & "<br>"


Do While rng.Cells(r, 1).Value = rng.Cells(r + 1, 1)
r = r + 1
Set strDept = rng.Cells(r, 3)
.Subject = "Approvals Needed!"
List = .HTMLBody & strDept & "<br>"
r = r + 1
.HTMLBody = List
Loop
.HTMLBody = strBody & "<B>" & List & "</B>" & "<br>" & Signature
.Display

End With

Set OutMail = Nothing
r = r + 1
Loop
Set OutApp = Nothing
End Sub

最佳答案

我删除了之前的答案,然后取消删除它,以防您需要该信息。为了不让任何人感到困惑,从 OP 代码构建的答案如下。

免责声明:我不喜欢 Do While 中递增的代码风格,这使得追踪错误变得非常困难,但我理解其意图。我已经按照我的大脑工作方式以及也许更好的编码风格在下面包含了代码,您来评判。

好吧@learningthisstuff我弄清楚发生了什么,代码假设名称已排序。没有提供的一件事是,如果部门名称相同,它将被列出多次,如果存在不同代码的欺骗,该部门对于一个人来说总是唯一的(没有欺骗?)。

这段代码有效,我只是将它作为虚拟集上的宏运行。最重要的是排序和递增逻辑,我改变了一些东西以使其更具可读性/易于理解。

我希望这对您有所帮助,并且您可以根据情况的变化进行修改。

Sub Email_Macro()
'
' Email_Macro Macro
'
Dim OutApp As Object
Dim OutMail As Object
Dim cell, lookrng As Range
Dim strdir As String
Dim strFilename As String
Dim sigString As String
Dim strBody As String
Dim strName As Variant
Dim strName1 As Variant
Dim strDept As Variant
Dim strName2 As String
Dim strbody2 As String
Dim strName3 As Variant
Dim emailWS As Worksheet
Dim nameCol As Double
Dim deptCol As Double
Dim lastRow As Double
Dim startRow As Double
Dim r As Double

Dim depList As String
deptList = ""


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


Set emailWS = ThisWorkbook.ActiveSheet
startRow = 2 ' starting row
nameCol = 1 'col of name
deptCol = 3 'col of dept

'find the last row with a name in it from the name column
lastRow = emailWS.Cells(emailWS.Rows.Count, nameCol).End(xlUp).Row

'set variable to the starting row #
r = startRow 'this is where the counting begins

'sort the data first before going through the email process
'assumes these are the only columns 1 (nameCol) thru 3 (deptCol) to sort
'assumes you are sorting based on col 1 (nameCol)
emailWS.Range(Cells(startRow, nameCol), Cells(lastRow, deptCol)).Sort key1:=emailWS.Range(Cells(startRow, nameCol), Cells(lastRow, nameCol))

Do While r <= lastRow
Set OutMail = OutApp.CreateItem(0)

Set strName = emailWS.Cells(r, nameCol)
Set strName3 = emailWS.Cells(r, deptCol)
'careful the line below assumes there is always a comma separator in the name
strName2 = Trim(Split(strName, ",")(1))

strBody = "<Font Face=calibri>Dear " & strName2 & ", <br><br> Please approve the following divisions:<br><br>"

With OutMail
.To = emailWS.Cells(r, 2).Value
.Subject = "Please Approve Divisions"
deptList = strName3 & "<br>"


Do While emailWS.Cells(r, 1).Value = emailWS.Cells(r + 1, 1)
r = r + 1
Set strDept = emailWS.Cells(r, 3)
.Subject = "Approvals Needed!"
deptList = deptList & strDept & "<br>"
Loop
.HTMLBody = strBody & "<B>" & deptList & "</B>" & "<br>" & Signature
.Display

End With

Set OutMail = Nothing

'conditionally increment the row based on the name difference
If emailWS.Cells(r, 1).Value <> emailWS.Cells(r + 1, 1) Then
r = r + 1 'increment if there is a new name or no name
deptList = "" 'reset the department list
Else 'Do nothing
End If
Loop
Set OutApp = Nothing


End Sub

屏幕截图:

enter image description here

为了证明我不会在没有一些解决方案/指导的情况下发表评论?这对我来说更容易理解和排除故障。它以非常可预测的方式逐步遍历行,并且我们根据指定的条件处理每一行。我还尝试使用变量名称,让您知道它们的用途。

Sub Email_Macro()
'
' Email_Macro Macro
'
Dim OutApp As Object 'email application
Dim OutMail As Object 'email object
Dim strBody As String 'first line of email body
Dim strName As String 'name in the cell we are processing
Dim strDept As String 'dept of the name we are processing
Dim previousName As String 'previous name processed
Dim nextName As String 'next name to process

Dim emailWS As Worksheet 'the worksheet selected wehn running macro
Dim nameCol As Double 'column # of names
Dim deptCol As Double 'column # of depts
Dim lastRow As Double 'last row of data in column
Dim startRow As Double 'row we wish to start processing on
Dim r As Double 'loop variable for row
'This will be the list of departments, we will build it as we go
Dim depList As String
Dim strSig As String 'email signature
strSig = "Respectfully, <br> Wookie"

deptList = "" 'empty intitialization
previousName = "" 'empty intialization
nextName = "" 'empty intialization

'Turn off screen updating
'Application.ScreenUpdating = False
'choose email application
Set OutApp = CreateObject("Outlook.Application")
'set worksheet to work on as active (selected sheet)
Set emailWS = ThisWorkbook.ActiveSheet
startRow = 2 ' starting row
nameCol = 1 'col of names, can also do nameCol = emailWS.Range("A1").Column
deptCol = 3 'col of depts, can also do deptCol = emailWS.Range("A3").Column
'** Advantage of the optional way is if you have many columns and you don't want to count them

'find the last row with a name in it from the name column
lastRow = emailWS.Cells(emailWS.Rows.Count, nameCol).End(xlUp).Row

'sort the data first before going through the email process using Range sort and a key
'assumes these are the only columns 1 (nameCol) thru 3 (deptCol) to sort
'assumes you are sorting based on col 1 (nameCol)
emailWS.Range(Cells(startRow, nameCol), Cells(lastRow, deptCol)).Sort key1:=emailWS.Range(Cells(startRow, nameCol), Cells(lastRow, nameCol))

'Set up our loop, it will go through every cell in the column we select in the loop
For r = startRow To lastRow
'Get the name and dept
'For the name we will split around the comma and take the second part of array (right of comma)
strName = Trim(Split(emailWS.Cells(r, nameCol), ",")(1))
strDept = emailWS.Cells(r, deptCol)

'if the next name is not blank (EOF)
If emailWS.Cells(r + 1, nameCol) <> "" Then
'assign the next name
nextName = Trim(Split(emailWS.Cells(r + 1, nameCol), ",")(1))
Else
'this is your EOF exit so assume a name
nextName = "Exit"
End If 'Else do noting on this If

If strName <> previousName Then
'Set our "new" name to previousName for looping
'process the "new" name
previousName = strName
'create the email object
Set OutMail = OutApp.CreateItem(0)
'Process as new email
With OutMail
.To = strName 'address email to the name
.Subject = "Please Approve Divisions" 'appropriate subject
deptList = strDept & "<br>" 'add the dept to dept list
'Build the first line of email body in HTML format
strBody = "<Font Face=calibri>Dear " & strName & ", <br><br> Please approve the following divisions:<br><br>"
End With
Else
'The name is the same as the email we opened
'Process Dept only by adding it to string with a line break
deptList = deptList & strDept & "<br>"
End If

'Do we send the email and get ready for another?
If strName <> nextName Then
'the next name is not the same as the one we are processing and we sorted first
'so it is time to send the email
OutMail.HTMLBody = strBody & "<B>" & deptList & "</B>" & "<br><br>" & strSig
OutMail.Display

Else 'Do Nohing
End If

Next r 'move to the next row

'nullify email reference
Set OutMail = Nothing
Set OutApp = Nothing


End Sub

如果你想防止重复的部门,那么我会这样做,你可以看到它的去向,只有一个结尾:

    End With
Else
'The name is the same as the email we opened
'Process Dept only by adding it to string with a line break
If InStr(deptList, strDept) = 0 Then
'Dept is not in the list so Add the department
deptList = deptList & strDept & "<br>"
Else
'Do nothing, the dept is already there
End If
End If

我想永远不要放弃。一切皆有可能,也许只是超出了我们当前的技能范围(所以寻求一些帮助并继续学习)。

干杯 - WWC

关于excel - 从 Excel Loop 创建电子邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47946041/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com