Add a header in Project with COM Interop - c#

I used COM Interop to automatically create a MS-Project file and I added few tasks in it.
I am trying to automatically add a header and a footer in this file similarly than the way it works in MS-Word as below :
foreach (Microsoft.Office.Interop.Word.Section section in myDoc.Sections)
{
Microsoft.Office.Interop.Word.Range headerRange = section.Headers[Microsoft.Office.Interop.Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
headerRange.Fields.Add(headerRange, Microsoft.Office.Interop.Word.WdFieldType.wdFieldPage);
headerRange.ParagraphFormat.Alignment = Microsoft.Office.Interop.Word.WdParagraphAlignment.wdAlignParagraphRight;
}
But I don't find document on the subject, is it in the least possible?
Edit
I have tried with this syntax :
Application.FilePageSetupHeader , 1, "Date: &[Date]"
But it looks like a VBA syntax and I am using C# with Interop COM.
I've tried with this instruction that I found while doing some tests :
project.Application.FilePageSetupHeader(1, PjAlignment.pjCenter, "Date");
But it alway gives me this error System.Runtime.InteropServices.COMException: 'The argument value is not valid.'
Does anybody know a clean syntax in C# or the way FilePageSetupHeader works in C# ?

The headers and footers in MS Project are rudimentary. There is a single string property for each section (left, center, right); formatting is done via format codes.
For example, this adds the date to the center header:
Application.FilePageSetupHeader , PjAlignment.pjCenter, "Date: &[Date]"
FilePageSetupHeader Documentation
FilePageSetupFooter Documentation

As all the parameters of the function FilePageSetupHeader are optionals, it seems that the first parameter, the view is required. So I had to get it like this (I have only one view in my project) :
Microsoft.Office.Interop.MSProject.Views views = project.Views;
Microsoft.Office.Interop.MSProject.View view = null;
foreach(Microsoft.Office.Interop.MSProject.View vw in views)
{
view = vw;
}
Then you can use it edit your header :
projApp.Application.FilePageSetupHeader(view, Microsoft.Office.Interop.MSProject.PjAlignment.pjCenter,
"Date: " + DateTime.Now.ToString("dd/MM/yyyy"));
Note : projApp is a Microsoft.Office.Interop.MSProject.Application object.

Related

Null Reference Exception when calling iText7 PdfAcroForm.GetAcroForm() in .Net Core 3.1 class library

I am working on converting an application to .Net Core 3.1, and in my class library I am generating a PDF form from an existing template, and filling that form with data. In ITextSharp, the predecessor to IText7, the PdfAcroForm static method ".GetAcroForm()" worked perfectly, but in the current version of iText7 (7.1.12) a Null Reference Exception is thrown. I have followed the documentation to the best of my ability, but I am unsure how to continue. Any suggestions would be appreciated.
NOTE: The template path exists, the new document shows that it has been filled properly, and it is impossible to "new" a PdfAcroForm, you are required to use the static .GetAcroForm() method.
A null check will not solve this issue, as the object should never be null. The documentation indicates that the .GetAcroForm() method will create a new form if the parameter "createNotExist" is set to true, which I have done here.
I have researched and have located an issue on the iText GitHub that indicates that this issue was "fixed" around a year ago: https://github.com/itext/itext7/pull/44#issue-351612749
The following is the method which prepares the forms:
public string DocumentGenerator(string templatePath, FormFieldSet[] formFieldSet, bool useSpecailOutputPath)
{
if(!File.Exists(templatePath))
{
throw new Exception("The template file provided does not exist: MC-071(iText)");
}
string newFile = useSpecailOutputPath ?
m_SpecialOutputPath :
Path.GetTempPath() + Guid.NewGuid().ToString() + ".pdf";
try
{
PdfDocument newDocument = new PdfDocument(new PdfReader(templatePath), new PdfWriter(newFile));
PdfAcroForm acroForm = PdfAcroForm.GetAcroForm(newDocument, true); // <=== Exception Thrown Here
foreach (FormFieldSet fs in formFieldSet)
{
acroForm.GetField(fs.FieldName).SetValue(fs.FillValue);
}
// Sets form flattening
acroForm.FlattenFields();
// Closes and writes the form
newDocument.Close();
return newFile;
}
catch { return string.Empty; };
}
Any suggestions would be greatly appreciated
I had the same problem, and after digging down all the way to iText7's internal objects and methods, I finally "solved" my problem.
Apparently iText has some internal errors/exceptions that they are just sort of "skipping" and "pushing past", because I realized by accident that I had "Enable Just My Code" in Visual Studios disabled, and so my system was trying to debug iText7's code as well as mine. The moment that I re-enabled it in my Visual Studio settings (Tools > Options > Debugging > General > Enable Just My Code checkbox), the problem magically went away.
So I spent four hours trying to troubleshoot a problem that was in THEIR code, but that they apparently found some way to work around and push through the method anyways even on a null reference failure.
My convert to PDF function is now working just fine.
Just an update to anyone looking for this issue. This is a known issue and is fixed in the current development branch. You are safe to bypass the exception in visual studio until it is corrected. This has no negative impact on the functionality and is the result of a misplaced return in the original iText7 source.

BizTalk Dynamic Disassembler Problems - The body part is NULL

I started with the solution here http://social.technet.microsoft.com/wiki/contents/articles/20547.biztalk-server-dynamic-schema-resolver-real-scenario.aspx
which matches my scenario perfectly except for the send port, but that isn't necessary. I need the receive port to choose the file and apply a schema to disassemble. From their the orchestration does the mapping, some of it custom, etc.
I've done everything in the tutorial but I keep getting the following error.
"There was a failure executing the receive pipeline... The body part is NULL"
The things I don't get from the tutorial but don't believe they should be an issue are:
I created a new solution and project to make the custompipeline component (reference figure 19) and thus the dll file. Meaning it is on it's own namespace. However, it looks like from the tutorial they created the project within the main biztalk solution (ie the one with the pipeline and the orchestration) and thus the namespace has "TechNetWiki.SchemaResolver." in it. Should I make the custompipeline component have the namespace of my main solution? I'm assuming this shouldn't matter because I should be able to use this component in other solutions as it is meant to be generic to the business rules that are associated with the biztalk application.
The other piece I don't have is Figure 15 under the "THEN Action" they have it equal the destination schema they would like to disassemble to but then they put #Src1 at the end of "http://TechNetWiki.SchemaResolver.Schemas.SRC1_FF#Src1". What is the #Src1 for?
In the sample you've linked to, the probe method of the pipeline component is pushing the first 4 characters from the filename into a typed message that is then passed into the rules engine. Its those 4 characters that match the "SRC1" in the example.
string srcFileName = pInMsg.Context.Read("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties This link is external to TechNet Wiki. It will open in a new window. ").ToString();
srcFileName = Path.GetFileName(srcFileName);
//Substring the first four digits to take source code to use to call BRE API
string customerCode = srcFileName.Substring(0, 4);
//create an instance of the XML object
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(string.Format(#"<ns0:Root xmlns:ns0='http://TechNetWiki.SchemaResolver.Schemas.SchemaResolverBRE This link is external to TechNet Wiki. It will open in a new window. '>
<SrcCode>{0}</SrcCode>
<MessageType></MessageType>
</ns0:Root>", customerCode));
//retreive source code in case in our cache dictionary
if (cachedSources.ContainsKey(customerCode))
{
messageType = cachedSources[customerCode];
}
else
{
TypedXmlDocument typedXmlDocument = new TypedXmlDocument("TechNetWiki.SchemaResolver.Schemas.SchemaResolverBRE", xmlDoc);
Microsoft.RuleEngine.Policy policy = new Microsoft.RuleEngine.Policy("SchemaResolverPolicy");
policy.Execute(typedXmlDocument);
So the matching rule is based on the 1st 4 characters of the filename. If one isn't matched, the probe returns a false - i.e. unrecognised.
The final part is that the message type is pushed into the returned message - this is made up of the namespace and the root schema node with a # separator - so your #src1 is the root node.
You need to implement IProbeMessage near to class
I forgot to add IProbeMessage in the code of article. It is updated now.
but it is there in sample source code
Src1 is the the root node name of schema. I mentioned that in article that message type is TargetNamespace#Root
I recommend to download the sample code
I hope this will help you

Cannot set Word Style's Base Style From C#

Microsoft.Office.Interop.Word version 14.0.0.0. .NET 4.0 VS 2010.
The MS Word API's Style class has a BaseStyle property that can be used to set the style's base (based on) style. That property works fine for me in VBA.
However from C# using Word interopt there is no BaseStyle property. However, there are two (undocumented as far as I can tell) functions set_BaseStyle() and get_BaseStyle().
When I call set_BaseStyle() I get a COMException with the message:
"This command is not available."
I think this means that the COM interface does not support the procedure (command). But why? Why does it appear in intellisense and compile? Is there a workaround?
This simple example works on my machine (VS 2012, Office 2007)
Application application = new Application {Visible = true};
string styleName1 = "Heading 1";
object styleNameObject1 = styleName1;
string styleName2 = "Heading 2";
object styleNameObject2 = styleName2;
var document = application.Documents.Add();
document.Select();
application.Selection.set_Style(ref styleNameObject2);
Style style = (Style)application.Selection.get_Style();
Style baseStyle = style.get_BaseStyle();
style.set_BaseStyle(ref styleNameObject1);
application.Selection.Range.Text = "This is the title";
application.Quit(false);
So the problem probably lies in your setup. The message is rather vague and it says word cannot do stuff, for other examples look at C# and Word2010 : DeleteAllComments throws "This command is not available." or search and replace in Word documents via .NET automation.
Is the file readonly? Does it happen with other styles or simpler files (such as my example)? Are Macros allowed in Word?
I found the problem.
The sample code posted by Vadim was a big help, as it did work, and I slowly slowly converted in to my code and eventually broke it, them moved back and forth until I homed in on the problem.
However, I can't explain what I found!
I was specifying all parameters when I opened the (existing) document with Application.Documents.Open(). It turns out that if I specify false (0) for the isvisible parameter, the code fails. If I secify true (-1) it works.
Note that in either case I can make 100s of other changes to the document. For some reason I cannot change the base style if it is invisible.
strange.
Thanks for your help.

How to add a Bookmark control to a Word document at runtime

I want to add in a C# application a bookmark to a particular range to my Word document at runtime . I have found one solution
Microsoft.Office.Tools.Word.Bookmark bookmark1;
bookmark1 = this.Controls.AddBookmark(this.Paragraphs[1].Range, "bookmark1");
But an error shows that the Windows form has no definition for AddBookmark. Please help.
You are using a WinForms application, therefore by using the keyword this it will refer to the form class you are using which does not have a definition for Controls.AddBookmark.
I suggest you take a look here: http://msdn.microsoft.com/en-us/library/cc442946.aspx
This will show you how to create a word addin from which you can then use this code to add a bookmark.
Microsoft.Office.Tools.Word.Bookmark bookmark1; bookmark1 = this.Controls.AddBookmark(this.Paragraphs[1].Range, "bookmark1");

How do I get latest clearcase label programmatically from C#?

I am trying to put version information to my C# GUI framework retrieved from the latest ClearCase label. This was originally done from Visual Soursafe as below.
vssDB = new VSSDatabaseClass();
vssDB.Open( databaseName, "vssadmin", "vssadmin" );
VSSItem item = vssDB.get_VSSItem( #"$\BuildDCP.bat", false );
foreach(VSSVersion vssVersion in item.get_Versions(0))
{
// Pull the first non-blank label and use that
if ( vssVersion.Label != "" )
{
labelID = vssVersion.Label.ToString();
break;
}
}
I am trying to do something similar using ClearCase since we changed our source code control from VSS to CC. Any help would be greatly appreciated.
Thanks!
I believe this could be better achieved through a script, which would be called from your C# program.
But you may be able to directly call some COM objects, through the CAL interface provided with ClearCase.
The documentation for the interface can be accessed through ClearCase help (Start>Programs>Rational ClearCase>ClearCase Help), where there's an entry for "ClearCase Automation Library (CAL)". An alternate path is to look in the ClearCase/bin directory for "cc_cal.chm".
In VB, with CAL API, that would give something like:
Dim CC As New ClearCase.Application
Dim labelID As String
Set aVersion = CC.Version("[Path-To]\BuildDCP.bat");
Set someLabels = Ver.Labels;
If (someLabels.Count > 0) Then
' the first label listed is the most recently applied
labelID = someLabels.Item(1).Type.Name
EndIf
I really wish that the COM interfaces had better documentation, or were more obvious. Or that the code to ClearCase Explorer or Project Explorer were open source.
I've done a few cool things, but I pretty much started by adding COM references to my C# project, and then started screwing around with the interfaces I found.
Good luck!

Categories

Resources