如何判断是使用VBA从电子邮件还是从桌面运行宏?

时间:2019-03-06 14:29:55

标签: excel vba email desktop

我已经开发宏很多年了。我们的用户从本地驱动器运行这些宏。但是,由于营业额,新员工等原因,此信息并不总是传递给新用户。

我们有一个中心位置,用户可以在其中下载这些宏的副本。如果他们遵循步骤,它将宏保存到本地驱动器。但是,有时用户会通过电子邮件从同事那里获得宏。然后,他们从电子邮件中打开或将其保存到桌面。

如果他们从电子邮件或桌面运行我们的宏,则可能会出现问题;通常需要有人与我们联系以获得支持。我想减少支持电话的数量。

我想知道是否有一种方法可以确定宏是从电子邮件还是从用户的桌面打开的。理想情况下,我正在考虑将代码添加到“打开时”模块中,并显示一条消息,告诉用户在打开/运行宏之前将宏保存到本地驱动器。

但是,我不确定如何识别这两个位置。我之前使用过“ Path”属性,但是这些宏可以位于数百个现场办公室的任意数量的驱动器上。我认为最好先识别电子邮件或桌面位置,然后显示消息。

我们大多数用户都使用Office 2010或2016。感谢您的帮助。.........

2 个答案:

答案 0 :(得分:4)

如果您从邮件中打开工作簿并调试using System; using System.Collections.Generic; using System.Linq; using System.IO; using System.Text; using System.Threading.Tasks; using System.Xml.XPath; using MigraDoc.DocumentObjectModel; using MigraDoc.DocumentObjectModel.Shapes; using MigraDoc.DocumentObjectModel.Shapes.Charts; using MigraDoc.DocumentObjectModel.Tables; using MigraDoc.Rendering; using System.Diagnostics; using PdfSharp.Pdf; namespace ConsoleApplication2 { class Program { static void Main() { // Create a MigraDoc document Document document = CreateDocument(); //string ddl = MigraDoc.DocumentObjectModel.IO.DdlWriter.WriteToString(document); //MigraDoc.DocumentObjectModel.IO.DdlWriter.WriteToFile(document, "MigraDoc.mdddl"); PdfDocumentRenderer renderer = new PdfDocumentRenderer(unicode: true); renderer.Document = document; renderer.RenderDocument(); // Save the document... //renderer.PdfDocument.Save(filename); renderer.PdfDocument.Save("example.pdf"); // ...and start a viewer. //Process.Start(@"C:\pdf.pdf"); } /// <summary> /// Creates a Document /// </summary> public static Document CreateDocument() { // Create a new MigraDoc document Document document = new Document(); DefineStyles(document); DefineCover(document); DefineParagraphsTest(document); return document; } /// <summary> /// Defines the styles used in the document. /// </summary> public static void DefineStyles(Document document) { // Get the predefined style Normal. Style style = document.Styles["Normal"]; // Because all styles are derived from Normal, the next line changes the // font of the whole document. Or, more exactly, it changes the font of // all styles and paragraphs that do not redefine the font. style.Font.Name = "Times New Roman"; // Heading1 to Heading9 are predefined styles with an outline level. An outline level // other than OutlineLevel.BodyText automatically creates the outline (or bookmarks) // in PDF. style = document.Styles["Heading1"]; style.Font.Name = "Arial"; style.Font.Size = 18; style.Font.Bold = true; style.Font.Color = Colors.DarkBlue; style.ParagraphFormat.PageBreakBefore = true; style.ParagraphFormat.SpaceAfter = 8; style = document.Styles["Heading2"]; style.Font.Size = 12; style.Font.Bold = true; style.ParagraphFormat.PageBreakBefore = false; style.ParagraphFormat.SpaceBefore = 6; style.ParagraphFormat.SpaceAfter = 6; style = document.Styles["Heading3"]; style.Font.Size = 10; style.Font.Bold = true; style.Font.Italic = true; style.ParagraphFormat.SpaceBefore = 6; style.ParagraphFormat.SpaceAfter = 3; style = document.Styles[StyleNames.Header]; style.ParagraphFormat.AddTabStop("16cm", TabAlignment.Right); style = document.Styles[StyleNames.Footer]; style.ParagraphFormat.AddTabStop("8cm", TabAlignment.Center); // Create a new style called TextBox based on style Normal style = document.Styles.AddStyle("TextBox", "Normal"); style.ParagraphFormat.Alignment = ParagraphAlignment.Justify; style.ParagraphFormat.Borders.Width = 2.5; style.ParagraphFormat.Borders.Distance = "3pt"; style.ParagraphFormat.Shading.Color = Colors.SkyBlue; // Create a new style called TOC based on style Normal style = document.Styles.AddStyle("TOC", "Normal"); style.ParagraphFormat.AddTabStop("16cm", TabAlignment.Right, TabLeader.Dots); style.ParagraphFormat.Font.Color = Colors.Blue; //Create a new style called Title based on style Normal style = document.Styles.AddStyle("Title", "Normal"); style.Font.Name = "Arial"; style.Font.Size = 28; style.Font.Bold = true; style.Font.Color = Colors.Black; //Create a new style called PUID based on style Normal style = document.Styles.AddStyle("PUID", "Normal"); style.Font.Name = "Arial"; style.Font.Size = 22; style.Font.Bold = true; style.Font.Color = Colors.Black; //Create a new style called PASS based on style Normal style = document.Styles.AddStyle("PASS", "Normal"); style.Font.Name = "Arial"; style.Font.Size = 36; style.Font.Bold = false; style.Font.Color = Colors.Green; //Create a new style called FAIL based on style Normal style = document.Styles.AddStyle("FAIL", "Normal"); style.Font.Name = "Arial"; style.Font.Size = 36; style.Font.Bold = false; style.Font.Color = Colors.Red; //Create a new style called Text based on style Normal style = document.Styles.AddStyle("Text", "Normal"); style.Font.Name = "Arial"; style.Font.Size = 10; style.Font.Color = Colors.Black; style.ParagraphFormat.Alignment = ParagraphAlignment.Justify; } /// <summary> /// Defines the cover page. /// </summary> public static void DefineCover(Document document) { Section section = document.AddSection(); section.PageSetup.DifferentFirstPageHeaderFooter = true; HeaderFooter cover_footer = section.Footers.FirstPage; //DIN A4 = 21cm x 29,7cm Paragraph paragraph = section.AddParagraph("Title"); paragraph.Style = "Title"; paragraph.Format.SpaceBefore = "0cm"; paragraph.Format.Alignment = ParagraphAlignment.Center; paragraph = section.AddParagraph("Date: "); paragraph.Style = "Text"; paragraph.AddDateField(); paragraph = section.AddParagraph("Green"); paragraph.Style = "PASS"; paragraph.Format.Alignment = ParagraphAlignment.Center; paragraph = section.AddParagraph("Red"); paragraph.Style = "FAIL"; paragraph.Format.Alignment = ParagraphAlignment.Center; } public static void DefineParagraphsTest(Document document) { Paragraph paragraph = document.LastSection.AddParagraph("First", "Heading1"); paragraph.AddBookmark("First"); GenerateHistogram(document); } public static void GenerateHistogram(Document document) { document.LastSection.AddParagraph("Histogram", "Heading2"); Chart chart = new Chart(); chart.Left = 0; chart.Width = Unit.FromCentimeter(16); chart.Height = Unit.FromCentimeter(12); chart.Format.Alignment = ParagraphAlignment.Center;//has no effect chart.FooterArea.AddLegend(); for (int loop = 0; loop < 15; loop++) { Series series = chart.SeriesCollection.AddSeries(); series.ChartType = ChartType.Column2D; List<double> Yvalues = new List<double>(); for (double i = 0.2; i <= 4.5; i += 0.1) { Yvalues.Add(i); } series.Add(Yvalues.ToArray()); series.HasDataLabel = false; series.Name = "legend" + loop; } XSeries xseries = chart.XValues.AddXSeries(); //Xaxis contains every second value, to avoid overlapping text List<string> Xaxis = new List<string>(); bool skip = false; for (double i = 0.2; i <= 4.5; i += 0.1) { if (skip) { Xaxis.Add(""); skip = false; } else { Xaxis.Add(i.ToString()); skip = true; } } xseries.Add(Xaxis.ToArray()); chart.XAxis.MajorTickMark = TickMarkType.Outside; chart.XAxis.Title.Caption = "Time Interval [s]"; chart.YAxis.MajorTickMark = TickMarkType.Outside; chart.YAxis.HasMajorGridlines = true; chart.PlotArea.LineFormat.Color = Colors.DarkGray; chart.PlotArea.LineFormat.Width = 1; document.LastSection.Add(chart); } } } ,将会得到类似的内容:

ThisWorkbook.Path

同一件事也将进入桌面,因此您可以使用? thisworkbook.Path C:\Users\UserName\AppData\Local\Microsoft\Windows\INetCache\Content.Outlook\9PWSZZ9J触发器来检查工作簿路径,例如 Outlook Desktop 发送一条消息警告,将其保存在本地驱动器上。

根据Shaves的评论进行编辑:

有最后一种方法。只需说说他们的组策略,他们就可以将文件保存在本地Dirve C:上(假设他们都有驱动器)

您的方法可能是

Workbook_Open()

通过这种方式,您不仅可以警告用户,还可以将文件保存在需要的位置,然后从警告用户如何找到文件的位置将其删除。

答案 1 :(得分:1)

这里是Damian建议的扩展版本。我将其分为两部分。


第一部分:从展望

我正在使用一个MS Office版本。随时向Select Case

添加更多内容

当您从电子邮件中打开附件,然后再将其保存到硬盘驱动器时,Outlook会将副本放置在SecureTemp文件夹中。此文件夹是 Internet临时文件下的隐藏文件夹。

Sub Sample()
    Dim ol_Version As String
    Dim ol_RegKey As String
    Dim ol_SecureTempRegKey As String
    Dim ol_SecureTempFolder As String

    '~~> This is the registry key which stores Outlook's version
    ol_RegKey = "HKEY_CLASSES_ROOT\Outlook.Application\CurVer\"

    ol_Version = CreateObject("WScript.Shell").RegRead(ol_RegKey)

    '~~> Check the outlook version
    Select Case ol_Version
        Case "Outlook.Application.15"

            ol_SecureTempRegKey = "HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Outlook\Security\OutlookSecureTempFolder"
        '
        '~~> Add more cases here
        '
    End Select

    If ol_SecureTempRegKey <> "" Then
        ol_SecureTempFolder = CreateObject("WScript.Shell").RegRead(ol_SecureTempRegKey)

        Debug.Print "Outlook's temp folder is " & ol_SecureTempFolder
    End If
End Sub

一旦获得SecureTemp路径,就可以检查文件是否从Outlook中打开。


第二部分:从桌面

要获取用户的桌面文件夹路径,可以使用此路径。一旦获得Desktop路径,就可以检查文件是否从那里打开。

Sub Sample()
    Dim desktopPath As String

    desktopPath = CreateObject("WScript.Shell").SpecialFolders("Desktop")

    Debug.Print "User's desktop folder is " & desktopPath
End Sub