I want to set a public folder to have an initial view (custom view), I know how to do it manually on outlook 2007, however, I cannot find any property or method i can use in the Interop (Folder and MAPI folder) that can do this.
After a few hours of googling, i came out the following:
Imports NUnit.Framework
Imports System.Windows.Forms
Imports System.Net.Mail
Imports System.Net.Mime
Imports System.Net
Imports System.Runtime.InteropServices
Imports Outlook = Microsoft.Office.Interop.Outlook
<TestFixture()>
Public Class TestOutlook
<Explicit()>
<Test()>
Public Sub TestSetFolderInitialView()
Dim ol As New Outlook.Application
Dim exCatched As Exception = Nothing
Try
' Get My Mailbox
Dim myFolder As Outlook.MAPIFolder = Nothing
For i As Integer = 0 To ol.Session.Folders.Count - 1
myFolder = ol.Session.Folders(i + 1)
If myFolder.Name = "Mailbox - Rex" Then ' Change it to your mail box name
Exit For
End If
Next
' Get the folder I want to Set initial view
Dim testFolder As Outlook.MAPIFolder = Nothing
If myFolder IsNot Nothing Then
For i As Integer = 0 To myFolder.Folders.Count - 1
Dim pFolder = myFolder.Folders(i + 1)
If pFolder.Name = "Inbox" Then
For Each fol As Outlook.MAPIFolder In pFolder.Folders
If fol.Name = "TestFolder" Then
testFolder = fol
Exit For
End If
Next
Exit For
End If
Next
End If
If testFolder IsNot Nothing Then
Try
' Create a test view
Dim newVw = CType(testFolder.Views.Add("RexTest-" & DateTime.Now.ToString("yyyyMMdd-hhmmss"),
Outlook.OlViewType.olTableView,
Outlook.OlViewSaveOption.olViewSaveOptionThisFolderEveryone),
Outlook.TableView)
newVw.LockUserChanges = True
newVw.Save()
newVw.Apply()
' PR_DEFAULT_VIEW_ENTRYID:
Dim ns = "http://schemas.microsoft.com/mapi/proptag/"
Dim PR_DEFAULT_VIEW_ENTRYID = "0x36160102"
Dim PR_FOLDER_XVIEWINFO_E = "0x36E00102"
Dim defaultVw = testFolder.PropertyAccessor.GetProperty(ns & PR_DEFAULT_VIEW_ENTRYID)
Dim xVwInfo = testFolder.PropertyAccessor.GetProperty(ns & PR_FOLDER_XVIEWINFO_E)
' the defaultVw is nothing for the first time (actually throw exception)
' if i manually change it from the outlook,
' the value will be something like: 000000004B593F3D35EF8C42AB181C105AE444D40700E46C905CB9ABE446AA44351902AFC40E000026BF7A8C000040DB82FE9B98724F9B222A9C9BDB42CD0000005CF0280000
' **** The problem is how to get the correct binary data for the newly created view so i can set it like this: *****
'testFolder.PropertyAccessor.SetProperty(ns & PR_DEFAULT_VIEW_ENTRYID, testFolder.PropertyAccessor.StringToBinary(newVw.Name))
Catch ex As Exception
' _log.Warn(String.Format("Error set initial view {0} to folder - {1}", newVw.Name, testFolder.Name), ex)
exCatched = ex
' First time error 'The property "http://schemas.microsoft.com/mapi/proptag/0x36160102" is unknown or cannot be found' will be shown
' If we set the initial view of the folder in the outlook, this error will go away
End Try
End If
Catch ex As Exception
Debug.WriteLine(ex.Message)
Debug.WriteLine(ex.StackTrace)
exCatched = ex
Finally
If ol IsNot Nothing Then
Marshal.ReleaseComObject(ol)
ol = Nothing
End If
End Try
If exCatched IsNot Nothing Then
Throw exCatched
End If
End Sub
End Class
Now the only left part is how to get the correct binary data from the newly created view. some clue to manipulate the binary value: http://microsoft.public.win32.programmer.messaging.narkive.com/x1fNHHA5/default-view
however it was written in a different language and I got no idea how to make it in vb or c#.
any help appreciated.
Have you tried MAPIFolder.CurrentView and MAPIFolder.Views?
Related
I found a lot of examples about uploading a resource to ALM via UFT.
However there were always a resource already created in ALM.
How can i create and upload a resource to ALM using UFT?
My problem is I don't know how many resources I am going to need, so I have to dinamically create resources and then upload them.
I do not want to upload files as attachments to the run.
Thank you
I think I found the answer here: http://www.codetweet.com/other/create-new-resource-almqc-using-ota/
Sub CreateNewResource(resourceFolderId As Integer, fileType As String, fileName As String, fileParentFolderPath As String)
On Error GoTo Errhandler:
'--- Represents a file or folder stored in the Quality Center repository
Dim resource As QCResource
'--- Represents a QC resource folder.
Dim resourceFolder As QCResourceFolder
'--- Services for managing QC resources.
Dim resourceFactory As QCResourceFactory
'--- Services for managing QC resource folders.
Dim resourceFolderFactory As QCResourceFolderFactory
'--- Services to manage resource storage.
Dim testResourceStorage As IResourceStorage
Dim resourceItem
Dim resourceFound As Boolean
' ***TDConn is TDConnection class object.Create this object before using this function.
Set resourceFolderFactory = TDConn.QCResourceFolderFactory
Set resourceFolder = resourceFolderFactory.Item(resourceFolderId)
Set resourceFactory = resourceFolder.QCResourceFactory
Set currResourceList = resourceFactory.NewList("")
For ItemCount = 1 To currResourceList.Count
currItem = currResourceList.Item(ItemCount).Name
If UCase(currItem) = UCase(fileName) Then
Set resourceItem = currResourceList.Item(ItemCount)
resourceFound = True
Exit For
End If
Next
If Not resourceFound Then
'--- Create a resource
Set resourceItem = resourceFactory.AddItem(fileName)
resourceItem.ResourceType = fileType
resourceItem.fileName = fileName
resourceItem.Post
'--- Check if the resources added successfully
Set currResourceList = resourceFactory.NewList("")
For ItemCount = 1 To currResourceList.Count
currItem = currResourceList.Item(ItemCount).Name
If UCase(currItem) = UCase(fileName) Then
resourceFound = True
Exit For
End If
Next
If resourceFound Then
'--- Attach the file to resource
resourceItem.vC.CheckOut ""
Set testResourceStorage = resourceItem
testResourceStorage.UploadResource fileParentFolderPath, False
resourceItem.vC.CheckIn "Automated check-in by utility" & Now
Else
oFile.WriteLine ("Recently added new resource not found on ALM.Try again later.")
Exit Sub
End If
Else
resourceItem.vC.CheckOut ""
Set testResourceStorage = resourceItem
testResourceStorage.UploadResource fileParentFolderPath, False
resourceItem.vC.CheckIn "Automated check-in by utility" & Now
End If
Set resourceFolderFactory = Nothing
Set resourceFolder = Nothing
Set resourceFactory = Nothing
Set currResourceList = Nothing
Exit Sub
Errhandler:
MsgBox("Error Executing - `CreateNewResource` ; Error Uploading file " & fileName)
Exit Sub
End Sub
I have both AutoCAD and AutoCAD Architecture installed on my system. AutoCAD Architecture has a tab called Vision Tools with a nifty command called Display By Layer to set the display order of objects in accordance with the layers of the drawing. Is there anyway to add this tab or use this command in AutoCAD?
Not sure if you're looking for a built-in feature or APIs for it.
For a built in feature, check the DRAWORDER command. For an API/programming approach, check the respective DrawOrderTable method. See below:
Update: please also check this 3rd party tool: DoByLayer.
[CommandMethod("SendToBottom")]
public void commandDrawOrderChange()
{
Document activeDoc
= Application.DocumentManager.MdiActiveDocument;
Database db = activeDoc.Database;
Editor ed = activeDoc.Editor;
PromptEntityOptions peo
= new PromptEntityOptions("Select an entity : ");
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK)
{
return;
}
ObjectId oid = per.ObjectId;
SortedList<long, ObjectId> drawOrder
= new SortedList<long, ObjectId>();
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = tr.GetObject(
db.BlockTableId,
OpenMode.ForRead
) as BlockTable;
BlockTableRecord btrModelSpace =
tr.GetObject(
bt[BlockTableRecord.ModelSpace],
OpenMode.ForRead
) as BlockTableRecord;
DrawOrderTable dot =
tr.GetObject(
btrModelSpace.DrawOrderTableId,
OpenMode.ForWrite
) as DrawOrderTable;
ObjectIdCollection objToMove = new ObjectIdCollection();
objToMove.Add(oid);
dot.MoveToBottom(objToMove);
tr.Commit();
}
ed.WriteMessage("Done");
}
With some help from VBA it might look by this. Note i did not add fancy listbox code. I just show the worker and how to list layers. The trivial Code to add things to a listbox on a form and how to sort / rearrange listbox items can be found on any excel / VBA forum on the web . Or you just uses a predefined string like in the example. To get VBA to work download and install the acc. VBA Enabler from autocad. It is free.
'select all items on a layer by a filter
Sub selectALayer(sset As AcadSelectionSet, layername As String)
Dim filterType As Variant
Dim filterData As Variant
Dim p1(0 To 2) As Double
Dim p2(0 To 2) As Double
Dim grpCode(0) As Integer
grpCode(0) = 8
filterType = grpCode
Dim grpValue(0) As Variant
grpValue(0) = layername
filterData = grpValue
sset.Select acSelectionSetAll, p1, p2, filterType, filterData
Debug.Print "layer", layername, "Entities: " & str(sset.COUNT)
End Sub
'bring items on top
Sub OrderToTop(layername As String)
' This example creates a SortentsTable object and
' changes the draw order of selected object(s) to top.
Dim oSset As AcadSelectionSet
Dim oEnt
Dim i As Integer
Dim setName As String
setName = "$Order$"
'Make sure selection set does not exist
For i = 0 To ThisDrawing.SelectionSets.COUNT - 1
If ThisDrawing.SelectionSets.ITEM(i).NAME = setName Then
ThisDrawing.SelectionSets.ITEM(i).DELETE
Exit For
End If
Next i
setName = "tmp_" & time()
Set oSset = ThisDrawing.SelectionSets.Add(setName)
Call selectALayer(oSset, layername)
If oSset.COUNT > 0 Then
ReDim arrObj(0 To oSset.COUNT - 1) As ACADOBJECT
'Process each object
i = 0
For Each oEnt In oSset
Set arrObj(i) = oEnt
i = i + 1
Next
End If
'kills also left over selectionset by programming mistakes....
For Each selectionset In ThisDrawing.SelectionSets
selectionset.delete_by_layer_space
Next
On Error GoTo Err_Control
'Get an extension dictionary and, if necessary, add a SortentsTable object
Dim eDictionary As Object
Set eDictionary = ThisDrawing.modelspace.GetExtensionDictionary
' Prevent failed GetObject calls from throwing an exception
On Error Resume Next
Dim sentityObj As Object
Set sentityObj = eDictionary.GetObject("ACAD_SORTENTS")
On Error GoTo 0
If sentityObj Is Nothing Then
' No SortentsTable object, so add one
Set sentityObj = eDictionary.AddObject("ACAD_SORTENTS", "AcDbSortentsTable")
End If
'Move selected object(s) to the top
sentityObj.MoveToTop arrObj
applicaTION.UPDATE
Exit Sub
Err_Control:
If ERR.NUMBER > 0 Then MsgBox ERR.DESCRIPTION
End Sub
Sub bringtofrontbylist()
Dim lnames As String
'predefined layer names
layer_names = "foundation bridge road"
Dim h() As String
h = split(layernames)
For i = 0 To UBound(h)
Call OrderToTop(h(i))
Next
End Sub
'in case you want a fancy form here is how to get list / all layers
Sub list_layers()
Dim LAYER As AcadLayer
For Each LAYER In ThisDrawing.LAYERS
Debug.Print LAYER.NAME
Next
End Sub
to make it run put the cursor inside the VBA IDE inside the code of list_layers andpress F5 or choose it from the VBA Macro list.
How would you go about opening a form in another project from a form..
Lets say i have such a project structure:
p1
frm1
frm2
p2
frmxyz
opening frm1 from frmxyz in VB6...? Something like:
p1.frm1.show() 'Maybe?
How do you do it?
There two different ways to resolve this issue:
1.)
You can add frm1 to project p2, with project -> add form -> tab "existing". After that you can easily access with frm1.show().
2.)
you create an interface object with a function to access the form compile the p1 as an active-x dll. in the next step, you can add the active-x dll as reference in p2 and show the form on calling the the function in the interface object.
It's faily complicated. The easiest way I figured how to do it is the following :
Sub UseExternalUserForm()
'Set the File name, File path, and Form name
Dim myForm As String, myDirectory As String, myFile As String
myDirectory = "C:\FilePath\"
myFile = "MyFile.xls"
myForm = "UserForm1"
'Start dealing with workbooks and their objects
Dim vbc As Object
Dim wb1 As Workbook, wb2 As Workbook
Set wb1 = ThisWorkbook
Set wb2 = Workbooks.Open(myDirectory & myFile)
If UserFormExists(2, myForm) Then
'Export the form if it exists
wb2.VBProject.VBComponents(myForm).Export (myForm & ".frm")
Else
'Display an error message if it doesn't
MsgBox myForm & " doesn't exist in " & wb2.Name
End If
wb2.Close False
If UserFormExists(1, myForm) Then
'Display an error message if it already exists
MsgBox myForm & " already exists in " & wb1.Name
Else
'Import the form if it doesn't
Set vbc = Application.VBE.vbProjects(1).VBComponents.Import(myForm & ".frm")
VBA.UserForms.Add(myForm).Show
'Remove the imported form
Application.VBE.vbProjects(1).VBComponents.Remove vbc
End If
End Sub
'How to figure out if a form already exists in a project (numbered with an integer representing the index
' of the project in the VBAProject Explorer)
Public Function UserFormExists(projectIndex As Integer, formName As String) As Boolean
On Error Resume Next
UserFormExists = (Application.VBE.vbProjects(projectIndex).VBComponents(formName).Name = formName)
On Error GoTo 0
End Function
Let me know if you need any extra explanations as to how to get this code to work for you.
I need some help please. I have managed to create a task in outlook using VB and SendItem. My problem is the code I'm using is creating two tasks and not just the one I want.
I have tried removing the .Save as I thought this was the cause but it still adds two tasks. I have added breakpoints to the code to ensure its not cycling round twice for some obscure reason and it just executes once.
Would appreciate someone telling me the obvious please
Code snippet:
`If bNotFount = False Then
Set Ns = Application.GetNamespace("MAPI")
Set ItemT = GetCurrentItem()
Set taskFolder = Ns.GetDefaultFolder(olFolderTasks)
Set olTask = Ns.GetDefaultFolder(olFolderTasks).Items.Add(olTaskItem)
With olTask
.Subject = ItemT.Subject
.Attachments.Add ItemT
.Body = ItemT.Body
.DueDate = Now + 1
.Move taskFolder
.Save
.Display 'show the task to add notes
End With
End If'
You don't need to move it to the default task folder because you saving it there anyway.
Just remove .Move taskFolder line.
I updated your code:
Private Sub Application_ItemSend(Item As Object, ByRef Cancel As Boolean) Handles Application.ItemSend
Dim ns As Outlook.NameSpace
Dim taskFldr As Outlook.Folder
Dim olTask As Outlook.TaskItem
' If bNotFount = False Then
Ns = Application.GetNamespace("MAPI")
taskFldr = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderTasks)
olTask = taskFldr.Items.Add
With olTask
.Subject = Item.Subject
.Attachments.Add(Item)
.Body = Item.Body
.DueDate = Now + 1
.Save()
.Display() 'show the task to add notes
End With
' End If
End Sub
In Visual studio 2010>New Project>Visual Basic>Windows>Windows forms Application, i have made a form (form1.vb) and a database (Local Database>"Database1.sdf") and a Table with 3 Columns ("Name","City","Age").
I like to copy this 3 fields and paste to document "test1.doc" (open this with Ms Office or Open Office Writer). I have bookmarks ("PasteName", PasteCity", "PasteAge") in specified places in test1.doc .
How to make a button to open the document "test1.doc" and copy - paste this 3 items from table to doc and preview before print it? (not for save - only print preview and close without save after printing)
I have find this code for MS Office but didn't work in Visual Studio. I like something similar. (this code is for a doc Form Fields - I have Bookmarks in my doc).
Private Sub cmdPrint_Click()
Dim appWord As Word.Application
Dim doc As Word.Document
Set appWord = GetObject(, "Word.Application")
Set appWord = New Word.Application
Set doc = appWord.Documents.Open("C:\WordForms\CustomerSlip.doc", , True)
With doc
.FormFields("fldCustomerID").Result = Me!CustomerID
.FormFields("fldCompanyName").Result = Me!CompanyName
.FormFields("fldContactName").Result = Me!ContactName
.Visible = True
.Activate
End With
Set doc = Nothing
Set appWord = Nothing
End Sub
Thanks programers people
This works for me. (button action)
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'Print customer slip for current customer.
Dim appWord As Word.Application
Dim doc As Word.Document
'Avoid error 429, when Word isn't open.
On Error Resume Next
Err.Clear()
'Set appWord object variable to running instance of Word.
appWord = GetObject(, "Word.Application")
If Err.Number <> 0 Then
'If Word isn't open, create a new instance of Word.
appWord = New Word.Application
End If
doc = appWord.Documents.Open("D:\Test.docx", , True)
doc.Visible()
doc.Activate()
With doc.Bookmarks
.Item("Name").Range.Text = Me.NameID.Text
.Item("City").Range.Text = Me.CityID.Text
End With
Dim dlg As Word.Dialog
dlg = appWord.Dialogs.Item(Word.WdWordDialog.wdDialogFilePrint)
dlg.Display()
'doc.Printout
doc = Nothing
appWord = Nothing
Exit Sub
errHandler:
MsgBox(Err.Number & ": " & Err.Description)
End Sub