Word VSTO: Save a string as an AutoText value - vb.net

I am porting a Word vba project that has some older WordBasic elements into a VSTO project using vb.net. One of the tasks I need to do is programmatically save a string, or the contents of a text box on a form, to an AutoText value in the Word template.
In the old project, this was easy. The command looked something like this:
WordBasic.SetAutoText "AT Name", strSomeValue, 0
Attempting this in vb.net:
'declarations
Public appWord As Word.Application
Public tplMyTpl As Word.Template
Public doc As Word.Document
'Get the template
appWord = Me.Application
doc = appWord.ActiveDocument
tplMyTpl = doc.AttachedTemplate
'try saving autotext
tplMyTpl.AutoTextEntries.Add("AT Name", strSomeValue)
does not work because the AutoTextEntries.Add method only accepts the value as a Word.Range. A type cast error is thrown at runtime with the code above. It would have to look something like:
dim sel as Word.Selection = appWord.Selection
tplMyTpl.AutoTextEntries.Add("AT Name", sel.Range)
Problem is I do not want to insert the string into my document, select it as a Range, save the AutoText entry then delete the text. That seems like extremely sloppy coding.

You can still use WordBasic in VSTO. Just call it through your Word.Application object reference, e.g.:
appWord.WordBasic.SetAutoText("AT Name", strSomeValue, 0)
Tested and working in Word 2013.

Related

MS Word runs on background and requests documents to be saved even though it is already saved

I have a procedure that creates a PDF file according to an ms word template and its data is retrieved from a database.
It works fine, creates a PDF file perfectly , no run time errors. The problem is that whenever I shut off the computer, ms word prevents the shutdown and if I press cancel ms word shows a message;
The code goes like this;
Dim wordApp As Word.Application
Dim templateBookmarks As Word.Bookmarks
Dim templateName As String
Dim template As Word.Document
'Some other variables for computations
wordApp = CreateObject("Word.Application")
sourceTable = New DataTable
'Some other procs to fill the data table
templateName = "Foo Template.docx"
template = wordApp.Documents.Add(templatePath & templateName)
templateBookmarks = template.Bookmarks
templateBookmarks.Item("sample bookmark").Range.Text = "foo"
'Then fills the table in the template like...
template.Tables(1).Cell(1, 1).Range.Text = dataSource.Rows(0).Item(0)
'Then saves the document as a pdf
Dim saveName As String = "sample file"
template.SaveAs2(savePath & saveName, Word.WdSaveFormat.wdFormatPDF)
I have tried to force garbage collection for the word COM resources, as well as changing the template from an actual document i.e. docx to a word template .dotx. I also tried the method Quit() but it only shows the ms word message much earlier. This is the first time I needed to use interop so pardon if I don't have much idea about it.
The files I needed are saved, the only problem is the ms word message and unsaved and unnecessary files e.g. Document1,Document2,Document3 that seems to be created aside from the required PDF
Use the Document.Close method which closes the specified document after saving files using the PDF file format. It allows specifying the SaveChanges parameter which specifies the save action for the document. Can be one of the following WdSaveOptions constants: wdDoNotSaveChanges, wdPromptToSaveChanges, or wdSaveChanges.
On Error GoTo errorHandler
ActiveDocument.Close SaveChanges:=wdDoNotSaveChanges
errorHandler:
If Err = 4198 Then MsgBox "Document was not closed"

Why is the code to change the color of a cell in vb.net different from vba?

This may sound dumb but can someone explain the reason why I need to include this extra code in vb.net that I don't need in VBA when changing the color of a cell.
I wrote a program that creates and saves an excel file using the microsoft.office.interop reference. Here is my code:
Public Class Export_Excel_Class
Public excelapp As Microsoft.Office.Interop.Excel.Application
Public excelbook As Microsoft.Office.Interop.Excel.Workbook
Public excelsheet As Microsoft.Office.Interop.Excel.Worksheet
Public Sub newExcel()
excelapp = New Microsoft.Office.Interop.Excel.Application
excelbook = excelapp.Workbooks.Add()
excelsheet = excelbook.Sheets("sheet1")
excelsheet.Range("A1").Select()
excelsheet.Range("a1").AddComment("hello")
excelsheet.Range("a1:B10").Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Yellow)
excelbook.SaveAs("C:\Users\DatOneBull\Desktop\Excel_Test")
excelapp.Quit()
End Sub
On the line that sets the color I had originally had tried excelsheet.Range("a1:B10").Interior.Color =
and tried to set a color but the color proptery is read only. I found the solution online but there was no explanation. Can someone tell me what this section of code means and why it is able to set the color value of th range?
System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Yellow)
VB.NET stores colors differently to VBA. The ToOle function converts the VB.NET color to the equivalent VBA version. This is an example of marshalling.
(If you are interested, the "OLE" in "ToOle" stands for "Object Linking and Embedding" which is an older way for windows programs to communicate with each other)
In VBA, you would set the color something like this:
Range("A1").Interior.Color = Excel.XlRgbColor.rgbYellow
' Or
Range("A2").Interior.Color = VBA.RGB(255, 255, 0)
Note that I purposely fully qualified the VBA code. This is valid VBA code, but in a style you rarely see.
In VB.Net you can do it like:
ws.Range("A1").Interior.Color = Excel.XlRgbColor.rgbYellow
ws.Range("A2").Interior.Color = Microsoft.VisualBasic.Information.RGB(255, 255, 0)
essentially the same code. Or you can do it like you are currently doing.
The net effect is the same; an integer value that represents color is being assigned to the Interior.Color property. Either you use a function to compute that value, or you use a constant. The various .Net functions are equivalents to the VBA.RGB function. VBA knows nothing about colors defined as a System.Drawing.Color, hence a conversion function is necessary.

VB 2013, modify word document property/custom property

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.

How do I center a paragraph in Word using vb.net?

I am using Visual Studio 2015 and coding in vb.net and importing Microsoft.Office.Interop.Word . I am using the following code to create a one page Word document with only two lines. How can I center, both vertically and horizontally these two lines? Also, is there a way to put both lines, with a line break in between, in one paragraph rather than using two? I am very new to this type of programming so please be specific. Thanks.
Private Sub CreateTitlePage2()
Dim wdApp As Microsoft.Office.Interop.Word.Application = New Microsoft.Office.Interop.Word.Application
Dim wdDoc As Microsoft.Office.Interop.Word.Document = New Microsoft.Office.Interop.Word.Document
Dim wdPara1 As Microsoft.Office.Interop.Word.Paragraph
Dim wdPara2 As Microsoft.Office.Interop.Word.Paragraph
wdDoc.Application.Visible = False
wdPara1 = wdDoc.Content.Paragraphs.Add
wdPara1.Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter
wdPara1.Range.Font.Bold = True
wdPara1.Range.Text = "BINDER DOCUMENT"
wdPara1.Range.InsertParagraphAfter()
wdPara2 = wdDoc.Content.Paragraphs.Add
wdPara2.Format.SpaceBefore = WdVerticalAlignment.wdAlignVerticalCenter
wdPara2.Range.Font.Bold = True
wdPara2.Range.Text = "Created: " + formattedDate2
wdPara2.Range.InsertParagraphAfter()
wdDoc.SaveAs(binderNameDoc)
wdDoc.Close()
wdApp.Quit()
End Sub
#Ross: It would help if you'd describe HOW it's "not working". However...
WdVerticalAlignment is not valid applied to a paragraph object, I'm surprised you're not getting a compiler error. See https://msdn.microsoft.com/en-us/library/aa224305(v=office.11).aspx.
If you want to center something vertically on the page then it must be done via the PageSetup object and then it will apply to the entire SECTION. See https://msdn.microsoft.com/en-us/library/office/ff838676.aspx?f=255&MSPPError=-2147217396
If you document is really only the one page, as you say, then you don't need to worry about the SECTION part as the document will have only the one.
RE Line break: Insert ANSI 11 character (vbVerticalTab) for a line break (what you get when pressing Shift+Enter in the Word application).

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