How to automate Public folder calender to show in Favorite Folder of mail - vbscript

How to automate the process to show my public folder calender in Mail Favorite folder?
I wanted to do it either by login script or by group policy.
I am using Microsoft Exchange server 2007 with Windows Server 2008 R2 and Domain controller running Windows Server 2003 R2.
All workstation system have either Outlook 2010 or Outlook 2007.
While searching on this I found the script below, but by this script (already modified the path) I am just able to make public folder calender to show in public folder favorite but not in mail favorite folder.
Const olPublicFoldersAllPublicFolders = 18
Dim olkApp, olkSes, olkFolder
Set olkApp = CreateObject("Outlook.Application")
Set olkSes = olkApp.GetNameSpace("MAPI")
'Change the profile name on the next line'
olkSes.Logon "Outlook"
'Change the folder name on the next line. Repeat the next two lines for each folder
you want to add.'
Set olkFolder =
olkSes.GetDefaultFolder(olPublicFoldersAllPublicFolders).Folders("Public
calender").Folders("p cal")
olkFolder.AddToPFFavorites
'Change the folder name on the next line. Repeat the next two lines for each folder
you want to add.'
Set olkFolder = OpenOutlookFolder("Public Folders\Favorites\P cal")
AddFavoriteFolder olkFolder
olkSes.Logoff
Set olkApp = Nothing
Set olkSes = Nothing
Set olkFolder = Nothing
WScript.Quit
Sub AddFavoriteFolder(olkFolder)
' Purpose: Add a folder to Favorite Folders.'
' Written: 5/2/2009'
' Author: BlueDevilFan'
' Outlook: 2007'
Const olModuleMail = 0
Const olFavoriteFoldersGroup = 4
Dim olkPane, olkModule, olkGroup
Set olkPane = olkApp.ActiveExplorer.NavigationPane
Set olkModule = olkPane.Modules.GetNavigationModule(olModuleMail)
Set olkGroup =
olkModule.NavigationGroups.GetDefaultNavigationGroup(olFavoriteFoldersGroup)
olkGroup.NavigationFolders.Add olkFolder
Set olkPane = Nothing
Set olkModule = Nothing
Set olkGroup = Nothing
End Sub
Function OpenOutlookFolder(strFolderPath)
' Purpose: Opens an Outlook folder from a folder path.'
' Written: 4/24/2009'
' Author: BlueDevilFan'
' Outlook: All versions'
Dim arrFolders, varFolder, bolBeyondRoot
On Error Resume Next
If strFolderPath = "" Then
Set OpenOutlookFolder = Nothing
Else
Do While Left(strFolderPath, 1) = "\"
strFolderPath = Right(strFolderPath, Len(strFolderPath) - 1)
Loop
arrFolders = Split(strFolderPath, "\")
For Each varFolder In arrFolders
Select Case bolBeyondRoot
Case False
Set OpenOutlookFolder = olkSes.Folders(varFolder)
bolBeyondRoot = True
Case True
Set OpenOutlookFolder = OpenOutlookFolder.Folders(varFolder)
End Select
If Err.Number <> 0 Then
Set OpenOutlookFolder = Nothing
Exit For
End If
Next
End If
On Error GoTo 0
End Function

You can't do this. You can only add mail folders or search folders to the Mail Favorites view. Quoting Outlook's help, Favorites contain "shortcuts to folders such as your Inbox, Sent Items, and Search Folders. You can add, remove, and arrange folders [...] access your mail folders more easily" (my emphasis).
From MSFT's point of view, this is logically consistent.
Adding a public object to your public folder favorites is the type of activity that a user is expected to do infrequently. So it's not appropriate to handle that in a login script. It's like adding resources to your personal library of information, eg a folder with project status or manuals.
Adding a mail folder to your Mail Favorites is a quick and dirty trick for frequently used items. This is more like adding a bookmark.
You could argue that if you have to set up a large number of users that all need access to a public folder, that it makes sense to handle that in a login script, and that is fine, but again, it would be adding it to the public folder favotires, not the mail one....and you've have to have code to not create the favorite if it already existed.

Related

How to get MST properties from vbscript

So, I am creating a vbscript that will read an MSI and MST file. The idea is that if the user that will run the script is testing an MSI with an MST file involved, the script should create a "report" of the new properties that this MST have.
I am able to get the properties from a regular MSI, the problem is when I am trying to get into the MST section. While doing research I found out about the _TransformView Table and this should help me to obtain this information but I think I am not sure I know how to handle that table.
Const msiTransformErrorViewTransform = 256
Const msiOpenDB = 2
Dim FS, TS, WI, DB, View, Rec
Set WI = CreateObject("WindowsInstaller.Installer")
Set DB = WI.OpenDatabase(msiPath,msiOpenDB)
DB.ApplyTransform mstPath, msiTransformErrorViewTransform
If Err.number Then
Exit Function
End If
For i = 0 To 24 'Number of properties on the arrPropertyList
Set View = DB.OpenView("Select `Value` From Property WHERE `Property` = " & "'" & arrPropertyList(i) & "'")
View.Execute
Set Rec = View.Fetch
If Not Rec Is Nothing Then
objLog.WriteLine arrPropertyList(i) & " = " & Rec.StringData(1)
End If
Next
That code will display the msi properties that I have added on the arrPropertyList. The thing is that I am looking for the MST properties and I am only getting the MSI ones. I know that I should change the Query to access the _TransformView Table when calling the DB.OpenView but not sure how can I get to this information! Any knowledge you can share would be welcome.
It works slightly differently to what you think. Run the following to see what I mean (maybe force the VBS to run with Cscript.exe from a command prompt if you're expecting a lot of output):
'create 2 constants - one for when we want to just query the MSI (read) and one for when we want to make changes (write)
Const msiOpenDatabaseModeReadOnly = 0
Const msiOpenDatabaseModeTransact = 1
Const msiTransformErrorViewTransform = 256
'create WindowsInstaller.Installer object
Dim oInstaller : Set oInstaller = CreateObject("WindowsInstaller.Installer")
'open the MSI (the first argument supplied to the vbscript)
Dim oDatabase : Set oDatabase = oInstaller.OpenDatabase("C:\Temp\Temp.msi",msiOpenDatabaseModeReadOnly)
oDatabase.ApplyTransform "C:\Temp\Temp.mst", msiTransformErrorViewTransform
'create a view of the registry we want to see
Dim sql : sql = "SELECT * FROM `_TransformView`"
Dim regView : Set regView = oDatabase.OpenView(sql)
'execute the query
regView.Execute
'fetch the first row of data (if there is one!)
Dim regRecord : Set regRecord = regView.Fetch
'whilst we've returned a row and therefore regRecord is not Nothing
While Not regRecord Is Nothing
'print out the registry key
wscript.echo "Table: " & regRecord.StringData(1)
wscript.echo "Column: " & regRecord.StringData(2)
wscript.echo "Row: " & regRecord.StringData(3)
wscript.echo "Data: " & regRecord.StringData(4)
wscript.echo "Current: " & regRecord.StringData(5)
wscript.echo "***"
'go and fetch the next row of data
Set regRecord = regView.Fetch
Wend
regView.Close
Set regView = Nothing
Set regRecord = Nothing
Set oDatabase = Nothing
Set oInstaller = Nothing
So if you only wanted to see changes in the Property table, you would change the SQL query to:
Dim sql : sql = "SELECT * FROM `_TransformView` WHERE `Table` = 'Property'"
As well as storing the column names of the changed entries, the 'Column' column in the '_TransformView' table also stores whether the value was inserted, removed etc by using the values:
INSERT, DELETE, CREATE, or DROP.
You can find lots of VBScript Windows Installer tutorials for reference - don't forget to set your objects to Nothing otherwise you'll leave handles open. And of course use the link you provided for further reference.
WiLstXfm.vbs: Are you familiar with the MSI SDK sample: wilstxfm.vbs (View a Transform)? It can be used to view transform files. Usage is as follows:
cscript.exe WiLstXfm.vbs MySetup.msi MySetup.mst
Mock-up output:
Property Value [INSTALLLEVEL] {100}->{102}
File DELETE [Help.chm]
I think all you need is in there? Maybe give it a quick look. There is a whole bunch of such MSI API Samples - for all kinds of MSI purposes.
Github.com / Windows SDK: These VBScripts are installed with the Windows SDK, so you can find them on your local disk if you have Visual Studio installed, but you can also find them on Github.com:
Github: WiLstXfm.vbs - Microsoft repository on github.com.
Disk: On your local disk, search under Program Files (x86) if you have Visual Studio installed. Current Example: %ProgramFiles(x86)%\Windows Kits\10\bin\10.0.17763.0\x86.

Use VBScript to show properties dialog/sheet - for multiple items

I'm trying to write a script in VBS to show the file properties dialog/sheet for multiple items. Those items will be all of the items in a parent folder (e.g. all items in W:\).
Essentially, I'm trying to get the properties dialog to show the number of files in a drive. Right-clicking on the drive and selecting Properties does not show the number of files. You would instead need to go into the first level of the drive, select all folders/files, and then right-click and select Properties.
I have customised some code (below) I've found on the internet to bring up the file properties dialog/sheet for either a specific folder, or a drive. I have no idea what I could further change to get the properties dialog for all files and folder of a specified drive. Perhaps getting all folders/files of the drive into an array and then working with that?
Please note I'm looking for the actual properties dialog, and not just a simple return of the total number of files (I know how to do this).
Any help would be appreciated! Thanks :)
Code:
dim objShell, objFSO, folParent, sParent, filTarget, sFileName, sOutput, fivVerbs, iVerb, vVerb, fvbVerb, testItemsParent, TestMappedDestination
set objFSO = CreateObject("Scripting.FileSystemObject")
set objShell = CreateObject("Shell.Application")
const mappedDestination = "c:\"
vVerb = "P&roperties"
sParent = objFSO.GetParentFolderName(mappedDestination)
sFileName = objFSO.GetFileName(mappedDestination)
If Len(mappedDestination) = 3 then
nsTarget = &H11
TestMappedDestination = "(" & UCase(Left(mappedDestination,2)) & ")"
Else
nsTarget = sParent
TestMappedDestination = UCase(sFileName)
End If
set folParent = objShell.Namespace(nsTarget)
For each filTarget in folParent.Items
If Len(mappedDestination) = 3 then
testItemsParent = UCase(Right(filTarget,4))
Else
testItemsParent = UCase(filTarget)
End if
If testItemsParent = TestMappedDestination then
Set fivVerbs = filTarget.Verbs
For iVerb = 0 to fivVerbs.Count - 1
If fivVerbs.Item(iVerb).Name = vVerb then
Set fvbVerb = fivVerbs.Item(iVerb)
fvbVerb.DoIt()
filTarget.InvokeVerbEx fvbVerb.Name, ""
Msgbox "Placeholder msgbox to keep properties dialog/sheet from disappearing on script completion"
Exit for
End if
Next
Exit for
End if
Next

Word document mysteriously write protected?

I am trying to do a find and replace operation on several Word documents in a folder. I wrote the following VBScript to do that:
Option Explicit
Dim Word, Document, FolderPath, FileSystem, FileList, File, Doc, InfoString
Const ReadOnly = 1
Const wdFindContinue = 1
Const wdReplaceAll = 2
Const wdOriginalDocumentFormat = 1
Set FileSystem = CreateObject("Scripting.FileSystemObject")
FolderPath = FileSystem.GetAbsolutePathName(".")
Set FileList = FileSystem.GetFolder(FolderPath).files
Set Word = CreateObject("Word.Application")
Word.Visible = False
Word.DisplayAlerts = False
For Each File in FileList
If LCase(Right(File.Name,3)) = "doc" Or LCase(Right(File.Name,4)) = "docx" Then
If File.Attributes And ReadOnly Then
File.Attributes = File.Attributes - ReadOnly
End If
Set Doc = Word.Documents.Open(File.Path,,True)
' find and replace stuff
End If
Next
Word.Documents.Save True, wdOriginalDocumentFormat
Word.Quit
MsgBox("Done")
Problem is, when it reaches the line Word.Documents.Save, a Save As dialog box always pops up. If I click Cancel, I get an error from Windows Script Host saying the file is write protected, even though it is not shown as write protected if I open the Properties dialog in File Explorer. If I click save, I am prompted to save all the other files too. What is the problem here?
I have a suspicion that it is caused by the Word documents being very old, like from the 1990s.
Set Doc = Word.Documents.Open(File.Path,,True)
and look at the docs from Object Browser.
Function Open(FileName, [ConfirmConversions], [ReadOnly], [AddToRecentFiles], [PasswordDocument], [PasswordTemplate], [Revert], [WritePasswordDocument], [WritePasswordTemplate], [Format], [Encoding], [Visible], [OpenAndRepair], [DocumentDirection], [NoEncodingDialog]) As Document
Member of Word.Documents
So the True says to open Read Only. This is Word's read only, nothing to do with the file.

Open files with common name part

First of all, please excuse my shortcomings in presenting my issue as I haven't got much knowledge in VBA. Your help would be kindly appreciated.
I am working on a project that would imply putting the content of three different Excel files from three different sub-folders into one Excel file, and then run some macros in order to process the data they contain. Since I've already set the processing macros, my issue relies in importing the content correctly.
The problem I'm facing is that I don't have the exact names of the files I would like to open, and that they would change each month. Therefore, I can't use the "WorkBooks.Open" command that requires a precise name. However, the files have predictable name formats. For instance, one of the sub-folders will be comprised of files named "XXX-jan2013.xls", another one "january2013-XXX" and the last one "XXX-01/2013".
My goal would be to input the month and year manually, for instance “01/2013”, and then open all the files containing "January”, “jan” or “01" in their names.
Here’s what I have so far, with comments:
Sub ChosenDate()
‘It aims at opening a box in which the desired month would be written manually
Dim InputDate As String
‘These are the indications the user will get
InputDate = InputBox(Prompt:="Please choose a month.", _
Title:="Date", Default:="MM/YYYY")
‘In case the person forgets to write what he’s asked to
If InputDate = "MM/YYYY" Or _
InputDate = vbNullString Then
Exit Sub
‘If he does it correctly, I call the second Sub
Else: Call FilesOpening
End If
End Sub
‘So far, everything works fine
Public Sub FilesOpening()
‘This one aims at opening the chosen files
Dim ThisFile As String
Dim Files As String
‘Defining the folder in which the file is, as it can change from a computer to another
ThisFile = ThisWorkbook.Path
‘Here’s where I start struggling and where the macro doesn’t work anymore
‘If I wanted to open all the files of the folder, I would just write that:
Files = Dir(ThisFile & "\*.xls")
‘You never know…
On Error Resume Next
‘Creating the Loop
Do While Files <> vbNullString
Files = Dir
Set wbBook = Workbooks.Open(ThisWorkbook.Path & "\" & Files)
Loop
End Sub
‘But it doesn’t look inside of sub-folders, neither does it consider the date
Sub DataProcess()
‘This one is fine, except I can’t find a way to name the files correctly. Here’s the beginning:
Windows("I don’t know the name.xls").Activate
Sheets("Rapport 1").Select
Cells.Select
Selection.Copy
Windows("The File I Want To Put Data In.xlsm").Activate
Sheets("Where I Want To Put It").Select
Range("A1").Select
ActiveSheet.Paste
Windows("I don’t know the name.xls").Close
‘How can I get the name?
I hope my statement is understandable.
Thank you very much in advance!
Have a nice day,
E.
You need to build a list of the paths and the expected file masks. You can then loop each matching file and do your stuff.
Sub foo()
Dim request As String: request = "01/2013"
'//make a date
Dim asDate As Date: asDate = "01/" & request
Dim dirs(2) As String, masks(2) As String
dirs(0) = "c:\xxx\dir1\"
masks(0) = "*" & Format$(asDate, "mmmmyyyy") & "*.xls"
dirs(1) = "c:\xxx\dir2\"
masks(1) = "*" & Format$(asDate, "mmmyyyy") & "*.xls"
dirs(2) = "c:\xxx\dir3\"
masks(2) = "*" & Format$(asDate, "mmyyyy") & "*.xls"
Dim i As Long
For i = 0 To UBound(dirs)
GetFiles dirs(i), masks(i)
Next
End Sub
Private Function GetFiles(path As String, mask As String)
Dim file As String
'//loop matching files
file = Dir$(path & mask)
Do Until Len(file) = 0
'//process match
process path & file
file = Dir$()
Loop
End Function
Sub process(filePath As String)
MsgBox "processing " & filePath
'workbook.open
End Sub
As "XXX-01/2013" is not a file name I assumed "XXX-012013".
If its another subdirectory just:
dirs(x) = "c:\xxx\dir3\" & Format$(asDate, "mm") & "\"
masks(x) = "*" & year(asDate) & "*.xls"

Sending email from webpage using Outlook

I have a webpage that has a button that sends a letter on the page to an email recipent. Currently we are use Lotus Notes and with VB script, we are able to create an object of Lotus Notes and one of the properties for this object is PutInFolder. After the user clicks on the email button, the script will send the email and also put save the email in a certain folder on the user's computer. Our company is now switching over to Outlook 2007 and I'm looking to do the same thing with an Outlook object instead. Our development is local intranet only, and there are only a few users that will have access to this. Anyway, my problem is I cannot seem to find the same functionality with an Outlook Application.
I do have the send of the email currently working using this logic. Does anyone have any ideas on how to save the email in the user's outlook folder? I tried looking for a list of properties that I can call but I cannot find anything searching. Maybe I don't have the right terminalogy in the searches.
Thank you.
sub send_mailvb(sendto, sendcc, sendbcc, subject_text, body_text, attachment1, attachment2, attachment3)
'Open mail, adress, attach report
dim objOutlk 'Outlook
dim objMail 'Email item
dim strMsg
const olMailItem = 0
'Create a new message
set objOutlk = createobject("Outlook.Application")
set objMail = objOutlk.createitem(olMailItem)
' Setup send to
objMail.To = sendto
' Setup send cc
If sendcc <> "" Then
objMail.cc = sendcc
End If
' Setup send bcc
If sendbcc <> "" Then
objMail.bcc = sendbcc
End If
'Set up Subject Line
objMail.subject = subject_text
'Add the body
strMsg = body_text & vbcrlf
'Add an attachments
If attachment1 <> "" Then
objMail.attachments.add(attachment1)
End If
If attachment2 <> "" Then
objMail.attachments.add(attachment2)
End If
If attachment3 <> "" Then
objMail.attachments.add(attachment3)
End If
objMail.body = strMsg
objMail.display 'Use this to display before sending, otherwise call objMail.Send to send without reviewing
'Clean up
set objMail = nothing
set objOutlk = nothing
End Sub
For future reference... I found the solution I was looking for. It wasn't too bad of a mess. Here's the modified source to replicate the Send and save email to a specific folder incase someone else comes looking. Thanks to Tester101 for the website I was looking for. Again this is vbscript imbedded in the HTML page.
sub send_mailvb(sendto, sendcc, sendbcc, subject_text, body_text, attachment1, attachment2, attachment3)
'Open mail, adress, attach report
dim objOutlk 'Outlook
dim objMail 'Email item
dim strMsg
dim myInbox
const olMailItem = 0
'Create a new message
set objOutlk = createobject("Outlook.Application")
Set objNameSpace = objOutlk.Session
set objMail = objOutlk.createitem(olMailItem)
Set myNameSpace = objOutlk.GetNamespace("MAPI")
Set myExplorer = objOutlk.ActiveExplorer
' 6 at least on my machine pointed to the Inbox (should be the same as constant olFolderInbox). Within the Inbox I have a folder called Test
Set myExplorer.CurrentFolder = myNameSpace.GetDefaultFolder(6).Folders("Test")
Set myFolder = myExplorer.CurrentFolder
' Setup send to
objMail.To = sendto
' Setup send cc
If sendcc "" Then
objMail.cc = sendcc
End If
' Setup send bcc
If sendbcc "" Then
objMail.bcc = sendbcc
End If
'Set up Subject Line
objMail.subject = subject_text
'Add the body
strMsg = body_text & vbcrlf
'Add an attachments
If attachment1 "" Then
objMail.attachments.add(attachment1)
End If
If attachment2 "" Then
objMail.attachments.add(attachment2)
End If
If attachment3 "" Then
objMail.attachments.add(attachment3)
End If
objMail.body = strMsg
// objMail.display 'Use this to display before sending, otherwise call objMail.Send to send without reviewing
objMail.Save
objMail.Move(myFolder)
objMail.Send
'Clean up
set objMail = nothing
set objOutlk = nothing
End Sub
I found this article. It might be something tha could help.
http://www.outlookcode.com/codedetail_print.aspx?id=1041
If not this site has great resources for working with outlook.
It looks like the MailItem object has a Save method, as well as a SaveAs method. So you should be able to do something like this.
objMail.SaveAs "C:\Test.msg", 3
The 3 is to save the message in olMSG format see OlSaveAsType Enumeration.
I have a solution. We've decided to bcc the person sending the email and then use an outlook rule to move the email to the specified outlook folder. Thanks to everyone that replied.

Resources