Public Sub未将变量传递给其他模块

时间:2018-06-05 18:42:21

标签: vba excel-vba excel

我已经制作了一个宏来根据单元格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

1 个答案:

答案 0 :(得分:0)

@Jordan 我意识到像我们大多数人一样,你可能很匆忙,但有时候通过一些计划来思考问题是一个很好的选择,可以解决以后可能引起的麻烦。

此屏幕截图显示了如何“快速”,但我不会说这是获取全局访问这些变量的最佳方式。当你前进时,如果不是模块级别,你应该尝试将变量的范围保持在子级别,因为简单的事实你会发现你不需要很多全局变量,它也可以帮助你维护你的代码。变得庞大而庞大:

方法1:项目全球化 enter image description here 在全局变量的专用模块中,您始终可以知道它们的位置:

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(或函数,如果你要将某些东西返回给调用者)。我现在没有时间用你的代码来嘲笑那个。

进入那里玩得开心。