Pages

Monday, January 9, 2012

How to find and replace text programmatically – MS Word


While working with the Add – In, came across the scenario where I needed to replace the text in word document programmatically, this is how it can be done
Following code finds the word occurrence and replaces with the desired characters in first paragraph of the document.
private void FindAndReplaceText(object _wordToFind, object _replaceWith)
{
      
 string _text = Globals.ThisAddIn.Application.ActiveDocument.Paragraphs[0].Range.Text;

 object machtCase = true;
 object matchWholeWord = true;
 object matchWildCards = false;
 object matchSoundsLike = false;
 object nmachtAllWordForms = false;
 object forward = true;
 object format = false;
 object matchKashida = false;
 object matchDiacritics = false;
 object matchAlefHamza = false;
 object matchControl = false;
 object read_only = false;
 object visibible = true;
 object replace = 2;
 object wrap = 1;

 _Globals.ThisAddIn.Application.ActiveDocument.Paragraphs[0].Range.Find.Execute(ref _wordToFind,
        ref machtCase,
        ref matchWholeWord,
        ref matchWildCards,
        ref matchSoundsLike,
        ref nmachtAllWordForms,
        ref forward,
        ref wrap,
        ref format,
        ref _replaceWith,
        ref replace,
        ref matchKashida,
        ref matchDiacritics,
        ref matchAlefHamza,
        ref matchControl);
 }

Reference Link: - Here

Tuesday, January 3, 2012

How to Read Document Properties Programmatically


This was the one of good learning while working with MS Office Add-In using visual studio so thought to share.
Each document ships with some kind of metadata with it, and to them we call as properties. For word documents there are three types of properties available (As per my knowledge). And here are those
(Examples / APIs below are accessible when you create new application level add in, reference links are from MSDN pages where excel is considered as MS Office Application)

1.    Built In Properties / Default Properties – These are set of properties which are available with any word document, example of these can be – Title, Description, Keywords. More Information/Reference - Here
You can programmatically deal with these properties as –
DocumentProperties builtInDocProperties = (DocumentProperties)Globals.ThisAddIn.Application.ActiveDocument.BuiltInDocumentProperties;
foreach (DocumentProperty prop in builtInDocProperties)
{
   try
   {
     //Console.WriteLine(prop.Name + " - " + prop.Value);
   }
   catch { }
}

2.   Custom Properties – More Information / Reference - Here
DocumentProperties customDocProperties =  (DocumentProperties)Globals.ThisAddIn.Application.ActiveDocument.CustomDocumentProperties;

foreach (DocumentProperty prop in customDocProperties)
{
   try
   {
//Console.WriteLine(prop.Name + " - " + prop.Value);
   }
   catch { }
}

3.    Content Type Properties – These are the set of properties which are as the site columns / fields    in content type of the document library. In short these are server side properties of the document when document is opened from the document library. You won’t be able to access these properties programmatically when document is opened locally on machine. i.e. unless and until document is not opened from SharePoint document library , these properties will not be available to do to get/set operations. More Information Here / Reference - Here

MetaProperties _ctProperties = (MetaProperties)Globals.ThisAddIn.Application.ActiveDocument.ContentTypeProperties;
foreach (MetaProperty _ctp in _ctProperties)
{
   try
   {
       //Console.WriteLine(ctp.Name + " - " + ctp.Value);
   }
   catch { }
}

Noticed catch blocks while iterating through for each loop? Yes, these are required because few properties throws exception and reason is unknown to me. For example, in content type properties whenever people and group type of property is accessed, exception is thrown. You can read more on the MSDN Forums about this issue. – Here is the link.
More ever you can set the server side properties programmatically using same API like –
MetaProperties _ctProperties = (MetaProperties)Globals.ThisAddIn.Application.ActiveDocument.ContentTypeProperties;
_ctProperties ["Title"].Value = "TestTitle";

You just need to call the save method of the document instance to get these properties reflected in document library.

Word Add In Installer - Unable to read App Config


app.config file is not getting read after installing word add in installer?
Solution:
In Installer project there is a registry key for add in which has manifest entry. MSDN Documentation says that manifest values should be set to - [TARGETDIR]YourAddIn.vsto|vstolocal , now when this is changed to file path like file:/// [TARGETDIR]YourAddIn.vsto|vstolocal and reinstalling add in I got everything working fine.
Note : This worked for me and there is no guarantee that will work in each scenario , also be careful while modifying registry entries.

Error while accessing office document cache


I don’t know why but suddenly I started facing this error while I was trying to create new document or edit existing document in the SharePoint document library. was using Office 2010 and SharePoint 2010.
Error Message was: - Error while accessing office document cache.
Solution:
A quick search on the dear friend google given some idea I don’t remember what was the source of this post and that’s why thought to share.
Open task manager and take a look at processes tab. Try to find the process with name MSOSYNC.exe

And end the process. Now try to create / open documents from SharePoint document library and I hope this error will not be there anymore.
Note: I didn’t search for where else this process is used for, so not sure what effects this can have in your environment but worked fine for me for above error.
More Information about MSOSYNC.exe and other way to delete cached files here.

How to set people and group column programmatically using Client Object Model


using SP = Microsoft.SharePoint.Client;
using (SP.ClientContext _ctx = new SP.ClientContext("http://YourSiteUrl"))
{
  SP.ListItem _listItem = null;

  ctx.Credentials = CredentialCache.DefaultCredentials;
 
  SP.List _testList = web.Lists.GetByTitle("TestList");
  SP.CamlQuery _query = new SP.CamlQuery();
  query.ViewXml = @"<View><Query><Where><Geq><FieldRef Name='ID'/>" + "<Value Type='Number'>10</Value></Geq></Where></Query></View>";
  SP.ListItemCollection _listitems = _configList.GetItems(_query);

  ctx.Load(_listitems);
  ctx.ExecuteQuery();
 
  if (_listitems != null && _listitems.Count > 0)
  {
     _listItem = _listitems[0];

     SP.FieldUserValue _userValue = new SP.FieldUserValue();
     SP.User _newUser = _ctx.Web.EnsureUser("domain\\username");
     _ctx.Load(_newUser);
     _ctx.ExecuteQuery();

     _userValue.LookupId = _newUser.Id;

     _listItem["userfield"] = _userValue;
     _listItem.Update();

     _ctx.ExecuteQuery();

  }   

);

Wednesday, December 28, 2011

How to hide properties in Document Information Panel – SharePoint

Document Information Panel – This is the window which shows all the properties associated with the document. Let it be out of the box / default properties (like Title, Keywords), or custom properties or content type properties.

Wait, what are content type properties?
Consider a scenario where you have a SharePoint site and a document library. You create some site columns and then create content type for your document library. (Inheriting from the document content type). Now you associate this newly created content type to your document library and done.

You go ahead and click on create New Document link and Word Editor opens up. Now there you see the Document Information Panel (DIP) containing all the site columns in your content type. These are metadata holders for your document. And that’s why these document properties are called as content type properties.

In Following Image, I have opened the document from the SharePoint document library and added Version and Comments column in the default document content type , which are visible in DIP.


Issue:
There were some of the content type properties which were getting displayed in DIP, but I didn’t want users to see those /change those. In short I needed to hide those.
Let’s try to hide version property from DIP.
Solution:
First thought comes to mind like – ok these properties are nothing but the site columns right? So why don’t we just delete the site columns and get rid of properties in DIP? But NO. Because if we delete the site columns from the content type , the DIP won’t show the property but document will not be holding the metadata for that column.
So what could be done?
Trick I found is, just hide the site column.
How we can do it?
Library settings > Find your content type and click on it > select the site column which you don’t want to see in DIP > click on Hidden option in advanced option and select ok.



Now DIP will not show the content type property when creating new documents from the library
Version column gets hidden from DIP



Note: This approach is used only when the site column is not of type mandatory/required. As per my knowledge you cannot hide the column which is required.


How to debug the word add in project in Visual Studio

Last few days I was playing much with MS word add ins and its development, Yes you are right, when the word ‘develop’ comes into the picture , each and every developer needs to think some logic and then they let the figures do the remaining job. There are many times when run-time error occurs and developer go ahead and track/find them using debugger.
Most of us use Visual Studio, the developer’s heaven as IDE for the .NET based application development and Microsoft has given way too good features to debug your code. (Link here)
Some examples:
·         When debugging web based projects / SharePoint farm solutions , one attaches the debugger to the w3wp.exe (IIS process)
·         When debugging sandboxed solutions one needs to attach the debugger to the SPUCWorkerProcess.exe (SPUC)
·         And again while debugging the timer jobs in SharePoint debugger needs to be attached to Timer service. (OWSTimer.exe)
Ok ok, before I get the question like – come on we know all of these.. I will come to the point directly.
I learnt a lesson that if you need to debug the MS Office Addins then you must attach the debugger to the appropriate MS Office Client.
In my case, as I was working with MS Word Addin – so I needed to attach the debugger to WINWORD.exe service, like this

 
If you do not see WINWORD.exe process , make sure that you have launched the MS Word Client and selected – Show all process , show process from all users/sessions in the attach debugger window.
Also If the debugger is not getting attached, then make sure that the add-in is referring to the dll is latest in the respective location. (For example If add in is referring to the dll somewhere in release folder of your solution then make sure that the dll is latest)