Outlook Redemption: Silent Import with ReceivedTime modification - outlook

Please help to automate the process which consists of 2 Subs:
Import - I need to make Silent import without target & destination folder selection dialog.
I need to import to my "INBOX/Imported" subfolder in Outlook and want to understand where in this code I can mention it explicitly.
I need to grab .EML files from the folder "D:\Emails" without redundant dialogue for folder selection:
Sub Redemp()
Dim objShell: Set objShell = CreateObject("Shell.Application")
Dim objFolder: Set objFolder = objShell.BrowseForFolder(0, "Select the folder containing eml-files", 0)
Dim Item
If (Not objFolder Is Nothing) Then
Set WShell = CreateObject("WScript.Shell")
Set objOutlook = CreateObject("Outlook.Application")
Set Folder = objOutlook.Session.PickFolder
If Not Folder Is Nothing Then
For Each Item In objFolder.Items
If Right(Item.name, 4) = ".eml" And Item.IsFolder = False Then
Set objPost = Folder.Items.Add(6)
Set objSafePost = CreateObject("Redemption.SafePostItem")
objSafePost.Item = objPost
objSafePost.Import Item.Path, 1024
objSafePost.MessageClass = "IPM.Note"
' remove IPM.Post icon
Set utils = CreateObject("Redemption.MAPIUtils")
PrIconIndex = &H10800003
utils.HrSetOneProp objSafePost, PrIconIndex, 256, True 'Also saves the message
End If
Next
End If
End If
MsgBox "Import completed.", 64, "Import EML"
Set objFolder = Nothing
Set objShell = Nothing
End Sub
Also, it would be great to avoid imported messages appearing in Outlook as if I already started replying to (not very convenient). If I use the above code and select imported message it doesn't look like originally received, but rather looks like text that I reply to.
I need to unify the below code that corrects ReceivedTime property of imported message (or it can modify EML file before import, sequence of actions is not important) with above import procedure.
Sub Redemp_sentreceived()
Set rSession = CreateObject("Redemption.RDOSession")
rSession.MAPIOBJECT = Application.Session.MAPIOBJECT
Set Msg = rSession.GetRDOObjectFromOutlookObject(Application.ActiveExplorer.CurrentFolder)
For Each Item In Msg.Items
Item.ReceivedTime = Item.SentOn
Item.Save
Next
End Sub
Ultimately imported .EML files should be in target folder with correct ReceivedTime.
Many thanks for helping me out in advance!

There is really no reason to use Safe*Item objects in this case - use RDOSession object, set the MAPIOBJECT property just like you do in the second example.
Off the top of my head:
Set rSession = CreateObject("Redemption.RDOSession")
rSession.MAPIOBJECT = Application.Session.MAPIOBJECT
Set folder = rSession.GetDefaultFolder(plFolderInbox).Folders.Items("Imported")
Set fileFolder = objFSO.GetFolder("D:\Emails")
For Each objFile in fileFolder.Files
set msg = folder.Items.Add("IPM.Note")
msg.Sent = true
msg.Import objFile.Path, 1031
msg.Save
Next

The problem was in number pointed in Import (I changed 1031 -> 1024) and now it works like a charm!
Sub MailImport()
Dim objFSO As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set rSession = CreateObject("Redemption.RDOSession")
rSession.MAPIOBJECT = Application.Session.MAPIOBJECT
Set Folder = rSession.GetDefaultFolder(olFolderInbox)
Set fileFolder = objFSO.GetFolder("D:\Emails")
For Each objFile In fileFolder.Files
Set msg = Folder.Items.Add("IPM.Note")
msg.sent = True
msg.Import objFile.Path, 1024
msg.ReceivedTime = msg.SentOn
msg.Save
objFile.Delete
Next
Set objFSO = Nothing
End Sub

Related

How to overwrite a file in VBScript [duplicate]

i created a text file "list.txt" in commonapplicationdatafolder by using the following VBscript.i am displaying some
values from a variable(strlist) by writing in to textfile.
Const Value = &H23&
Const PATH = "\Cape\ibs"
Dim fso ' File System Object
Dim spFile ' Text File object to write
Dim objApplication ' Application object
Dim objFolder ' Folder object
Dim objFolderItem ' FolderItem object
Set objApplication = CreateObject("Shell.Application")
Set objFolder = objApplication.Namespace(Value)
Set objFolderItem = objFolder.Self
sname = objFolderItem.Path & PATH & "\list.txt"
Set fso = CreateObject("Scripting.FileSystemObject")
Set spFile = fso.CreateTextFile(sname, True)
spoFile.WriteLine(strlist)
spoFile.Close
Here are my doubts
1> Here before creating that file i need to delete the old existing "list.txt" Because during installation
i always want to create the list file. So i want to include code that removes any existing file(any old list.txt),
before creating the latest one.Here i did the following code
If fso.FileExists(sname) Then
fso.DeleteFile sname, True
Else
Set spFile = fso.CreateTextFile(sname, True)
spoFile.WriteLine(strlist)
Set objFolderItem = Nothing
Set objFolder = Nothing
Set objApplication = Nothing
Set fso = Nothing
spoFile.Close
End If
Whats going on is it will create folder first time,next time it will delete it ,But i always want that file there(new fresh one with value from 'strlist' )
Can any one tell me the vbscript code to do that.Their i removed Else part also but only deletion going ,below things are not working means creation.
2>Here i was writing in to "list.txt" by using simply 'WriteLine' method(spoFile.WriteLine(strlist)),but i read somewhere that we need to use
'OpenTextFile'(Const ForWriting = 2) for writing,If that is the case what changes i need to do here,Is it mandatory?
you need to move your delete or not delete decision before your write decision.
If fso.FileExists(sname) Then
'you delete if you find it'
fso.DeleteFile sname, True
End If
'you always write it anyway.'
Set spoFile = fso.CreateTextFile(sname, True)
spoFile.WriteLine(strlist)
Set objFolderItem = Nothing
Set objFolder = Nothing
Set objApplication = Nothing
Set fso = Nothing
spoFile.Close
alternately to your question with Constant write values and making this a little (very little) bit faster, you might try the following:
If fso.FileExists(sname) Then
Set spoFile = fso.OpenTextFile(sname, 2, True)
Else
Set spoFile = fso.CreateTextFile(sname, True)
End If
' perform your write operations and close normally'
' copy in flash drive
Const Removable = 1
Set FSO = CreateObject("Scripting.FileSystemObject")
Set colDrives = FSO.Drives
For Each Drive in colDrives
If Drive.DriveType = Removable then
fso.copyfile "filename.vbs" , Drive.DriveLetter&":\"
End if
Next

Provide the source path

How can I take input as folder through GUI by using VBScript?
Example: I don't want to use following Window method.
Function Browse4Folder(strPrompt, intOptions, strRoot)
Dim objFolder, objFolderItem, objShell
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.BrowseForFolder(0, strPrompt, intOptions, strRoot)
If (objFolder Is Nothing) Then
Browse4Folder = ""
Else
Set objFolderItem = objFolder.Self
Browse4Folder = objFolderItem.Path
Set objFolderItem = Nothing
Set objFolder = Nothing
End If
Set objShell = Nothing
End Function
I want to achieve the following:
I have a folder containing .h, .c, .exe, …
I have written the operation to removed unwanted files (like I required only .h file).
The end result should be only getting .h files.
All operation I have done but for statement (1), I have written the above snippet which provide the manual selection of the folder, but I want to make it automate (if I will run the script, all the operation should be complete without doing anything manually).
If I understand your question correctly, you want to remove all files from a given folder, except those with a specific extension (.h). That could be achieved with a procedure like this:
Sub DeleteExcept(path, extension)
Set fso = CreateObject("Scripting.FileSystemObject")
For Each f In fso.GetFolder(path).Files
If LCase(fso.GetExtensionName(f)) <> LCase(extension) Then f.Delete True
Next
End Sub
DeleteExcept "C:\your\folder" "h"

Excel and Word behaving difrerently in the same code

I have a problem - instances of Excel and Word behave differently in the same procedure. Have a look at the code. The idea there is to have a procedure that handles resaving files in excel and word in various format combinations.
The problem is that I notice that word and excel behave differently - the appWord and appExcel have different type names. At some point appWord is changed from Application to Object, which then makes it impossible to close it. I don't understand the differences in the behaviour, since the code applied to them is identical.
Option Explicit
Dim fso
Dim appWord
Dim appExcel
Set fso = CreateObject("Scripting.FileSystemObject")
startWord
ResaveFiles appWord.Documents, "docx", 12, 0
appWord.quit
startExcel
ResaveFiles appExcel.Workbooks, "xlsx", 51, 56
appExcel.quit
MsgBox "All done."
Sub ResaveFiles(appType, srcExtName, srcExtNum, tmpExtNum)
Dim objFile
Dim objOpenFile
Dim strDirectory
For Each objFile in fso.GetFolder(".").Files
If lcase(fso.GetExtensionName(objFile)) = srcExtName Then
If typeName(appType) = "Documents" Then StartWord
If typeName(appType) = "Workbooks" Then StartExcel
Set objOpenFile = appType.Open(objFile.path)
strDirectory = fso.BuildPath(objOpenFile.path, fso.GetBaseName(objOpenFile.name) & "._temp")
objOpenFile.SaveAs strDirectory, tmpExtNum
objOpenFile.Close
msgBox typename(appType) & objFile
msgBox typename(appWord) 'First typename test
msgBox Typename(appExcel)
If typeName(appType) = "Documents" Then appWord.Quit
If typeName(appType) = "Workbooks" Then appExcel.Quit
set objOpenFile = appType.Open(strDirectory)
objOpenFile.SaveAs objFile.path, srcExtNum
objOpenFile.Close
fso.DeleteFile(strDirectory)
msgBox typename(appWord) 'Second typename test
msgBox Typename(appExcel)
End If
Next
End Sub
'Start Word
Sub StartWord
Set appWord = CreateObject("Word.Application")
appWord.visible = false
appWord.DisplayAlerts = false
End Sub
'Start Excel
Sub StartExcel
Set appExcel = CreateObject("Excel.Application")
appExcel.visible = false
appExcel.DisplayAlerts = false
End Sub
I have tested it in the following way (with two typename tests) - when there are word files available, first appWord is Application and appExcel is empty, then it changes to Object and appExcel stays Empty (in this case we get an error when the subprocedure ends at AppWord.Quit). When there are no word files, and the script is processing Excels, first appWord is Object and appExcel is Application, then appWord is still Object and appExcel is still Application - in this case there are no errors when the subprocedure ends, on the appExcel.Quit.
Maybe i'm wrong, just my opinion:
If typeName(appType) = "Documents" Then appWord.Quit
If typeName(appType) = "Workbooks" Then appExcel.Quit
set objOpenFile = appType.Open(strDirectory)
appType is a reference to what appWord.Documents or appExcel.Workbooks are referencing before entering your ResaveFiles Sub, where you instantiate a new copy of 'Excel.Application' or 'Word.Application', and in each of the cases, you instruct the application TO QUIT. The question is not why in the case of word you got an error. From my point of view YOU SHOULD got an error. The question is why, if instructed to quit, excel keeps open and maintaining references to handle your code.
EDIT - And not tried. Just adapted from OP code. Adapt as needed
Option Explicit
ResaveFiles "Word.Application", "docx", 12, 0
ResaveFiles "Excel.Application", "xlsx", 51, 56
MsgBox "All done."
Sub ResaveFiles(progID, srcExtName, srcExtNum, tmpExtNum )
Dim app, doc
Dim fso, objFile, objOpenFile, strDirectory
Set fso = CreateObject("Scripting.FileSystemObject")
For Each objFile in fso.GetFolder( "." ).Files
If LCase(fso.GetExtensionName( objFile.Name )) = srcExtName Then
' Get references
Set app = GetNewAppInstance( progID )
Set doc = GetDocumentHandler( app )
' Save temp
Set objOpenFile = doc.Open( objFile.Path )
strDirectory = fso.BuildPath( objOpenFile.path, fso.GetBaseName(objOpenFile.name) & "._temp" )
objOpenFile.SaveAs strDirectory, tmpExtNum
objOpenFile.Close
' Release objects
Set objOpenFile = nothing
Set doc = nothing
app.Quit
Set app = nothing
' Get references again
Set app = GetNewAppInstance( progID )
Set doc = GetDocumentHandler( app )
' Resave file
Set objOpenFile = doc.Open( strDirectory )
objOpenFile.SaveAs objFile.path, srcExtNum
objOpenFile.Close
' Release objects
Set objOpenFile = nothing
Set doc = nothing
app.Quit
Set app = nothing
' Clean
fso.DeleteFile(strDirectory)
End If
Next
End Sub
Function GetNewAppInstance( ByVal progID )
Set GetNewAppInstance = CreateObject( progID )
With GetNewAppInstance
.Visible = False
.DisplayAlerts = False
End With
End Function
Function GetDocumentHandler( app )
Dim name
name = app.Name
If InStr(name,"Excel") > 0 Then
Set GetDocumentHandler = app.Workbooks
ElseIf InStr(name,"Word") > 0 Then
Set GetDocumentHandler = app.Documents
Else
Set GetDocumentHandler = app
End If
End Function

Open directory chooser dialog in specific dir

I've got the following code to display a directory chooser dialog
Function selectOutputFolder(lastPath As String) As String
Const BIF_NEWDIALOGSTYLE = &H00000040
Dim objShell As Variant
Dim objFolder As Variant
Dim objFolderItem As Variant
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.BrowseForFolder(0, "Choose a directory", BIF_NEWDIALOGSTYLE, lastPath)
If Not (objFolder Is Nothing) Then
Set objFolderItem = objFolder.Self
selectOutputFolder = objFolderItem.Path
End If
End Function
I was playing around with the 4th parameter of BrowseForFolder which is only a limit for the directory traversal and not to jump into this folder on open.
This is implemented into a lotus script agent, so if you know any alternative in vba or lotusscript, let me know!
There is a "Standard" way to do this in LotusScript by using the SaveFileDialog- Method of the NotesUIWorkspace- Class.
'...your sub goes around this
Dim ws as New NotesUIWorkspace
Dim varPaths as Variant
varPaths = ws.SaveFileDialog( True , "Choose file" , "" , lastPath )
If not isEmpty( varPaths ) then
selectOutputFolder = varPaths(0)
End If

Upgrading VB6 code from Outlook 2007 to Outlook 2010

We want to upgrade our VB6 code to use Outlook 2010, but we're getting the following error:
Active x cannot create object
This is our current code:
Public Sub SendEmail()
Set emailOutlookApp = CreateObject("Outlook.Application.12")
Set emailNameSpace = emailOutlookApp.GetNamespace("MAPI")
Set emailFolder = emailNameSpace.GetDefaultFolder(olFolderInbox)
Set emailItem = emailOutlookApp.CreateItem(olMailItem)
Set EmailRecipient = emailItem.Recipients
EmailRecipient.Add (EmailAddress)
EmailRecipient.Add (EmailAddress2)
emailItem.Importance = olImportanceHigh
emailItem.Subject = "My Subject"
emailItem.Body = "The Body"
'-----Send the Email-----'
emailItem.Save
emailItem.Send
'-----Clear out the memory space held by variables-----'
Set emailNameSpace = Nothing
Set emailFolder = Nothing
Set emailItem = Nothing
Set emailOutlookApp = Nothing
Exit Sub
I'm not sure if "Outlook.Application.12" is correct. But I can't find a definitive answer for this.
For Outlook 2010, this is definitly corect Outlook.Application.14.
But, I don't know what about office 2007.
I think it's Outlook.Application.12 and for lower versions it is simply "Outlook.Application".
Here's the code I switched to for 2010:
Private Sub EmailBlahbutton_Click()
Dim mOutlookApp As Object
Dim OutMail As Object
Dim Intro As String
On Error GoTo ErrorHandler
Set mOutlookApp = GetObject("", "Outlook.application")
Set OutMail = mOutlookApp.CreateItem(0)
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
'These are the ranges being emailed.
ActiveSheet.Range(blahblahblah).Select
'Intro is the first line of the email
Intro = "BLAHBLAHBLHA"
'Set the To and Subject lines. Send the message.
With OutMail
.To = "blahblah#blah.com"
.Subject = "More BLAH here"
.HTMLBody = Intro & RangetoHTML(Selection)
.Send
End With
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
ActiveSheet.Range("A1").Select
ActiveWindow.ScrollColumn = ActiveCell.Column
ActiveWindow.ScrollRow = ActiveCell.Row
Set OutMail = Nothing
Set mOutlookApp = Nothing
Exit Sub
ErrorHandler:
Set mOutlookApp = CreateObject("Outlook.application")
Resume Next
End Sub
Function RangetoHTML(rng As Range)
' Changed by Ron de Bruin 28-Oct-2006
' Working in Office 2000-2010
Dim fso As Object
Dim ts As Object
Dim TempFile As String
Dim TempWB As Workbook
TempFile = Environ$("temp") & "/" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm"
'Copy the range and create a new workbook to past the data in
rng.Copy
Set TempWB = Workbooks.Add(1)
With TempWB.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial xlPasteValues, , False, False
.Cells(1).PasteSpecial xlPasteFormats, , False, False
.Cells(1).Select
Application.CutCopyMode = False
On Error Resume Next
.DrawingObjects.Visible = True
.DrawingObjects.Delete
On Error GoTo 0
End With
'Publish the sheet to a htm file
With TempWB.PublishObjects.Add( _
SourceType:=xlSourceRange, _
Filename:=TempFile, _
Sheet:=TempWB.Sheets(1).Name, _
Source:=TempWB.Sheets(1).UsedRange.address, _
HtmlType:=xlHtmlStatic)
.Publish (True)
End With
'Read all data from the htm file into RangetoHTML
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2)
RangetoHTML = ts.ReadAll
ts.Close
RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
"align=left x:publishsource=")
'Close TempWB
TempWB.Close savechanges:=False
'Delete the htm file we used in this function
Kill TempFile
Set ts = Nothing
Set fso = Nothing
Set TempWB = Nothing
End Function
Why do you explicitly specify the version? Why not simply
Set emailOutlookApp = CreateObject("Outlook.Application")
Try "Outlook.Application.14". Not sure if this is related though: 2007 to 2010 upgrade issue
I realize it's not the exact issue, but it may lead you down the right path.

Resources