VB 2013, modify word document property/custom property - vb.net

I wish to make an add-in to update word document properties. I’m all ready to go with the addin / ribbon / etc. as I have other ribbon functions that are working. I used the MSVS wizard to create the word ribbon project.
I’m stuck on how to; access the active word document, and access the properties/custom properties. I can’t figure out the; declarations, calls, library, etc. I have not been able to make any of the MSDN samples work…. I’m totally missing something.
For example: ‘ActiveDocument.CustomDocumentProperties’ does not work.
Disclaimer - I’m not a coder. I had this all working with vba, I’m trying to port it over to vb. I’m also still reading through the posted help, and trying samples.
Any suggestions would be appreciated. Kind regards,

I got it figured.
Outside the module declare:
Imports moDoc = Microsoft.Office.Interop.Word
Within the sub - This associates the open app with an object:
Dim oActiveApp As moDoc.Application
oActiveApp = GetObject(, "Word.Application")
Now to associate the open app as a document:
Dim mocCustProperties As Microsoft.Office.Core.DocumentProperties
Dim odpProp As Office.DocumentProperty
Now odpProp is an available to read/add properties:
For Each odpProp In mocCustProperties
If odpProp.Name = “something” Then
‘do dtuff
End If
Next
There must be a way to do this by referencing the active document as a document rather than an application, but I was unable to make this work.
Cheers,

Drat - missed a couple lines above - please ignore.
I got it figured.
Outside the module declare:
Imports moDoc = Microsoft.Office.Interop.Word
Within the sub, This associated the open app with the object
Dim oActiveApp As moDoc.Application
oActiveApp = GetObject(, "Word.Application")
oDocCustomProperty = oActiveApp.ActiveDocument.CustomDocumentProperties
Now to associate the open app as a document
Dim mocCustProperties As Microsoft.Office.Core.DocumentProperties
Dim odpProp As Office.DocumentProperty
mocCustProperties = CType(oDocCustomProperty, Office.DocumentProperties)
Now odpProp is an available to read/add propoeties
For Each odpProp In mocCustProperties
If odpProp.Name = “something” Then
‘do dtuff
End If
Next

Learned some more.
I no longer need the:
Imports moDoc = Microsoft.Office.Interop.Word
Using the Office.Core. rather than the Office.Core.Interop
Dim Prop As Microsoft.Office.Core.DocumentProperty
Dim oBuiltInProperties As Microsoft.Office.Core.DocumentProperties
Dim oCustomProperties As Microsoft.Office.Core.DocumentProperties
oBuiltInProperties = DirectCast(Globals.DocSelect.Application.ActiveDocument.BuiltInDocumentProperties, Microsoft.Office.Core.DocumentProperties)
oCustomProperties = DirectCast(Globals.DocSelect.Application.ActiveDocument.CustomDocumentProperties, Microsoft.Office.Core.DocumentProperties)
For Each Prop In oBuiltInProperties
'do stuff
Prop.Name = sx
sy=Prop.Value.ToString
next
'create properties
sx="New Property"
sy="New Property Value"
oCustomProperties.Add(sx, False, Microsoft.Office.Core.MsoDocProperties.msoPropertyTypeString, sy)
All works now.

Related

How to Link a VBA code with opened ETABS OAPI?

a project on ETABS 2015 is open on my PC. I want to do some change and process on it by a VBA code automatically. but all the sample code that I found was like this:
Public Sub Example()
Dim SapModel As cSapModel
Dim EtabsObject As cOAPI
Dim FileName as String
Dim ret As Integer = -1
'create ETABS object
EtabsObject = CreateObject("CSI.ETABS.API.ETABSObject")
'start ETABS application
ret = EtabsObject.ApplicationStart()
'create SapModel object
SapModel = EtabsObject.SapModel
'initialize model
ret = SapModel.InitializeNewModel()
'open an existing file - If no file exists, run the Save example first.
FileName = "c:\CSI_API_temp\example.edb"
ret = SapModel.File.OpenFile(FileName)
This code just open a new ETABS in my PC. but my ETABS project is already running and I want to connect to it but I don't know how!
please help me.
Your sample code is basically and typically the one needed to open ETABS ITSELF and to initialize a new model,
ETABSObject = CreateObject("CSI.ETABS.API.ETABSObject") followed by the invocation of ApplicationStart method are the direct means for that.
If you refer to the ETABS API documentation file in the installation destination (e.g "C:\Program Files\Computers and Structures\ETABS 2015\CSi API ETABS 2015.chm" ) Under the section "Release Notes>Attaching to a manually started instance of ETABS", or if you see the same section from the link
http://docs.csiamerica.com/help-files/etabs-api-2015/html/3ceb8889-9028-4de3-9c87-69a12055ade7.htm
you'll find code (in VB.Net) close to what you aim to, but it will not work with vba, so, what you will simply do is this
'The ret variable, just for method invocation convenience
Dim ret As Integer
'Create an instance of the currently opened Program
Dim myETABSObject As ETABS2015.cOAPI
Set myETABSObject = GetObject(, "CSI.ETABS.API.ETABSObject")
'Create an instance to the model
Dim myETABSModel As ETABS2015.cSapModel
Set myETABSModel = myETABSObject.SapModel
'Now, after the "reference instances" are obtained
'Initialize the model (using the model's instance of course)
ret = myETABSModel.InitializeNewModel() 'default units in kip_in_F
'Set the model templete, which is "Blank"
ret = myETABSModel.File.NewBlank()
And You can normally proceed in your coding.
Note: 1- GetObject(CSI.ETABS.API.ETABSObject) method will raise an error if ETABS is not opened.
2- you still can use GetObject even if ETABS is not opened and if you want to open it from windows shell (like using command prompt to open programs instead of double clicking on their respective icons), but this of course needs some Error Handling and the use of "Windows Script Host Object Model".
3- The examples in the documentation (under the documented methods and properties) may not be complete in terms of initiating input data, in cases like this they are just to create an impression of how to use their respective methods and properties.
The code below does as you asked. It uses VBA to connect to a currently running instance of ETABS. Please note if you're running multiple instances of ETABS it may not attach to the one you want.
You'll need to add a reference to 'ETABSv1.tlb' to your VBA project. If you're using VBA Editor for Excel, on the Tools menu select References, then click Browse then add C:\Program Files\Computers and Structures\ETABS 19\ETABSv1.tlb
Sub Main()
'create API helper object
Dim myHelper As ETABSv1.cHelper
Set myHelper = New ETABSv1.Helper
'dimension the ETABS Object as cOAPI type
Dim myETABSObject As ETABSv1.cOAPI
Set myETABSObject = Nothing
'attach to a running instance of ETABS
'get the active ETABS object
Set myETABSObject = myHelper.GetObject("CSI.ETABS.API.ETABSObject")
'get a reference to cSapModel to access all API classes and functions
Dim mySapModel As ETABSv1.cSapModel
Set mySapModel = myETABSObject.SapModel
' DO YOUR WORK BELOW.
MsgBox "Do your work here."
' DO YOUR WORK ABOVE.
'clean up variables
Set mySapModel = Nothing
Set myETABSObject = Nothing
Exit Sub
ErrHandler:
MsgBox "Cannot run API script: " & Err.Description
End Sub
ETABS comes with API documentation that you can find in the installation folder. On my machine it is here: C:\Program Files\Computers and Structures\ETABS 19\CSA API ETABS v1.chm

Getting the count of sheets in debug mode - MS Excel PIA

I cannot access .Count property of Sheets. I'm using Excel Interop. I'm in debug mode and I'm trying this:
?xlSheets.Count
This results in:
(1) : error BC30456: 'Count' is not a member of 'Sheets'.
I have no clue on what's wrong, as I see in MSDN that there is such property!
This works well: ?xlSheets(1).Name. But Count fails... Is it possible to get the count of sheets?
These guys had a similar problem - they wanted to .Worksheets.Add(.Worksheets.Sheets.Count). Finally they did not get the count, they went for .Worksheets.Add(After:=.Worksheets(3))...
UPDATE:
To my great delight, after further trying / experimentations, it became clear that in debug modeSheets.Count does not work only when there is no such line in the code.
While debugging this code, I can access Sheets.Count, because this line exists in the code.
Imports Excel = Microsoft.Office.Interop.Excel
Public Class Form1
Dim xlApp As Excel.Application
Dim xlWorkBook As Excel.Workbook
Dim xlWorkbooks As Excel.Workbooks
Dim xlSheets As Excel.Sheets
Private Sub btnCreate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCreate.Click
xlApp = New Excel.Application
xlWorkbooks = xlApp.Workbooks
xlWorkBook = xlWorkbooks.Open("C:\Temp\Template.xlsm")
xlSheets = xlWorkBook.Sheets
MessageBox.Show(xlSheets.Count)
xlWorkBook.Close()
xlApp.Quit()
'Clean Up
releaseObject(xlSheets)
releaseObject(xlWorkBook)
releaseObject(xlWorkbooks)
releaseObject(xlApp)
End Sub
Private Sub releaseObject(ByVal obj As Object)
Try
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
obj = Nothing
Catch ex As Exception
obj = Nothing
Finally
GC.Collect()
GC.WaitForPendingFinalizers()
End Try
End Sub
End Class
But when I replace MessageBox.Show(xlSheets.Count) with MessageBox.Show(xlSheets.Creator), the error appears when trying to ?xlSheets.Count. I don't yet know the reason of such behaviour (I come from VBA environment where debug mode seems to be more flexible), but at least that works during run time...
If someone knows how to fix this, please let me know, as I feel restricted while testing small things in debug mode!
Use Project > Properties > References. Locate and select the "Microsoft Excel xx.x Object Library" entry. In the Properties window, set the Embed Interop Types property to False. Use Build > Rebuild to rebuild your app. It will now work the way you expected.
Briefly, this option is a strong optimization for COM interop libraries, like Microsoft.Office.Interop.Excel, you no longer have a runtime dependency on the library. The compiler copies the interop types from the library into your program's executable, only the ones you actually need to run your program. Explains your discovery, the Count property is in fact missing when you don't use it in your program.
You don't want to leave it this way, set the property back to True after you're done testing.
Your code works fine for me. I notice the file type is a macro-enabled workbook. Have you set your macro settings properly on your dev PC? By default Excel will disable macros.
Edit: I think I get your problem now. You are getting the error when trying to print the property in debug mode. Probably you have stopped the code at a point where the variable is not set (.Count is only available while the button code is actually running). Put a breakpoint on the message box line, click the button, and try again.

Previous Excel instance not getting through IIS

I am using VB.NET to open the Excel files but dont want to create excel object every time.
My code is working perfectly in debug mode, but after publish, it never gets the existing instances and always create new instances which we can see from Task Manager. Here is my code which always returns false in published mode.
My OS is Windows Server 2008. Please guide how to solve this.
Function IsExcelRunning() As Boolean
Dim xlApp As Excel.Application
On Error Resume Next
xlApp = GetObject(, "Excel.Application")
IsExcelRunning = (Err.Number = 0)
MyHelper.writeLog("Excel Instance found=" & IsExcelRunning)
xlApp = Nothing
Err.Clear()
End Function
Here is how I call.
If IsExcelRunning() Then
excelApp = GetObject(, "Excel.Application")
Else
excelApp = Server.CreateObject("Excel.Application")
End If
We used to use Excel Interop and I remember it always being difficult to work with (clunky.) Due to the Interop opening an Excel process and not closing it every time you use it, makes it difficult to work with.
The Interop opens Excel automatically, so all we needed to do was close it. This is what we used to use to kill the Process. Replace YourProcessName with Excel.exe.
Dim proc As System.Diagnostics.Process
Dim info As ManagementObject
Dim search As New ManagementObjectSearcher("SELECT ProcessId FROM Win32_process WHERE caption = 'YourProcessName'")
For Each info In search.Get()
Dim TheString As String = info.GetText(TextFormat.Mof).ToString
proc = System.Diagnostics.Process.GetProcessById(Mid$(TheString, _
(Len(TheString) - 8), 4))
proc.CloseMainWindow()
proc.Refresh()
If proc.HasExited Then GoTo NoKill
proc.Kill()
NoKill:
Next
You'll need to import
Imports System.Management
You'll also need to add the reference 'System.Management' to your project.
See: http://msdn.microsoft.com/en-us/library/vstudio/wkze6zky.aspx for adding a reference to a project.
If you can rather work with CSV, I would suggest you try to. If you are creating the Excel file yourself, try to find a report creator that let's you create / export to Excel. You'll save yourself a lot of time in the long run.

Silverlight application using vb.net. Issue creating new email in lotus notes

Im writing a silverlight application in vb.net and need to send an email via lotus notes. I wish to do this by opening the lotus notes client app, open a new email window and substitute all the necessary details (to, subject etc.) in the new email window. I am using the below code but it only OPENS the lotus notes application on the machine, it does not do anything past this. Its seems that everything after the initial CreateObject call is simply ignored, although it doesnt throw any errors. I have attempt to reference interops.domino.dll but being silverlight project visual studio states the dll is not compiled for the silverlight runtime. Any assistance with this would be greatly appreciated.
Dim outlook = AutomationFactory.CreateObject("Notes.NotesSession")
Dim notesdb = outlook.GetDatabase("", "")
notesdb.OpenMail()
Dim doc = notesdb.CreateDocument()
Dim msg = "Hey whats up"
doc.ReplaceItemValue("SendTo", "person#temp.com")
doc.ReplaceItemValue("Subject", "Hello")
Dim rtitem = doc.CreateRichTextItem("Body")
rtitem.AppendText(msg)
All you do in the moment is to create a new document in the backend and fill it with values.
It is like creating a word document without opening it...
You need some more code to actually SHOW the document you created.
In addition you need to assign a Form, otherwise Notes will not know, how to display this document:
Dim session = AutomationFactory.CreateObject("Notes.NotesSession")
Dim notesdb = outlook.GetDatabase("", "")
Dim ws = AutomationFactory.CreateObject("Notes.NotesUIWorkspace")
notesdb.OpenMail()
Dim doc = notesdb.CreateDocument()
Dim msg = "Hey whats up"
doc.ReplaceItemValue("Form", "Memo")
doc.ReplaceItemValue("SendTo", "person#temp.com")
doc.ReplaceItemValue("Subject", "Hello")
Dim rtitem = doc.CreateRichTextItem("Body")
rtitem.AppendText(msg)
ws.EditDocument( True, doc )
As I do not use silverlight I unfortunately could not test the code, but It should point into the right direction.
You can not do UI manipulations via COM in Notes, as the UI-Classes (NotesUIDocument, NotesUIWorkspace, ...) are not supported via COM.
You can only use the backend-classes likes NotesDocument, ...
This still leaves you a lot of possibilites, as you can eiter use NotesRichTextItem or MIMEEntity classes to compose e-mails.

How to do Mailmerge in Openoffice using Vb.net

Its 5th Question and apart of one I didn't get response from the experts....
Hope this time I will get the helping hand.
I want to do mailmerge in openoffice using Vb.net and I am totally new with openoffice.
I searched on net for some help to understand how to use openoffice with vb.net but all I get is half info.....So can you please help me and give me code for mailmerge in vb.net for openoffice.
Well i have list of workers in DB and there is this facility that if they want to mail to all or some of the workers then they can do it.I have completed this task using Microsoft Office now as a Add in we are providing the facility to perform the same task using Open Office.
What they have to do is just select the List of workers and click on a button and it will automate the mailmerge using the field of those workers data from DB. The Code of mine is as shown below
Public Sub OpenOfficeMail(ByVal StrFilter As String)
Dim oSM ''Root object for accessing OpenOffice from VB
Dim oDesk, oDoc As Object ''First objects from the API
Dim arg(-1) ''Ignore it for the moment !
''Instanciate OOo : this line is mandatory with VB for OOo API
oSM = CreateObject("com.sun.star.ServiceManager")
''Create the first and most important service
oDesk = oSM.createInstance("com.sun.star.frame.Desktop")
''Create a new doc
oDoc = oDesk.loadComponentFromURL("private:factory/swriter", "_blank", 0, arg)
''Close the doc
oDoc.Close(True)
oDoc = Nothing
''Open an existing doc (pay attention to the syntax for first argument)
oDoc = oDesk.loadComponentFromURL("file:///C:\Users\Savan\Documents\1.odt", "_blank", 0, arg)
Dim t_OOo As Type
t_OOo = Type.GetTypeFromProgID("com.sun.star.ServiceManager")
Dim objServiceManager As New Object
objServiceManager = System.Activator.CreateInstance(t_OOo)
Dim oMailMerge As New Object
oMailMerge = t_OOo.InvokeMember("createInstance", Reflection.BindingFlags.InvokeMethod, Nothing, _
objServiceManager, New [Object]() {"com.sun.star.text.MailMerge"}) 'com.sun.star.text.MailMerge"})
oMailMerge.DocumentURL = "file:///C:\Users\Savan\Documents\1.odt"
oMailMerge.DataSourceName = CreateSource(StrFilter)''Function that will return the datasource name which will be a text file's path
oMailMerge.CommandType = 0
oMailMerge.Command = "file:///C:\Mail.txt"
oMailMerge.OutputType = 2
oMailMerge.execute(New [Object]() {})**---->I am getting Error here**
End Sub