Vba 使用while和when编译错误
我目前在While和Wend语句中遇到了一个问题,但首先让我给出一个小的背景背景来解释我试图实现的目标。 我有一个按钮,单击该按钮,创建一个新的工作表,其中包含一个人的姓名,并使用自动筛选从源表中复制与他们相关的整行(其中有他们的姓名)。这没有任何问题,使用下面的代码(你们中的许多人可能会从Ron Bruin那里认识到),我通过一个类似的代码(有点像我下面包含的通用代码)设法通过点击按钮将信息发送给我添加的所有人,但这带来了一点问题。 假设总共有30人,人数和姓名都是常数。如果所有的名字都以工作表的形式出现,那么我就可以发送而没有任何问题。问题是,这是每月一次的,在某些月份,这30人中并非所有人都会出现在工作表上。举下面的例子,这意味着如果John Doe和Jane Doe都有一个包含数据的工作表,我可以发送,但是如果Jane没有出现在源表中,那么代码就会中断。我意识到那时我需要某种If语句,经过多次尝试,我都无法工作。然后我发现了While/Wend语句,它似乎是用于此目的的更好选项。从逻辑上讲,我试图在下面完成的是“虽然有一个名为John Doe的工作表”,然后执行它下面的所有代码,如果不满足条件,则在Wend之后继续执行”。目前我认为我有一个问题,可能有两个问题: 第一个是在执行代码时,我得到一个错误“compileerror:Wend without While” 根据答案,这似乎与未终止的IF语句有关,但事实似乎并非如此 第二个原因是我无法测试 While(工作表(“John Doe”)。名称“John Doe”)是一个有效的While语句,它将按照我的意愿工作 如果有人能解释为什么这不起作用,我将不胜感激,这样我就可以从中学习。感谢你花时间阅读这篇文章!如果需要更多信息或我写的东西不清楚,请让我知道Vba 使用while和when编译错误,vba,excel,Vba,Excel,我目前在While和Wend语句中遇到了一个问题,但首先让我给出一个小的背景背景来解释我试图实现的目标。 我有一个按钮,单击该按钮,创建一个新的工作表,其中包含一个人的姓名,并使用自动筛选从源表中复制与他们相关的整行(其中有他们的姓名)。这没有任何问题,使用下面的代码(你们中的许多人可能会从Ron Bruin那里认识到),我通过一个类似的代码(有点像我下面包含的通用代码)设法通过点击按钮将信息发送给我添加的所有人,但这带来了一点问题。 假设总共有30人,人数和姓名都是常数。如果所有的名字都以工作
Sub emailfitest()
Dim OutApp As Object
Dim OutMail As Object
Dim rng As Range
Dim strbody As String
On Error Resume Next
While (Worksheets("John Doe").Name <> "John Doe")
Set rng = Sheets("John Doe").Range("A1:K80").SpecialCells(xlCellTypeVisible)
On Error Resume Next
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.SentonBehalfofName = "bla@domain.com"
.To = "blabla@domain.com"
.CC = ""
.BCC = ""
.Subject = "Bla bla 123"
.WrapText = True
.HtmlBody = "<HTML><BODY><p> " & strTo & " <br /> " & strCC & " <br /> </p>" & _
"<p>Hi Bla, " & " </B> <br /> <br /< </p>" & _
"<p>text1<br /> <br /> </p> " & _
"<p>text2.<br /> </p> " & _
"<li>bulletpoint 1<br /> </li> " & _
"<li>bulletpoint2<br /> <br /> </li> " & _
"<p>text3<br /> </p> " & _
"<p> text4 <A href=https://blabbla.com>Here</A><br /></p>" & _
"<p>text5</p> <br /> <br />" & _
"<p>text6 <br /></p>" & RangetoHTML(rng)
.Send
Wend
End With
On Error GoTo 0
With Application
.EnableEvents = True
.ScreenUpdating = True
Set OutMail = Nothing
Set OutApp = Nothing
While (Worksheets("Jane Doe").Name <> "Jane Doe")
'---------------------------------------------------------------------------------
Set rng = Sheets("Jane Doe").Range("A1:K80").SpecialCells(xlCellTypeVisible)
On Error Resume Next
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.SentonBehalfofName = "blabla@domain.com"
.To = "thingsandstuff@domain.com"
.CC = ""
.BCC = ""
.Subject = "hello1233h12"
.WrapText = True
.HtmlBody = "<HTML><BODY><p> " & strTo & " <br /> " & strCC & " <br /> </p>" & _
"<p>Hi Jane" & " </B> <br /> <br /< </p>" & _
"<p>text1<br /> <br /> </p> " & _
"<p>text2<br /> </p> " & _
"<li>bulletpoint1<br /> </li> " & _
"<li>bulletpoint2<br /> <br /> </li> " & _
"<p>text3<br /> </p> " & _
"<p>blablabla <A href=https://bblablabsa.com >Here</A><br /></p>" & _
"<p>text4</p> <br /> <br />" & _
"<p>text5<br /></p>" & RangetoHTML(rng)
.Send
Wend
End With
On Error GoTo 0
With Application
.EnableEvents = True
.ScreenUpdating = True
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
--------------------------------------------
Function RangetoHTML(rng As Range)
' Changed by Ron de Bruin 28-Oct-2006
' Working in Office 2000-2013
Dim fso As Object
Dim ts As Object
Dim TempFile As String
Dim TempWB As Workbook
TempFile = Environ$("temp") & "\" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm"
'Copy the range and create a new workbook to past the data in
rng.Copy
Set TempWB = Workbooks.Add(1)
With TempWB.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial xlPasteValues, , False, False
.Cells(1).PasteSpecial xlPasteFormats, , False, False
.Cells(1).Select
Application.CutCopyMode = False
On Error Resume Next
.DrawingObjects.Visible = True
.DrawingObjects.Delete
On Error GoTo 0
End With
'Publish the sheet to a htm file
With TempWB.PublishObjects.Add( _
SourceType:=xlSourceRange, _
Filename:=TempFile, _
Sheet:=TempWB.Sheets(1).Name, _
Source:=TempWB.Sheets(1).UsedRange.Address, _
HtmlType:=xlHtmlStatic)
.Publish (True)
End With
'Read all data from the htm file into RangetoHTML
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2)
RangetoHTML = ts.readall
ts.Close
RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
"align=left x:publishsource=")
'Close TempWB
TempWB.Close savechanges:=False
'Delete the htm file we used in this function
Kill TempFile
Set ts = Nothing
Set fso = Nothing
Set TempWB = Nothing
End Function
Sub-emailfitest()
Dim OutApp作为对象
将邮件变暗为对象
变暗rng As范围
像弦一样暗的链子
出错时继续下一步
While(工作表(“John Doe”)。名称“John Doe”)
Set rng=板材(“John Doe”).范围(“A1:K80”).特殊单元(xlCellTypeVisible)
出错时继续下一步
Set-OutApp=CreateObject(“Outlook.Application”)
Set-OutMail=OutApp.CreateItem(0)
出错时继续下一步
发邮件
.SentonBehalfName=”bla@domain.com"
.To=”blabla@domain.com"
.CC=“”
.BCC=“”
.Subject=“Bla Bla 123”
.WrapText=True
.HtmlBody=“”&strTo&“
”&strc&“
”和_
“Hi Bla,&”
你的以
结尾和Wend
是错误的选择
While (Worksheets("Jane Doe").Name <> "Jane Doe")
...
With OutMail
...
...
End With '// <~~ Close the With block first.
Wend '// <~~ THEN close the While block
这意味着您不能在第二次运行时将与OutMail
一起使用,因为您仍然在第一个与
块中
所有With
语句必须在块的末尾用End With
完成。将End With
和Wend
语句交换。您需要按照与打开子句相反的顺序关闭这些子句。顺便说一句:您真的应该试着理解自己的代码。例如,我在您的代码中计算了6次错误恢复(使用它根本不是一个好主意)。这向我表明,您使用了大量的复制+粘贴。但你需要知道你在那里真正做了什么。这也有助于更好地构造代码。除了End with和Wend语句之外,我不确定您的代码是否会运行。。而(工作表(“John Doe”)。命名为“John Doe”),这将如何工作?也许我只是不明白…@Rory,谢谢你解决了这个问题@cboden:我有点匆忙地复制了这个模块,但我在其他地方有一个干净的备份。我还避免了使用on-error-go-to-label x(作为解决这个问题的一种方法,我已经介绍过了。但无论如何,我的VBA技能基本上都是从不同的来源复制和粘贴,并尝试通过反复试验和一些谷歌搜索来获得一些东西。谢谢你的提醒!嗨,宏人,你的建议奏效了,谢谢你的解释!现在唯一的问题是em是While语句的第二个,因为当有一个没有给定名称的工作表时,代码会中断。我尝试将其切换到类似While(工作表(“John Doe”).name=True)的位置,但它也没有将此-->While(工作表(“John Doe”).name=True)切换到此While(工作表(“John Doe”).Name,现在代码至少运行了,尽管它被卡在循环中。我想看看我是否能找出问题的那一部分,因为否则它会开始连续发送电子邮件。这种情况永远都是真的-所以循环永远不会结束,你到底想在那里测试什么?循环什么时候结束?嗨,基本上我想要它要做的是使用While语句验证是否存在工作表John Doe,并在这种情况下向目标发送一封包含指定范围和文本的电子邮件。但是,如果没有找到John Doe的工作表,则应直接跳到Jane Doe,如果没有跳到下一个per,则另一个While语句将验证工作表Jane Doe是否存在son等,直到结束sub。需要检查现有工作表的人员每月都是相同的。在任何给定的月份,这些人员中的1人可能没有工作表,因此该人员不应收到电子邮件。
With Application
.EnableEvents = True
.ScreenUpdating = True