Guest User

Untitled

a guest
Feb 28th, 2022
288
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.80 KB | None | 0 0
  1. Attribute VB_Name = "mAttachmentSaver"
  2. '---------------------------------------------------------------------------------
  3. ' The sample scripts are not supported under any Microsoft standard support
  4. ' program or service. The sample scripts are provided AS IS without warranty
  5. ' of any kind. Microsoft further disclaims all implied warranties including,
  6. ' without limitation, any implied warranties of merchantability or of fitness for
  7. ' a particular purpose. The entire risk arising out of the use or performance of
  8. ' the sample scripts and documentation remains with you. In no event shall
  9. ' Microsoft, its authors, or anyone else involved in the creation, production, or
  10. ' delivery of the scripts be liable for any damages whatsoever (including,
  11. ' without limitation, damages for loss of business profits, business interruption,
  12. ' loss of business information, or other pecuniary loss) arising out of the use
  13. ' of or inability to use the sample scripts or documentation, even if Microsoft
  14. ' has been advised of the possibility of such damages.
  15. '---------------------------------------------------------------------------------
  16.  
  17. Option Explicit
  18.  
  19. ' *****************
  20. ' For Outlook 2010.
  21. ' *****************
  22. #If VBA7 Then
  23. ' The window handle of Outlook.
  24. Private lHwnd As LongPtr
  25.  
  26. ' /* API declarations. */
  27. Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _
  28. ByVal lpWindowName As String) As LongPtr
  29.  
  30. ' *****************************************
  31. ' For the previous version of Outlook 2010.
  32. ' *****************************************
  33. #Else
  34. ' The window handle of Outlook.
  35. Private lHwnd As Long
  36.  
  37. ' /* API declarations. */
  38. Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _
  39. ByVal lpWindowName As String) As Long
  40. #End If
  41.  
  42. ' The class name of Outlook window.
  43. Private Const olAppCLSN As String = "rctrl_renwnd32"
  44. ' Windows desktop - the virtual folder that is the root of the namespace.
  45. Private Const CSIDL_DESKTOP = &H0
  46. ' Only return file system directories. If the user selects folders that are not part of the file system, the OK button is grayed.
  47. Private Const BIF_RETURNONLYFSDIRS = &H1
  48. ' Do not include network folders below the domain level in the dialog box's tree view control.
  49. Private Const BIF_DONTGOBELOWDOMAIN = &H2
  50. ' The maximum length for a path is 260 characters.
  51. Private Const MAX_PATH = 260
  52.  
  53. ' ######################################################
  54. ' Returns the number of attachements in the selection.
  55. ' ######################################################
  56. Public Function SaveAttachmentsFromSelection() As Long
  57. Dim objFSO As Object ' Computer's file system object.
  58. Dim objShell As Object ' Windows Shell application object.
  59. Dim objFolder As Object ' The selected folder object from Browse for Folder dialog box.
  60. Dim objItem As Object ' A specific member of a Collection object either by position or by key.
  61. Dim selItems As Selection ' A collection of Outlook item objects in a folder.
  62. Dim atmt As Attachment ' A document or link to a document contained in an Outlook item.
  63. Dim strAtmtPath As String ' The full saving path of the attachment.
  64. Dim strAtmtFullName As String ' The full name of an attachment.
  65. Dim strAtmtName(1) As String ' strAtmtName(0): to save the name; strAtmtName(1): to save the file extension. They are separated by dot of an attachment file name.
  66. Dim strAtmtNameTemp As String ' To save a temporary attachment file name.
  67. Dim intDotPosition As Integer ' The dot position in an attachment name.
  68. Dim atmts As Attachments ' A set of Attachment objects that represent the attachments in an Outlook item.
  69. Dim lCountEachItem As Long ' The number of attachments in each Outlook item.
  70. Dim lCountAllItems As Long ' The number of attachments in all Outlook items.
  71. Dim strFolderPath As String ' The selected folder path.
  72. Dim blnIsEnd As Boolean ' End all code execution.
  73. Dim blnIsSave As Boolean ' Consider if it is need to save.
  74.  
  75. blnIsEnd = False
  76. blnIsSave = False
  77. lCountAllItems = 0
  78.  
  79. On Error Resume Next
  80.  
  81. Set selItems = ActiveExplorer.Selection
  82.  
  83. If Err.Number = 0 Then
  84.  
  85. ' Get the handle of Outlook window.
  86. lHwnd = FindWindow(olAppCLSN, vbNullString)
  87.  
  88. If lHwnd <> 0 Then
  89.  
  90. ' /* Create a Shell application object to pop-up BrowseForFolder dialog box. */
  91. Set objShell = CreateObject("Shell.Application")
  92. Set objFSO = CreateObject("Scripting.FileSystemObject")
  93. Set objFolder = objShell.BrowseForFolder(lHwnd, "Select folder to save attachments:", _
  94. BIF_RETURNONLYFSDIRS + BIF_DONTGOBELOWDOMAIN, CSIDL_DESKTOP)
  95.  
  96. ' /* Failed to create the Shell application. */
  97. If Err.Number <> 0 Then
  98. MsgBox "Run-time error '" & CStr(Err.Number) & " (0x" & CStr(Hex(Err.Number)) & ")':" & vbNewLine & _
  99. Err.Description & ".", vbCritical, "Error from Attachment Saver"
  100. blnIsEnd = True
  101. GoTo PROC_EXIT
  102. End If
  103.  
  104. If objFolder Is Nothing Then
  105. strFolderPath = ""
  106. blnIsEnd = True
  107. GoTo PROC_EXIT
  108. Else
  109. strFolderPath = CGPath(objFolder.Self.Path)
  110.  
  111. ' /* Go through each item in the selection. */
  112. For Each objItem In selItems
  113. lCountEachItem = objItem.Attachments.Count
  114.  
  115. ' /* If the current item contains attachments. */
  116. If lCountEachItem > 0 Then
  117. Set atmts = objItem.Attachments
  118.  
  119. ' /* Go through each attachment in the current item. */
  120. For Each atmt In atmts
  121.  
  122. ' Get the full name of the current attachment.
  123. strAtmtFullName = atmt.FileName
  124.  
  125. ' Find the dot postion in atmtFullName.
  126. intDotPosition = InStrRev(strAtmtFullName, ".")
  127.  
  128. ' Get the name.
  129. strAtmtName(0) = Left$(strAtmtFullName, intDotPosition - 1)
  130. ' Get the file extension.
  131. strAtmtName(1) = Right$(strAtmtFullName, Len(strAtmtFullName) - intDotPosition)
  132. ' Get the full saving path of the current attachment.
  133. strAtmtPath = strFolderPath & atmt.FileName
  134.  
  135. ' /* If the length of the saving path is not larger than 260 characters.*/
  136. If Len(strAtmtPath) <= MAX_PATH Then
  137. ' True: This attachment can be saved.
  138. blnIsSave = True
  139.  
  140. ' /* Loop until getting the file name which does not exist in the folder. */
  141. Do While objFSO.FileExists(strAtmtPath)
  142. strAtmtNameTemp = strAtmtName(0) & _
  143. Format(Now, "_mmddhhmmss") & _
  144. Format(Timer * 1000 Mod 1000, "000")
  145. strAtmtPath = strFolderPath & strAtmtNameTemp & "." & strAtmtName(1)
  146.  
  147. ' /* If the length of the saving path is over 260 characters.*/
  148. If Len(strAtmtPath) > MAX_PATH Then
  149. lCountEachItem = lCountEachItem - 1
  150. ' False: This attachment cannot be saved.
  151. blnIsSave = False
  152. Exit Do
  153. End If
  154. Loop
  155.  
  156. ' /* Save the current attachment if it is a valid file name. */
  157. If blnIsSave Then atmt.SaveAsFile strAtmtPath
  158. Else
  159. lCountEachItem = lCountEachItem - 1
  160. End If
  161. Next
  162. End If
  163.  
  164. ' Count the number of attachments in all Outlook items.
  165. lCountAllItems = lCountAllItems + lCountEachItem
  166. Next
  167. End If
  168. Else
  169. MsgBox "Failed to get the handle of Outlook window!", vbCritical, "Error from Attachment Saver"
  170. blnIsEnd = True
  171. GoTo PROC_EXIT
  172. End If
  173.  
  174. ' /* For run-time error:
  175. ' The Explorer has been closed and cannot be used for further operations.
  176. ' Review your code and restart Outlook. */
  177. Else
  178. MsgBox "Please select an Outlook item at least.", vbExclamation, "Message from Attachment Saver"
  179. blnIsEnd = True
  180. End If
  181.  
  182. PROC_EXIT:
  183. SaveAttachmentsFromSelection = lCountAllItems
  184.  
  185. ' /* Release memory. */
  186. If Not (objFSO Is Nothing) Then Set objFSO = Nothing
  187. If Not (objItem Is Nothing) Then Set objItem = Nothing
  188. If Not (selItems Is Nothing) Then Set selItems = Nothing
  189. If Not (atmt Is Nothing) Then Set atmt = Nothing
  190. If Not (atmts Is Nothing) Then Set atmts = Nothing
  191.  
  192. ' /* End all code execution if the value of blnIsEnd is True. */
  193. If blnIsEnd Then End
  194. End Function
  195.  
  196. ' #####################
  197. ' Convert general path.
  198. ' #####################
  199. Public Function CGPath(ByVal Path As String) As String
  200. If Right(Path, 1) <> "\" Then Path = Path & "\"
  201. CGPath = Path
  202. End Function
  203.  
  204. ' ######################################
  205. ' Run this macro for saving attachments.
  206. ' ######################################
  207. Public Sub ExecuteSaving()
  208. Dim lNum As Long
  209.  
  210. lNum = SaveAttachmentsFromSelection
  211.  
  212. If lNum > 0 Then
  213. MsgBox CStr(lNum) & " attachment(s) was(were) saved successfully.", vbInformation, "Message from Attachment Saver"
  214. Else
  215. MsgBox "No attachment(s) in the selected Outlook items.", vbInformation, "Message from Attachment Saver"
  216. End If
  217. End Sub
  218.  
Advertisement
Add Comment
Please, Sign In to add comment