{"id":60765,"date":"2023-11-06T12:43:34","date_gmt":"2023-11-06T11:43:34","guid":{"rendered":"https:\/\/ekiwi-blog.de\/60765\/vba-query-memory-path-before-saving\/"},"modified":"2023-11-06T12:54:34","modified_gmt":"2023-11-06T11:54:34","slug":"vba-query-memory-path-before-saving","status":"publish","type":"post","link":"https:\/\/ekiwi-blog.de\/en\/60765\/vba-query-memory-path-before-saving\/","title":{"rendered":"VBA: Query save path before (Save as dialog)"},"content":{"rendered":"<p><abbr title=\"Visual Basic for Application\">VBA<\/abbr> can be a great helper in the Microsoft Office world for automating everyday tasks, for example <a href=\"https:\/\/ekiwi-blog.de\/en\/51740\/vba-save-e-mail-attachment\/\">automatically saving file attachments from Outlook emails<\/a> or reading the <a href=\"https:\/\/ekiwi-blog.de\/en\/24960\/vba-read-pdf\/\">contents of a PDF and inserting them into an Excel file<\/a>. For such automatisms, it can be helpful to query the storage path, i.e. the directory where the data or files are to be saved, via a dialogue beforehand.<\/p>\n<pre><code><span style=\"color: #0000ff;\">Public Sub<\/span> SaveWithDialog()\r\n    <span style=\"color: #0000ff;\">Dim<\/span> folderToSave <span style=\"color: #0000ff;\">As String<\/span>\r\n    folderToSave = SaveToFolder\r\n    <span style=\"color: #008000;\">'Here are the further instructions for using the save as path<\/span>\r\n    <span style=\"color: #0000ff;\">Debug.Print<\/span> folderToSave\r\n<span style=\"color: #0000ff;\">End Sub<\/span><\/code><\/pre>\n<p>The 3-4 lines of code shown here are our basic function, which can then be executed as a macro. Here we define a string variable <em>folderToSave<\/em>, to which the directory path is then passed. With <em>Debug.Print<\/em> we output the memory path determined via a selection dialogue in the direct window.<\/p>\n<p>The query of the memory path using a &#8220;Save as&#8221; dialogue is outsourced here in a separate function. The problem is that such dialogue functions do not exist directly in VBA or are not available in all programs, such as Outlook. Instead, you have to use alternative workarounds. There are two variants for this.<\/p>\n<p>The function that handles the user&#8217;s save path query is called <em>SaveToFolder<\/em> in our example, is parameterless and returns the directory path selected by the user.<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_82_2 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of content<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/ekiwi-blog.de\/en\/60765\/vba-query-memory-path-before-saving\/#Variant_1_%E2%80%9CFind_folder%E2%80%9D_%E2%80%93_dialogue_for_save_path\" >Variant 1: &#8220;Find folder&#8221; &#8211; dialogue for save path<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/ekiwi-blog.de\/en\/60765\/vba-query-memory-path-before-saving\/#Variant_2_%E2%80%9CSave_as%E2%80%9D_%E2%80%93_use_dialogue\" >Variant 2: &#8220;Save as&#8221; &#8211; use dialogue<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Variant_1_%E2%80%9CFind_folder%E2%80%9D_%E2%80%93_dialogue_for_save_path\"><\/span>Variant 1: &#8220;<em>Find folder<\/em>&#8221; &#8211; dialogue for save path<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>You can use the &#8220;<em>Find folder<\/em>&#8221; dialogue. You can see what this dialogue looks like in the following screenshot.<\/p>\n<figure id=\"attachment_60578\" aria-describedby=\"caption-attachment-60578\" style=\"width: 340px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-60578\" src=\"https:\/\/ekiwi-blog.de\/wp-content\/uploads\/2023\/10\/vba-dialog-ordner-suchen-zum-speichern-unter-bestimmten-verzeichnis.jpg\" alt=\"Screenshot VBA dialogue Select folder to save under the selected directory\" width=\"340\" height=\"400\" srcset=\"https:\/\/ekiwi-blog.de\/wp-content\/uploads\/2023\/10\/vba-dialog-ordner-suchen-zum-speichern-unter-bestimmten-verzeichnis.jpg 340w, https:\/\/ekiwi-blog.de\/wp-content\/uploads\/2023\/10\/vba-dialog-ordner-suchen-zum-speichern-unter-bestimmten-verzeichnis-255x300.jpg 255w\" sizes=\"auto, (max-width: 340px) 100vw, 340px\" \/><figcaption id=\"caption-attachment-60578\" class=\"wp-caption-text\">Variant 1: Folder dialogue<\/figcaption><\/figure>\n<p>The folder search dialogue uses a <a href=\"https:\/\/www.devhut.net\/vba-shell-application-deep-dive\/\">Shell.Application<\/a>, as you can see from the following code.<\/p>\n<pre><code><span style=\"color: #0000ff;\">Function<\/span> SaveToFolder(<span style=\"color: #0000ff;\">Optional<\/span> OpenAt <span style=\"color: #0000ff;\">As String<\/span>) <span style=\"color: #0000ff;\">As String<\/span>\r\n    <span style=\"color: #0000ff;\">Dim<\/span> ShellApp <span style=\"color: #0000ff;\">As Object<\/span>\r\n    \r\n    <span style=\"color: #0000ff;\">Set<\/span> ShellApp = CreateObject(\"Shell.Application\"). _\r\n    BrowseForFolder(0, \"Select Folder\", 0, OpenAt)\r\n    \r\n    <span style=\"color: #0000ff;\">On Error Resume Next<\/span>\r\n    SaveToFolder = ShellApp.self.Path\r\n    <span style=\"color: #0000ff;\">On Error GoTo 0<\/span>\r\n    \r\n    <span style=\"color: #0000ff;\">Select Case<\/span> Mid(SaveToFolder, 2, 1)\r\n    <span style=\"color: #0000ff;\">Case Is<\/span> = \":\"\r\n        <span style=\"color: #0000ff;\">If<\/span> Left(SaveToFolder, 1) = \":\" <span style=\"color: #0000ff;\">Then<\/span>\r\n            SaveToFolder = \"\"\r\n        <span style=\"color: #0000ff;\">End If<\/span>\r\n    <span style=\"color: #0000ff;\">Case Is<\/span> = \"\\\"\r\n        <span style=\"color: #0000ff;\">If Not<\/span> Left(SaveToFolder, 1) = \"\\\" <span style=\"color: #0000ff;\">Then<\/span>\r\n            SaveToFolder = \"\"\r\n        <span style=\"color: #0000ff;\">End If<\/span>\r\n    <span style=\"color: #0000ff;\">Case Else<\/span>\r\n        SaveToFolder = \"\"\r\n    <span style=\"color: #0000ff;\">End Select<\/span>\r\n    \r\n<span style=\"color: #0000ff;\">ExitFunction:<\/span>    \r\n    <span style=\"color: #0000ff;\">Set<\/span> ShellApp = <span style=\"color: #0000ff;\">Nothing<\/span>\r\n<span style=\"color: #0000ff;\">End Function<\/span><\/code><\/pre>\n<p>This variant works under all Office applications, as the shell application is available Windows-wide.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Variant_2_%E2%80%9CSave_as%E2%80%9D_%E2%80%93_use_dialogue\"><\/span>Variant 2: &#8220;<em>Save as<\/em>&#8221; &#8211; use dialogue<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The second variant shows the classic &#8220;Save as&#8221; dialogue as you are used to under Windows. Unfortunately, this is not directly available in all applications with VBA. For example, you cannot use VBA in Outlook to directly call up such a dialogue to specify a folder as the save path.<\/p>\n<figure id=\"attachment_60574\" aria-describedby=\"caption-attachment-60574\" style=\"width: 550px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-60574\" src=\"https:\/\/ekiwi-blog.de\/wp-content\/uploads\/2023\/10\/vba-dialog-datei-speichern-unter.jpg\" alt=\"Screenshot VBA file save as dialogue, you can specify save path and file name\" width=\"550\" height=\"342\" srcset=\"https:\/\/ekiwi-blog.de\/wp-content\/uploads\/2023\/10\/vba-dialog-datei-speichern-unter.jpg 550w, https:\/\/ekiwi-blog.de\/wp-content\/uploads\/2023\/10\/vba-dialog-datei-speichern-unter-300x187.jpg 300w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><figcaption id=\"caption-attachment-60574\" class=\"wp-caption-text\">Variant 2: &#8220;Save as&#8221; dialogue<\/figcaption><\/figure>\n<p>However, this file dialogue is always available for Excel. This means that you can also call up the file dialogue in other Office programs by simply defining an Excel application object in VBA. The following VBA code shows how to do this.<\/p>\n<pre><code><span style=\"color: #0000ff;\">Function<\/span> SaveToFolder() <span style=\"color: #0000ff;\">As String<\/span>\r\n    <span style=\"color: #0000ff;\">Dim<\/span> fileDlg <span style=\"color: #0000ff;\">As<\/span> fileDialog\r\n    <span style=\"color: #0000ff;\">Set<\/span> excelApp = CreateObject(\"Excel.application\")\r\n    excelApp.Visible = <span style=\"color: #0000ff;\">False<\/span>\r\n    <span style=\"color: #0000ff;\">Set<\/span> fileDlg = excelApp.fileDialog(msoFileDialogFolderPicker)\r\n\r\n    <span style=\"color: #0000ff;\">With<\/span> fileDlg\r\n        <span style=\"color: #0000ff;\">If<\/span> .Show = -1 Then <span style=\"color: #008000;\">'when user presses Okay button<\/span>\r\n            <span style=\"color: #008000;\">'Loop through each string in the FileDialogSelectedItems collection.<\/span>\r\n            <span style=\"color: #0000ff;\">For<\/span> Each SelectedItem <span style=\"color: #0000ff;\">In<\/span> .SelectedItems\r\n                SaveToFolder = SelectedItem\r\n            <span style=\"color: #0000ff;\">Next<\/span> SelectedItem\r\n        <span style=\"color: #0000ff;\">Else<\/span>\r\n            <span style=\"color: #008000;\">'when user presses the cancel button<\/span>\r\n            SaveToFolder = \"\"\r\n        <span style=\"color: #0000ff;\">End If<\/span>\r\n    <span style=\"color: #0000ff;\">End With<\/span>\r\n    \r\n    <span style=\"color: #0000ff;\">Set<\/span> fileDlg = <span style=\"color: #0000ff;\">Nothing<\/span>\r\n    excelApp.Quit\r\n    <span style=\"color: #0000ff;\">Set<\/span> excelApp = <span style=\"color: #0000ff;\">Nothing<\/span>\r\n<span style=\"color: #0000ff;\">End Function<\/span><\/code><\/pre>\n<p>With one of these two variants, you offer the user the option of selecting a dedicated directory as the storage path in order to then use it in the <a title=\"VBA macro: Automatically add a file attachment to an e-mail message\" href=\"https:\/\/ekiwi-blog.de\/en\/49256\/vba-macro-automatically-add-a-file-attachment-to-an-e-mail-message\/\">VBA macro<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>VBA can be a great helper in the Microsoft Office world for automating everyday tasks, for example automatically saving file<\/p>\n","protected":false},"author":2,"featured_media":6532,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1555],"tags":[1701,3156,3155,2252,3035,1855,1707,2737,3153,3154,1857,1858,2168,1569,3231,1859,1860,1861,2715,1862,2068,1710],"class_list":["post-60765","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software-en","tag-access-en","tag-automatisch-en","tag-automatisieren-en","tag-code-en","tag-e-mail-en","tag-excel-en-2","tag-macro","tag-macros","tag-makro-en","tag-makros-en","tag-microsoft-en-2","tag-microsoft-office-en-2","tag-office-en","tag-outlook-en","tag-powerpoint-en","tag-programmieren-en","tag-programmierung-en","tag-vba-en-2","tag-vba-code-en","tag-visual-basic-for-application-en-2","tag-windows-en-2","tag-word-en"],"_links":{"self":[{"href":"https:\/\/ekiwi-blog.de\/en\/wp-json\/wp\/v2\/posts\/60765","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ekiwi-blog.de\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ekiwi-blog.de\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ekiwi-blog.de\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/ekiwi-blog.de\/en\/wp-json\/wp\/v2\/comments?post=60765"}],"version-history":[{"count":0,"href":"https:\/\/ekiwi-blog.de\/en\/wp-json\/wp\/v2\/posts\/60765\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ekiwi-blog.de\/en\/wp-json\/wp\/v2\/media\/6532"}],"wp:attachment":[{"href":"https:\/\/ekiwi-blog.de\/en\/wp-json\/wp\/v2\/media?parent=60765"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ekiwi-blog.de\/en\/wp-json\/wp\/v2\/categories?post=60765"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ekiwi-blog.de\/en\/wp-json\/wp\/v2\/tags?post=60765"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}