MS Word Interop - access CentimetersToPoints method - c#

I am trying to set the print margins in a Word Doc I am printing from my c# application but I am having trouble accessing the methods that I need to call (based on what they are in MS Word VBA)
In VBA the code looks like this:
Options.printBackground = False
With ActiveDocument.PageSetup
.TopMargin = CentimetersToPoints(0.61)
.BottomMargin = CentimetersToPoints(0.43)
.LeftMargin = CentimetersToPoints(1.27)
.RightMargin = CentimetersToPoints(0.43)
.Gutter = CentimetersToPoints(0)
End With
Here is my c# code
oWordDoc.PageSetup.TopMargin = Microsoft.Office.Interop.Word.Application.CentimetersToPoints(float.Parse ("0.61")) ;
The error I am getting is:
An object reference is required for the non-static field, method, or property 'Microsoft.Office.Interop.Word._Application.CentimetersToPoints(float)'
I have tried several varaiations after searching the VS 2010 Object Browser for CentimetersToPoints
The available interfaces in the Object Browser are:
Microsoft.Office.Interop.Word._Application.CentimetersToPoints(float)
Microsoft.Office.Interop.Word.ApplicationClass.CentimetersToPoints(float)
Microsoft.Office.Interop.Word._Global.CentimetersToPoints(float)
Microsoft.Office.Interop.Word.GlobalClass.CentimetersToPoints(float)
how can I access methods like this?
thanks

As the error message indicates, you need a reference to the Word.Application object to access this method, since it is not static.
I guess you have a oWordApp somewhere that you use to create or open the oWordDoc, so you can access the method from this object.
Or you can retreive the instance of the Word.Application from your oWordDoc (Word.Document) object.
oWordDoc.PageSetup.TopMargin = oWordDoc.Application.CentimetersToPoints(float.Parse("0.61"));

Related

How to set current cell on SAP GUIContainerShell in C#?

I am automating my work with SAP GUI script at the moment and whilst trying to recreate the recorded macro I am having an issue at one particular point which I don't know how to translate.
session.findById("wnd[0]/shellcont/shell/shellcont[1]/shell").setCurrentCell 1,"MAKTX2"
session.findById("wnd[0]/shellcont/shell/shellcont[1]/shell").doubleClickCurrentCell
session.findById("wnd[1]/tbar[0]/btn[0]").press
I have read through the SAP GUI Scripting API pdf and am struggling to see how I action the .setCurrentCell 1,"MAKTX2" part. I am accessing the container cell with the following:
GuiContainerShell materials = (GuiContainerShell)session.FindById("wnd[0]/shellcont/shell/shellcont[1]/shell");
How do I make "materials" double click "MAKTX2"?
Edit: Full SAP GUI script:
SapROTWr.CSapROTWrapper sapROTWrapper = new SapROTWr.CSapROTWrapper();
object SapGuilRot = sapROTWrapper.GetROTEntry("SAPGUI");
object engine = SapGuilRot.GetType().InvokeMember("GetScriptingEngine", System.Reflection.BindingFlags.InvokeMethod, null, SapGuilRot, null);
GuiApplication GuiApp = (GuiApplication)engine;
GuiConnection connection = (GuiConnection)GuiApp.Connections.ElementAt(0);
GuiSession session = (GuiSession)connection.Children.ElementAt(0);
GuiFrameWindow frame = (GuiFrameWindow)session.FindById("wnd[0]");
GuiTextField jobsite = (GuiTextField)session.FindById("wnd[0]/usr/subSA_0100_1:SAPMZCX_CSDSLSBM5001_OFS_OTS:2410/subSA_2410_1:SAPMZCX_CSDSLSBM5001_OFS_OTS:2510/ctxtKUWEV-KUNNR");
jobsite.Text = "I033";
frame.SendVKey(0);
GuiLabel aggregates = (GuiLabel)session.FindById("wnd[1]/usr/lbl[12,3]");
aggregates.SetFocus();
GuiFrameWindow frame2 = (GuiFrameWindow)session.FindById("wnd[1]");
frame2.SendVKey(1);
GuiContainerShell materials = (GuiContainerShell)session.FindById("wnd[0]/shellcont/shell/shellcont[1]/shell");
To be honest I can't help you with C#, but perhaps the SAP interface is generic enough anyway. Thing is, session.findById("wnd[0]/shellcont/shell/shellcont[1]/shell") gives you a reference to an object of type GuiShell or GuiContainerShell or whatever it's called. On this reference, you can call the methods defined for this type. So in the same way, when you do
session.findById("wnd[0]/shellcont/shell/shellcont[1]/shell").setCurrentCell 1,"MAKTX2"
You're just getting the reference first, and then applying the method setCurrentCell on it, all on the same line.
When you did in C#
GuiContainerShell materials = (GuiContainerShell)session.FindById("wnd[0]/shellcont/shell/shellcont[1]/shell");
you gave this reference a name materials, and provided that line works correctly, I guess you can just say now:
materials.setCurrentCell(1, "MAKTX2")
materials.doubleClickCurrentCell

Get excel filename and path error - C#

I am getting a very stupid error. I am new to VSTO and I need to get the location of the Excel file in some variable in my Addin.
string name = ActiveWorkbook.FullName;
I am getting a red line below ActiveWorkbook with error:
The name ActiveWorkBook does not exist in the current context.
I have added reference of Microsoft.Office.Interop.Excel in the code but its showing this error. I am new to this.. am I missing something?
In Excel VSTO, you need to use Globals.ThisAddIn.Application to get access to the Excel Application Model, see below :
var wb = Globals.ThisAddIn.Application.ActiveWorkbook;
string name = wb.FullName;
see also Programming VSTO Add-ins
If your code is inside the ThisAddIn class you can directly call: this.Application.ActiveWorkbook
ActiveWorkbook is not a class. It's the property of the Application interface. You can not call it in the class-name manner.
Then, you need to change your code to this.Application.ActiveWorkbook.FullName;

SSIS Custom transformation receive variable

I am creating a custom transformation in C# to be used in SSIS. I have already been able creating and adding the custom component and receive and alter data from a db source but I need more data to register in a log table. This data can only be passed with variables but I can't find a good explanation of how to add a readonlyvariable to my component.
I have tried to use IDTSVariable100 and VariableDispenser but I can't make sense of how to.
public override void ProvideComponentProperties()
{
base.ProvideComponentProperties();
base.RemoveAllInputsOutputsAndCustomProperties();
VariableDispenser varDispenser = this.VariableDispenser();
IDTSVariable100 vr = this.VariableDispenser.GetVariables();
IDTSInput100 input = this.ComponentMetaData.InputCollection.New();
input.Name = "Input_B";
IDTSOutput100 output=this.ComponentMetaData.OutputCollection.New();
output.Name = "Output_B";
// the output is synchronous with the input
output.SynchronousInputID = input.ID;
}
Basically i want to define readonlyvariables that I can alter the value before my custom component runs like the original "script component" has.
Well i researched a bit more and stumbled on a answer:
It seems that to access the SSIS public variables we have to get them with code on the ProcessInput Method:
var dimSrcId ="";
IDTSVariables100 variables = null;
this.VariableDispenser.LockForRead("User::dimSrcId");
this.VariableDispenser.GetVariables(out variables);
dimSrcId = variables["User::dimSrcId"].Value.ToString();
variables.Unlock();
By using the VariableDispenser.LockForRead() we're capable of searching for our variables and access there value.

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 do you call "Document Format" programmatically from C#?

I'm writing a simple VS add-in and would like to programmatically invoke the "Document Format" option (under Edit) within code. Google isn't being very friendly to me today....
Command cmd = _applicationObject.Commands.Item("Edit.FormatDocument", -1);
object dummy = null;
_applicationObject.Commands.Raise(cmd.Guid, cmd.ID, ref dummy, ref dummy);
If you have a reference to your document (of type Window), and you have a reference to the _DTE object, you can call it like this:
myDocument.Activate();
myDTE.ExecuteCommand("Edit.FormatDocument", string.Empty);
Most of the time, you can get a reference to the _DTE object from the parameters passed into your add-in.
You'll need to use the standard command editors, called with the VSStd2KCmdId.FORMATDOCUMENT command enumeration.

Categories

Resources