Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VBA电子邮件问题_Vba_Excel_Email - Fatal编程技术网

VBA电子邮件问题

VBA电子邮件问题,vba,excel,email,Vba,Excel,Email,我正在尝试设置电子邮件VBA以读取特定单元格引用中的信息。我知道我可以把工作表的名称,这将工作的方式,但我需要的文件能够非常可调整。这将在我们所有的网站使用,他们都有很大的不同,所以我需要能够使任何人调整文件 代码需要读取工作表“跟踪器”单元格“C6”中的信息,如果它与数字匹配,则将多张工作表复制到临时文件中,该临时文件将创建为通过电子邮件发送 要复制的范围是C8:K8 我目前拥有以下blow代码: Option Explicit Sub Email() Dim

我正在尝试设置电子邮件VBA以读取特定单元格引用中的信息。我知道我可以把工作表的名称,这将工作的方式,但我需要的文件能够非常可调整。这将在我们所有的网站使用,他们都有很大的不同,所以我需要能够使任何人调整文件

代码需要读取工作表“跟踪器”单元格“C6”中的信息,如果它与数字匹配,则将多张工作表复制到临时文件中,该临时文件将创建为通过电子邮件发送

要复制的范围是C8:K8

我目前拥有以下blow代码:

    Option Explicit
    Sub Email()
        Dim FileExtStr As String
        Dim FileFormatNum As Long
        Dim Sourcewb As Workbook
        Dim Destwb As Workbook
        Dim TempFilePath As String
        Dim TempFileName As String
        Dim OutApp As Object
        Dim OutMail As Object
        Dim sh As Worksheet
        Dim TheActiveWindow As Window
        Dim TempWindow As Window
        Dim SendTo As String
        Dim SendCC As String
        Dim SendBCC As String
        Dim SendBody As String
        Dim Subject As String

    'Revert Main Sheet Name
    If Not ActiveSheet.Name = Sheets("Tracker").Range("B7").Value Then
    ActiveSheet.Name = Sheets("Tracker").Range("B7").Value
    End If
    'Main Code
    Application.EnableEvents = False
    Dim Answer As String
    Answer = InputBoxDK("What's the password?", "Password")
        If Answer = Sheets("Passwords").Range("D8").Value Then
    'Stop Updating Screen
        Application.ScreenUpdating = False

        If Sheets(Sheets("Tracker").Range("L7").Value).Range("D6") > 0 Then
        SendTo = Sheets(Sheets("Tracker").Range("L7").Value).Range("D6")
        End If
            If Sheets(Sheets("Tracker").Range("L7").Value).Range("D9") > 0 Then
            SendCC = Sheets(Sheets("Tracker").Range("L7").Value).Range("D9")
            End If
                If Sheets(Sheets("Tracker").Range("L7").Value).Range("D12") > 0 Then
                SendBCC = Sheets(Sheets("Tracker").Range("L7").Value).Range("D12")
                End If
                    If Sheets(Sheets("Tracker").Range("L7").Value).Range("H5") > 0 Then
                    SendBody = Sheets(Sheets("Tracker").Range("L7").Value).Range("H5")
                    End If
                        If Sheets(Sheets("Tracker").Range("L7").Value).Range("D17") > 0 Then
                        Subject = Sheets(Sheets("Tracker").Range("L7").Value).Range("D17")
                        End If

        With Application
            .ScreenUpdating = False
            .EnableEvents = False
        End With

        'Checks Range to see if they have values - email whatever has value
    If Sheets("Tracker").Range("C8").Value > 0 Then
    Sheets(Sheets("Tracker").Range("C8").Value).Visible = True
        If Sheets("Tracker").Range("D8").Value > 0 Then
        Sheets(Sheets("Tracker").Range("D8").Value).Visible = True
            If Sheets("Tracker").Range("E8").Value > 0 Then
            Sheets(Sheets("Tracker").Range("E8").Value).Visible = True
                If Sheets("Tracker").Range("F8").Value > 0 Then
                Sheets(Sheets("Tracker").Range("F8").Value).Visible = True
                    If Sheets("Tracker").Range("G8").Value > 0 Then
                    Sheets(Sheets("Tracker").Range("G8").Value).Visible = True
                        If Sheets("Tracker").Range("H8").Value > 0 Then
                        Sheets(Sheets("Tracker").Range("H8").Value).Visible = True
                            If Sheets("Tracker").Range("I8").Value > 0 Then
                            Sheets(Sheets("Tracker").Range("I8").Value).Visible = True
                                If Sheets("Tracker").Range("J8").Value > 0 Then
                                Sheets(Sheets("Tracker").Range("K8").Value).Visible = True
                                    If Sheets("Tracker").Range("K8").Value > 0 Then
                                    Sheets(Sheets("Tracker").Range("K8").Value).Visible = True
                                    End If
                                End If
                            End If
                        End If
                    End If
                End If
            End If
        End If
    End If


        Set Sourcewb = ActiveWorkbook

        'Copy the sheets to a new workbook
        With Sourcewb
            Set TheActiveWindow = ActiveWindow
            Set TempWindow = .NewWindow


'THIS IS WHERE I NEED HELP    
    If Sheets("Tracker").Range("C6").Value = 9 Then
    Else: GoTo Skip1
    Skip1:
        If Sheets("Tracker").Range("C6").Value = 8 Then
        Sheets(Sheets("Tracker").Range("C8").Value).Copy
        Else: GoTo Skip2
    Skip2:
            If Sheets("Tracker").Range("C6").Value = 7 Then
            Sheets(Sheets("Tracker").Range("C8" & "D8").Value).Copy
            End If
        End If
    End If


        End With

        'Close temporary Window
        TempWindow.Close

        Set Destwb = ActiveWorkbook

        'Determine the Excel version and file extension/format
        With Destwb
            If Val(Application.Version) < 12 Then
                FileExtStr = ".xls": FileFormatNum = -4143
            Else
                Select Case Sourcewb.FileFormat
                Case 51: FileExtStr = ".xlsx": FileFormatNum = 51
                Case 52:
                    If .HasVBProject Then
                        FileExtStr = ".xlsm": FileFormatNum = 52
                    Else
                        FileExtStr = ".xlsx": FileFormatNum = 51
                    End If
                Case 56: FileExtStr = ".xls": FileFormatNum = 56
                Case Else: FileExtStr = ".xlsb": FileFormatNum = 50
                End Select
            End If
        End With

        'Save the new workbook/Mail it/Delete it
        TempFilePath = Environ$("temp") & "\"
        TempFileName = Sourcewb.Name & " " & Format(Now, "Mmmm")

        Set OutApp = CreateObject("Outlook.Application")
        Set OutMail = OutApp.CreateItem(0)

        With Destwb
            .SaveAs TempFilePath & TempFileName & FileExtStr, FileFormat:=FileFormatNum
            On Error Resume Next
            With OutMail
                .To = SendTo
                .CC = SendCC
                .BCC = SendBCC
                .Subject = Subject
                .Body = SendBody
                .Attachments.Add Destwb.FullName
                .Display
            End With
            On Error GoTo 0
            .Close savechanges:=False
        End With

            'Delete data to create template for next month

            '''''''''''''''''''''Sheets("Helmet1").Range("I8:P1008").Value = ""


        Else: MsgBox "Wrong password", vbCritical + vbOKCancel, "Incorrect Password"
        GoTo Exit1
        End If

        'Delete the file you have send
        Kill TempFilePath & TempFileName & FileExtStr

        Set OutMail = Nothing
        Set OutApp = Nothing

       '''''''''''''''''''' Sheets("Main Page").Visible = True
       ''''''''''''''''' Sheets("Climbing Equipment").Visible = False
       ''''''''''''' Sheets("Helmet1").Visible = False

        With Application
            .ScreenUpdating = True
            .EnableEvents = True
    Exit1:
        End With
    End Sub

这不是一个“这样做,一切都会好起来”的答案,因为我不知道你想做什么。相反,它列出了所有我认为是错误的东西,我希望这些东西能让你更接近你所寻找的代码

Option Explicit
Sub CreateNewWorkbook()

  Dim ColWtcCrnt As Long
  Dim WbkDestName As String
  Dim WshtCrnt As Worksheet
  Dim WshtCrntName As Variant
  Dim WshtParam As Worksheet
  Dim WshtToCopy As Variant
  Dim WbkDest As Workbook
  Dim WbkThis As Workbook

  Application.ScreenUpdating = False

  Set WbkThis = ThisWorkbook

  Set WshtParam = Worksheets(WbkThis.Worksheets("Tracker").Range("B7").Value)

  ' Load range into a variant as a 2D array
  WshtToCopy = WshtParam.Range("C8:K8")

  Set WbkDest = Workbooks.Add

  With WbkDest

    For ColWtcCrnt = 1 To UBound(WshtToCopy, 2)
      WshtCrntName = WshtToCopy(1, ColWtcCrnt)
      If WshtCrntName <> "" Then
        Set WshtCrnt = WbkThis.Worksheets(WshtCrntName)
        WshtCrnt.Visible = xlSheetVisible
        WbkThis.Worksheets(WshtCrntName).Copy after:=.Worksheets(.Worksheets.Count)
        WshtCrnt.Visible = xlSheetVeryHidden
      Else
        ' This assumes all the names are on the left of the range
        Exit For
      End If
    Next

    ' Delete default worksheets
    For Each WshtCrnt In .Worksheets
      If Left$(WshtCrnt.Name, 5) = "Sheet" Then
        ' Delete worksheet without displaying confirmation dialog box
        Application.DisplayAlerts = False
        WshtCrnt.Delete
        Application.DisplayAlerts = True
      Else
        ' New sheets were added on right so default sheets are on the left
        Exit For
      End If
    Next

  End With

  ' Don't worry about the extension. Let Excel decide which is best.
  WbkDestName = Format(Now(), "yymmdd hhmmss")

  WbkDest.SaveAs (WbkThis.Path & "\" & WbkDestName)
  WbkDest.Close

End Sub
你似乎有两本作业本。一个包含宏和源数据,另一个由宏创建,填充选定数据,然后通过电子邮件发送。要处理此问题,有两个工作簿变量:Sourcewb和Destwb。这两个变量都设置为Active工作簿

以下可能是正确的:

Set Sourcewb = ActiveWorkbook
虽然我更喜欢:

Set Sourcewb = ThisWorkbook
ActiveWorkbook是用户启动宏或宏已激活的工作簿。此工作簿是包含宏的工作簿

例如,假设用户打开工作簿Xxx和Yyy,然后从Xxx运行Yyy中的宏。Xxx是活动工作簿,Yyy是此工作簿。您可能认为您的用户永远不会从另一个工作簿运行宏,但我已经看到了

如果Destwb应该是一个新的空工作簿,则需要的语句是:

Set Destwb = Workbooks.Add
这将创建一个新的默认工作簿并将Destwb设置为该工作簿。“默认工作簿”指的是,如果您要求新工作簿,Excel为您创建的任何工作簿。对我来说,这是一本有三张空白工作表的工作簿,分别名为“Sheet1”、“Sheet2”和“Sheet3”。您的默认工作簿可能不同;例如,“Sheet”可替换为当地语言中表示“Sheet”的单词

试试这个:

从键盘创建新工作簿。对我来说,该工作簿将命名为“Book1”,因此“Book1”将显示在任务栏中。 打开Visual Basic编辑器并将以下代码复制到新模块。 运行宏Test1。

在我的系统上,立即窗口中显示以下内容:

Book1
Book1
Book1
Book2
当前两个Debug.Print语句执行时,只有一个打开的工作簿,This工作簿和Active工作簿都引用它。对于后两个Debug.Print语句,有两个打开的工作簿。此工作簿未更改,但ActiveWorkbook现在引用新工作簿

您希望从源工作簿加载控制参数,以便每个站点都有自己的版本。这是一种很好的方法,可以让相同的代码为不同的用户做不同的事情。但是,您已使代码尽可能难以理解。考虑:

If Not ActiveSheet.Name = Sheets("Tracker").Range("B7").Value Then
    ActiveSheet.Name = Sheets("Tracker").Range("B7").Value
End If
我推断工作表“跟踪器”的B7单元格包含包含参数的工作表的名称。但是,您可以使用它重命名活动工作表。这就是你的意思吗?我认为下面的说法更合适

Dim ParamsWs As Worksheet

Set ParamsWs = Worksheets("Tracker").Range("B7").Value
我还会将密码复制到一个变量:

Dim Password As String

Password = Worksheets("Passwords").Range("D8").Value
我用的是工作表而不是工作表。这就是我的学究气;我更喜欢明确我引用的是哪种类型的工作表。由于WorksheetsPasswords.RangeD8.Value只能访问一次,因此将其值复制到变量中可以保存任何内容,但我认为这会使代码更加清晰。访问工作表比访问变量慢,因此您不希望访问同一单元格两次。更重要的是,目前还不清楚这些细胞含有什么。您现在可能知道,但在六个月或十二个月内何时需要更新此宏呢?如果其他人必须更新此宏怎么办?为什么你让人很难理解你在做什么

考虑:

If Not ActiveSheet.Name = Sheets("Tracker").Range("B7").Value Then
    ActiveSheet.Name = Sheets("Tracker").Range("B7").Value
End If
If Sheets(Sheets("Tracker").Range("L7").Value).Range("D6") > 0 Then
  SendTo = Sheets(Sheets("Tracker").Range("L7").Value).Range("D6")
End If   
这可以简化为:

With ParamsWs
  If .Range("D6").Value > 0 Then
    SendTo =.Range("D6").Value
  End If
End With   
请注意,我将句点保留在RangeD6.Value之前。如果没有句点,则引用活动工作表。对于句点,它引用With语句指定的工作表

此单元格包含字符串,因此不应将其与零进行比较。以下是正确的:

  If .Range("D6").Value <> "" Then
    SendTo =.Range("D6").Value
  End If
注:我在每次作业结束时都增加了.Value。这又是我的迂腐。值是范围的默认属性,可以省略,但如果始终指定该属性,则认为代码更清晰

嵌套严重的If语句似乎正在设置任何可见的指定工作表。这有必要吗?他们有可能被隐藏起来吗?由于If语句是嵌套的,因此不检查一个空白单元格和其余单元格。这是正确的吗?如果它是正确的,它重要吗?以下情况是否可以接受

Dim CellCrnt As Range

With ParamsWs
  For Each CellCrnt In .Range("C8:K8")
    If CellCrnt.Value <> "" Then
      Worksheets(CellCrnt.Value).Visible = True
    End If
  Next
End With
然后X可以保存范围为-2147,4的数字 83648和+2147483647

如果我写:

X = "abc"
我将得到一个“类型匹配”错误。正确地键入变量可以真正帮助避免赋值错误。但是,有时您需要一个不限于单一类型的变量。我可以写:

Dim X As Variant

X = "abc"
X = 5
X = True
使用这段代码,X将依次保存一个字符串、一个整数和一个布尔值。我无法想象这个功能的用途,但下面的内容非常有用

Dim X As Variant

X = Range("A1").Value
X = Range("A1:F1").Value
X = Range("A1:A20").Value
X = Range("A1:F20").Value
对于第一条语句,我不知道单元格A1包含什么类型的值,但这并不重要,X将保存它

在其他语句中,我加载一部分行、一部分列和一个矩形;也就是说,我加载了几个不同类型的值。在每种情况下,X都将保存一个二维数组,第一个维度保存行,第二个维度保存列

这有两个好处。1将一大块单元格复制到变量中,然后访问变量中的值可能比从工作表中单独访问值快得多。2访问同一代码块中的多个工作表可能会变得复杂。将数据复制到变量可以简化代码

我已将RangeC8:K8加载到advantage 2的变体中

如果我是正确的,这段代码将演示您所寻求的功能

Option Explicit
Sub CreateNewWorkbook()

  Dim ColWtcCrnt As Long
  Dim WbkDestName As String
  Dim WshtCrnt As Worksheet
  Dim WshtCrntName As Variant
  Dim WshtParam As Worksheet
  Dim WshtToCopy As Variant
  Dim WbkDest As Workbook
  Dim WbkThis As Workbook

  Application.ScreenUpdating = False

  Set WbkThis = ThisWorkbook

  Set WshtParam = Worksheets(WbkThis.Worksheets("Tracker").Range("B7").Value)

  ' Load range into a variant as a 2D array
  WshtToCopy = WshtParam.Range("C8:K8")

  Set WbkDest = Workbooks.Add

  With WbkDest

    For ColWtcCrnt = 1 To UBound(WshtToCopy, 2)
      WshtCrntName = WshtToCopy(1, ColWtcCrnt)
      If WshtCrntName <> "" Then
        Set WshtCrnt = WbkThis.Worksheets(WshtCrntName)
        WshtCrnt.Visible = xlSheetVisible
        WbkThis.Worksheets(WshtCrntName).Copy after:=.Worksheets(.Worksheets.Count)
        WshtCrnt.Visible = xlSheetVeryHidden
      Else
        ' This assumes all the names are on the left of the range
        Exit For
      End If
    Next

    ' Delete default worksheets
    For Each WshtCrnt In .Worksheets
      If Left$(WshtCrnt.Name, 5) = "Sheet" Then
        ' Delete worksheet without displaying confirmation dialog box
        Application.DisplayAlerts = False
        WshtCrnt.Delete
        Application.DisplayAlerts = True
      Else
        ' New sheets were added on right so default sheets are on the left
        Exit For
      End If
    Next

  End With

  ' Don't worry about the extension. Let Excel decide which is best.
  WbkDestName = Format(Now(), "yymmdd hhmmss")

  WbkDest.SaveAs (WbkThis.Path & "\" & WbkDestName)
  WbkDest.Close

End Sub

创建新窗口只会在同一工作簿上打开另一个窗口,而不会创建新的工作簿对象。工作手册。添加可能是您正在寻找的。嗨,托尼,谢谢您的帮助。如前所述,我是一个新手,自学成才,非常感谢大家的帮助。查看文件的详细信息。该文件的运行方式与网站类似。可悲的是,隐藏床单是绝对必要的,因为人们似乎有能力只摧毁他们能看到的东西。隐藏工作表后,他们无法“意外”删除整个工作表,因为excel不允许这样做。他们也无法隐藏任何东西,非常隐蔽,因此他们不会奇迹般地遇到隐藏的对象。我意识到我目前的代码非常混乱,需要大量整理。我感谢你的帮助和解释。在射程之前。这在不久的将来和今天一样非常有用。然而,该文件实际上是一个巨大的蜘蛛网。您使用ParamsWs引用的表单需要位于收集所有电子邮件信息的位置。SendTo、BCC等。但是,需要检查要复制的工作表名称的单元格所在的范围再次位于不同的工作表中。已经完成了很多操作,因此人们可以在很大程度上编辑文件,而不必真正访问该文件。即使他们拥有密码,并且可以在整个文件中更改密码,他们在销毁方面的能力也非常有限。甚至不得不取消复制和粘贴…目前我缺少的一个大部件是复制多张由设定范围确定的图纸的代码。似乎无法让它发挥作用。除此之外,我是jsut关于与文件的这一部分排序的。
Option Explicit
Sub CreateNewWorkbook()

  Dim ColWtcCrnt As Long
  Dim WbkDestName As String
  Dim WshtCrnt As Worksheet
  Dim WshtCrntName As Variant
  Dim WshtParam As Worksheet
  Dim WshtToCopy As Variant
  Dim WbkDest As Workbook
  Dim WbkThis As Workbook

  Application.ScreenUpdating = False

  Set WbkThis = ThisWorkbook

  Set WshtParam = Worksheets(WbkThis.Worksheets("Tracker").Range("B7").Value)

  ' Load range into a variant as a 2D array
  WshtToCopy = WshtParam.Range("C8:K8")

  Set WbkDest = Workbooks.Add

  With WbkDest

    For ColWtcCrnt = 1 To UBound(WshtToCopy, 2)
      WshtCrntName = WshtToCopy(1, ColWtcCrnt)
      If WshtCrntName <> "" Then
        Set WshtCrnt = WbkThis.Worksheets(WshtCrntName)
        WshtCrnt.Visible = xlSheetVisible
        WbkThis.Worksheets(WshtCrntName).Copy after:=.Worksheets(.Worksheets.Count)
        WshtCrnt.Visible = xlSheetVeryHidden
      Else
        ' This assumes all the names are on the left of the range
        Exit For
      End If
    Next

    ' Delete default worksheets
    For Each WshtCrnt In .Worksheets
      If Left$(WshtCrnt.Name, 5) = "Sheet" Then
        ' Delete worksheet without displaying confirmation dialog box
        Application.DisplayAlerts = False
        WshtCrnt.Delete
        Application.DisplayAlerts = True
      Else
        ' New sheets were added on right so default sheets are on the left
        Exit For
      End If
    Next

  End With

  ' Don't worry about the extension. Let Excel decide which is best.
  WbkDestName = Format(Now(), "yymmdd hhmmss")

  WbkDest.SaveAs (WbkThis.Path & "\" & WbkDestName)
  WbkDest.Close

End Sub