我已经制作了一个宏来根据单元格X的值向某些人发送电子邮件。问题是我在一个模块中声明的所有变量都没有正确传递给Email模块。这两个模块都不是在项目中的“模块”选项卡之外创建的,因此不应该是问题。我已经将宏命名为public,我认为这可以防止这个问题出现,但它似乎没有起作用。有什么想法吗?附件是相关代码。
Public Sub Decision_Making_Parts_Recieved()
Worksheets("Parts Email Update").Activate
i = 2
Do
'Exits if part Number is not Present (End of List)
If Cells(i, 2) = "" Then
Exit Do
Else
End If
'Determines if Part is Marked To Be Emailed, if so, it Remembers the Contact Name For the Part
If Cells(i, 4) = "x" Or Cells(i, 4) = "X" Then
Current_Contact_Name = Cells(i, 3)
Current_Part_Number = Cells(i, 1)
Else
End If
'--------------------------------------------------------------------------------------------
'Activates the Worksheet Containing Variable Email Contact data
Worksheets("Contacts").Activate
'Search Contacts sheet for Name and finds Paired Email Address
A = 2
Do
'Exits if Name is not Present (End of List)
If Cells(A, 1) = "" Then
Exit Do
Else
End If
If Cells(A, 1) = Current_Contact_Name Then
Current_Contact_Address = Cells(A, 3)
Current_Contact_Role = Cells(A, 2)
Exit Do
Else
End If
A = A + 1
Loop
'--------------------------------------------------------------------------------------------
'Activates the Worksheet Containing Variable Email Setup data
Worksheets("Email Setup").Activate
'Creates Email Based on the Role of the Current Contact
If Current_Contact_Role = Range("B2") Then
Email_Subject = Range("A2") & " " & Current_Part_Number & " " & Range("E2")
Email_Body = Range("A4") & " " & Current_Part_Number & " " & Range("F2")
Else
End If
Call Email_Macro
'-----------------------------------------------------------------
'Updates the Parts sheet and Changes "x" (Send) to "S" (Sent)
Worksheets("Parts Email Update").Activate
Cells(i, 4) = "S"
'Resets the Variables
Current_Contact_Name = ""
Current_Part_Number = ""
Current_Contact_Address = ""
Current_Contact_Role = ""
i = i + 1
Loop
End Sub
这是我想要传递给
的模块Public Sub Email_Macro()
Dim OutApp As Object
Dim OutMail As Object
Dim strbody As String
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
strbody = Email_Body
'& vbNewLine & vbNewLine & _
' "This is line 1" & vbNewLine & _
' "This is line 2" & vbNewLine & _
' "This is line 3" & vbNewLine & _
' "This is line 4"
On Error Resume Next
With OutMail
'Adresses the Email to the Variable
.To = Current_Contact_Address
.CC = ""
.BCC = ""
.Subject = Email_Subject
.Body = strbody
'You can add a file like this
'.Attachments.Add ("C:\test.txt")
.Send 'or use .Display
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
答案 0 :(得分:0)
@Jordan 我意识到像我们大多数人一样,你可能很匆忙,但有时候通过一些计划来思考问题是一个很好的选择,可以解决以后可能引起的麻烦。
此屏幕截图显示了如何“快速”,但我不会说这是获取全局访问这些变量的最佳方式。当你前进时,如果不是模块级别,你应该尝试将变量的范围保持在子级别,因为简单的事实你会发现你不需要很多全局变量,它也可以帮助你维护你的代码。变得庞大而庞大:
方法1:项目全球化 在全局变量的专用模块中,您始终可以知道它们的位置:
Option Explicit
Public Current_Part_Number As String
Public Current_Contact_Name As String
Public Current_Contact_Address As String
Public Current_Contact_Role As String
Public Email_Subject As String
Public Email_Body As String
Private Sub initGlobalVars()
Current_Part_Number = ""
Current_Contact_Name = ""
Current_Contact_Address = ""
Current_Contact_Role = ""
Email_Subject = ""
Email_Body = ""
End Sub
不要忘记以某种方式初始化它们,不要指望你的功能,如果你改变它们会怎么样?
Option Explicit
Private Sub Workbook_Open()
'Calling a private function stands out, it is deliberate
Application.Run "Global_Vars.initGlobalVars"
End Sub
您会注意到我也命名了工作表,您接受的方法是包装您的工作表范围。
在这里,我将使用你的一段代码来完成它,在这里我也将替换你似乎用作流控制的Do,也许考虑你的流程,使用Do-Loop不是我的风格但是它可能是你的
Option Explicit
'Warning: GLOBAL VARIABLES USED
' Current_Contact_Name
' Current_Part_Number
Public Sub Decision_Making_Parts_Recieved()
Dim i As Double ' surely you do not want a global i
'you know what worksheet you are working on in this code block
With wsPartsEmailSetup
i = 2
'Exits if part Number is not Present (End of List)
If .Cells(i, 2) = "" Then
GoTo JumpOut
Else 'Do Nothing
End If
'Determines if Part is Marked To Be Emailed, if so, it Remembers the Contact Name For the Part
If .Cells(i, 4) = "x" Or .Cells(i, 4) = "X" Then
'If UCase(.Cells(i, 4)) = "X" Then
Current_Contact_Name = .Cells(i, 3)
Current_Part_Number = .Cells(i, 1)
Else 'Do Nothing
End If
End With
'Your flow control goes here, Sorry I don't use do very often, can be hard to follow
JumpOut:
'(more code) . .. maybe more jumpout places
End Sub
还有UCase功能,因此UCase(.Cells(i,4))=“X”将涵盖“x”和“X”
今天也许这对你有所帮助。也许这会让你明天考虑一些事情。
如果您的代码很短并且在顶部声明它们,您可以随时将您的潜艇移动到一个模块中,它们将是全局模块范围,您将无法在此模块之外使用它们。不要忘记初始化它们,你现在必须要处理它们,这是在子模块或模块范围内不释放的麻烦的一部分,你必须管理状态。
方法2:
Option Explicit
'inside of my module
Dim Current_Part_Number As String
Dim Current_Contact_Name As String
Dim Current_Contact_Address As String
Dim Current_Contact_Role As String
Dim Email_Subject As String
Dim Email_Body As String
Public Sub mySub1()
'do stuff with global module level variables
End Sub
Public Sub mySub2()
'do stuff with global module level variables
End Sub
方法3将它们作为参数传递给subs(或函数,如果你要将某些东西返回给调用者)。我现在没有时间用你的代码来嘲笑那个。
进入那里玩得开心。