Edit Excel Spreadsheet object in word document (C# Interop) - c#

I am currently trying to edit cells of an excel spreadsheet object with c# interop. I inserted it in a word document as an object.
Until there i didn't succeed to programm anything that really works. I'm able to select the component but i can't open it to edition and then reach grid's cells.
I use a button control in a custom office ribbon to launch edit. Here is my method:
public void EditTable(Office.IRibbonControl control)
{
Word.Application oWordApp = (Word.Application)Marshal.GetActiveObject("Word.Application");
Word.Document oWordDoc = oWordApp.ActiveDocument;
Word.Bookmark ReqsBookmark = DocumentHelper.GetBookmark("test");
ReqsBookmark.Select();
}
The only way i know to access a specific object with interop is with bookmarks.
Does anybody have an idea of how doing such a thing?

In Word, an Excel worksheet (workbook) is "wrapped" in an OLE control that is a member of the InlineShapes or Shapes collection. So you need the AddOLEObject method of the collection you want to use.
Access to the object model of the OLE server (Excel) is through the OLEFormat property of the InlineShape or Shape. So your code would be something like the sample below.
Note that although you say this is a VSTO project, the code you show us is not VSTO. You're starting up a new instance of the Word.Application, but the VSTO Add-in would be running in-process. My code is VSTO code, but can certainly be adjusted for other situations...
{
Word.Document doc = Globals.ThisAddIn.app.ActiveDocument;
object oRngTarget = Globals.ThisAddIn.app.Selection.Range;
//object oRngTarget = DocumentHelper.GetBookmark("test").Range;
object oOLEClass = "Excel.Sheet.12";
object oFalse = false;
Word.InlineShape ils = doc.InlineShapes.AddOLEObject(ref oOLEClass, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing, ref oRngTarget);
Word.OLEFormat olef = ils.OLEFormat;
System.Globalization.CultureInfo oldCI= System.Threading.Thread.CurrentThread.CurrentCulture;
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
Excel.Workbook wb = (Excel.Workbook)olef.Object;
Excel.Worksheet ws = (Excel.Worksheet)wb.Worksheets[1];
try
{
ws.get_Range("A1").Value2 = "New category";
ws.get_Range("B1").Value2 = 6.8;
}
catch (Exception ex)
{
System.Diagnostics.Debug.Print(ex.Message);
}
finally
{
ws = null;
wb = null;
ils = null;
doc = null;
System.Threading.Thread.CurrentThread.CurrentCulture = oldCI;
}
}
To later work with a spreadsheet in the Word document, you basically follow the same principle: declare and instantiate a InlineShape.OLEFormat object, Activate it, then cast olef.Object to an Excel.Workbook:
olef.Activate();
Excel.Workbook wb = (Excel.Workbook)olef.Object;

I finally succeeded thanks to this post about modify an embedded Excel object inside a Word doc
Here's the c# method if anybody need it one day:
{
Word.Document oWordDoc = Globals.ThisAddIn.Application.ActiveDocument;
Excel.Workbook oOLE = null;
Excel.Worksheet oSheet = null;
Word.InlineShapes ils = oWordDoc.InlineShapes;
ils[1].OLEFormat.Activate();
oOLE = ils[1].OLEFormat.Object;
oSheet = oOLE.Worksheets[1];
oSheet.get_Range("A1").Value = "I did it too!";
}
Thank you again #CindyMeister for your answer, it helped me to understand how it really works.

Related

Word Interop Bookmarks Dont Exist

I am currently creating a c# program which uses a template.dotx containing pre-defined building blocks (with bookmarks) to insert pages of content into a new document, all working as follows
Word._Application oWord;
Word._Document oDoc;
object oMissing = System.Reflection.Missing.Value;
object bAddress = "bAddress";
oWord = new Word.Application();
object oTemplate = _template;
oDoc = oWord.Documents.Add(ref oTemplate, ref oMissing,
ref oMissing, ref oMissing);
Word.Template objTmpl = (Word.Template)oDoc.get_AttachedTemplate();
Word.BuildingBlock objBB = objTmpl.BuildingBlockEntries.Item("PageBB");
Range where = oDoc.Range(oDoc.Content.End - 1, oDoc.Content.End - 1);
var orng = objBB.Insert(where, true);
orng.Bookmarks[bAddress].Range.Text = "Address";
I would like to do this in reverse, to open created file at a later date, and read through each bookmark to get the value.
The problem is when I open the resulting DocXCreatedFromTemplate.docx, the bookmarks have disappeared. Programmatically, I receive the bookmark not in collection error, but also by allowing word to open and checking manually the bookmarks are replaced with text but the bookmark reference has gone.
Is there any way to get round this?
I have worked this out, the following text replaces and deletes the bookmark
orng.Bookmarks[bAddress].Range.Text = "Address";
The solution was to re-add the bookmark afterwards using a method as follows
private void UpdateBookmarkWithoutDeleting(object bookmark, string text, _Document document)
{
var bookmarkRange = document.Bookmarks[bookmark].Range;
bookmarkRange.Text = text;
document.Bookmarks.Add(bookmark.ToString(), bookmarkRange);
}
I found the information at the following link (in VB):
https://wordmvp.com/FAQs/MacrosVBA/InsertingTextAtBookmark.htm

Printing into a label from Excel

I have an excel sheet with 47 columns and about 100 rows. I have a Windows form application with a text field, a button and a label.
Here's what I am trying to do:
When I paste a number into the text box and click the button, it searches the entire excel sheet and fetches the row and column of where that particular string is in the sheet (row, column). This is working fine. I am ok with the performance. Here's what I'd actually like to do -
After I get where the searched string is, I'd like to go to the 45th column, of that same row and get the string from that cell, and display it in the label.
Here's my code (Nothing I did is working!)
string File_name = "C:\\Users\\v-nikken\\Documents\\My Received Files\\Case Wellness.xlsx";
Microsoft.Office.Interop.Excel.Application oXL = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook oWB;
Microsoft.Office.Interop.Excel.Worksheet oSheet;
try
{
object missing = System.Reflection.Missing.Value;
oWB = oXL.Workbooks.Open(File_name, missing, missing, missing, missing,
missing, missing, missing, missing, missing, missing,
missing, missing, missing, missing);
oSheet = (Microsoft.Office.Interop.Excel.Worksheet)oWB.Worksheets[1];
Microsoft.Office.Interop.Excel.Range oRng = GetSpecifiedRange(textBox_SRNumber.Text, oSheet);
if (oRng != null)
{
//THIS IS THE LOGIC I HAVE TO TAKE VALUE FROM THE CELL TO THE LABEL
//AND OBV IT ISN'T WORKING
int IRPlace = Convert.ToInt32(oRng.Column) + 46; //This is obv wrong
label_IRMet.Text = Convert.ToString(oSheet.Cells[Convert.ToInt32(oRng.Row), IRPlace]); //This also
label_scope_sent.Text = IRPlace.ToString();
}
else
{
MessageBox.Show("Case number not found!", "Please try again");
}
oWB.Close(false, missing, missing);
oSheet = null;
oWB = null;
oXL.Quit();
}
catch (Exception ex)
{
}
Sorry about the formatting. The code section wasn't working for some reason.
Please help!!
Windows 10 - Excel 2016 - VS 2017 - .net 4.6.1
Microsoft.Office.Interop.Excel.Range valueForLabel=(Microsoft.Office.Interop.Excel.Range)yourSheet.Cells[oRng.Row,IRPlace];
string labelText=valueForLabel.Value.ToString();

Embbed outlook mails into word document

Is there a way to embbed outlook mailitems into word document programatically from a Outlook Mailitem List.??
I am trying to achieve something like this
Word.Application wdApp = new Word.Application();
Word.Document wdDoc = wdApp.Documents.Add(ref missing, ref missing, ref missing,
ref missing);
foreach(Outlook.MailItem olMail in mailAttachments)
{
//Paste/embbed this olMail into the word document
}
Ya Finally i found an effective solution
I used the InlineShapes.AddOLEObject method
My solution:
static void creatDocument(List<Outlook.MailItems> mailAttachments)
{
string userprofile = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
object missing = System.Reflection.Missing.Value
object start=0;
object end =0;
object classType ="{00020D0B-0000-0000-C000-000000000046}";
object fileName;
object linkToFile = false;
object displayAsIcon = true;
object iconFileName = Path.Combine(userprofile,"Pictures\MailIcon.ico");
object iconIndex =0;
object iconLabel;
object range;
Word.Application wdApp=new Word.Application();
Word.Document wdDoc = wdApp.Documents.Add(ref missing, ref missing, ref missing, ref missing);
Range rng = wdDoc.Range(ref start,ref missing);
foreach(outlook.MailItem olMail in mailAttachments)
{
olMail.SaveAs(Path.Combine(userprofile,"Documents\TemperoraySave") + CleanFileName(olMail.Subject) + ".msg" ,Outlook.OlSaveAsType.olMsg);
fileName = Path.Combine(userprofile,"Documents\TemperoraySave") + CleanFileName(olMail.Subject) + ".msg"
iconLabel = CleanFIleName(olMail.Subject) + ".msg";
rng = wdDoc.Content;
rng.Collapse(WdCollapseDirection.wdCollapseEnd);
range = rng;
wdDoc.InLineShapes.AddOLEObject(ref classType,ref fileName,ref linkToFile,ref displayAsIcon,ref iconFIleName,ref iconIndex,ref iconLabel,ref range);
var mailRanger = wdDoc.Paragraphs.Add();
mailRanger.Format.SpaceAfter =10f;
}
}
private static string CleanFileName(string fileName)
{
return Path.GetInvalidFileNameChars().Aggregate(fileName, (current, c) => current.Replace(c.ToString(), string.Empty));
}
Nope. The Word object model doesn't provide anything for that. Instead, you may consider using the CustomDocumentPropertiesenter link description here collection for storing your custom data. For example, you may save the message as an .msg file and save the path to the file or the ID of the record in the database to a custom document property. After, when you need to open a message you can get the ID or path for retrieving the email message.
You can't embed the source text of the emails, but you can copy the MailItem.HTMLBody or MailItem.Body (text) values and insert them into the Word document.

Tracking revisions in Excel in ASP.NET

I have managed to keep Microsoft Word's track revisions property on. It is working fine.
How do I do the same for MS Excel 2007 and above? Follwing is my code for word (which is working fine) and next is for Excel that I am trying to execute.
Word:
Word.Application app = new Word.Application();
Word.Document tempDoc = app.Documents.Open(path);
tempDoc.TrackRevisions = true;
tempDoc.Protect(typ, ref missing, ref password, ref missing, ref missing);
Excel:
Excel.Application ex_APP = new Excel.Application();
Workbook wrk = ex_APP.Workbooks.Open(path);
not able to go past this. When I try doing
wrk.
I don't get property as trackReviosons.
This is the way I am currently doing it it seems to work really well
using Excel = Microsoft.Office.Interop.Excel;
Then you get active workbook
//Gets Excel and gets Activeworkbook and worksheet
Excel.Application oXL;
Excel.Workbook oWB;
Excel.Worksheet oSheet;
oXL = (Excel.Application)Marshal.GetActiveObject("Excel.Application");
oXL.Visible = true;
oWB = (Excel.Workbook)oXL.ActiveWorkbook;
docProps = oWB.CustomDocumentProperties

How to open an Excel file in C#?

I am trying to convert some VBA code to C#. I am new to C#. Currently I am trying to open an Excel file from a folder and if it does not exist then create it. I am trying something like the following. How can I make it work?
Excel.Application objexcel;
Excel.Workbook wbexcel;
bool wbexists;
Excel.Worksheet objsht;
Excel.Range objrange;
objexcel = new Excel.Application();
if (Directory("C:\\csharp\\error report1.xls") = "")
{
wbexcel.NewSheet();
}
else
{
wbexcel.Open("C:\\csharp\\error report1.xls");
objsht = ("sheet1");
}
objsht.Activate();
You need to have installed Microsoft Visual Studio Tools for Office (VSTO).
VSTO can be selected in the Visual Studio installer under Workloads > Web & Cloud > Office/SharePoint Development.
After that create a generic .NET project and add a reference to Microsoft.Office.Interop.Excel via 'Add Reference... > Assemblies' dialog.
Application excel = new Application();
Workbook wb = excel.Workbooks.Open(path);
Missing.Value is a special reflection struct for unnecessary parameters replacement
In newer versions, the assembly reference required is called Microsoft Excel 16.0 Object Library. If you do not have the latest version installed you might have Microsoft Excel 15.0 Object Library, or an older version, but it is the same process to include.
FileInfo fi = new FileInfo("C:\\test\\report.xlsx");
if(fi.Exists)
{
System.Diagnostics.Process.Start(#"C:\test\report.xlsx");
}
else
{
//file doesn't exist
}
private void btnChoose2_Click(object sender, EventArgs e)
{
OpenFileDialog openfileDialog1 = new OpenFileDialog();
if (openfileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
this.btnChoose2.Text = openfileDialog1.FileName;
String filename = DialogResult.ToString();
var excelApp = new Excel.Application();
excelApp.Visible = true;
excelApp.Workbooks.Open(btnChoose2.Text);
}
}
Imports
using Excel= Microsoft.Office.Interop.Excel;
using Microsoft.VisualStudio.Tools.Applications.Runtime;
Here is the code to open an excel sheet using C#.
Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook wbv = excel.Workbooks.Open("C:\\YourExcelSheet.xlsx");
Microsoft.Office.Interop.Excel.Worksheet wx = excel.ActiveSheet as Microsoft.Office.Interop.Excel.Worksheet;
wbv.Close(true, Type.Missing, Type.Missing);
excel.Quit();
Here is a video mate on how to open an excel worksheet using C# https://www.youtube.com/watch?v=O5Dnv0tfGv4
For opening a file, try this:
objexcel.Workbooks.Open(#"C:\YourPath\YourExcelFile.xls",
missing, missing, missing, missing, missing, missing, missing,
missing, missing, missing, missing, missing,missing, missing);
You must supply those stupid looking 'missing' arguments. If you were writing the same code in VB.Net you wouldn't have needed them, but you can't avoid them in C#.
you should open like this
Excel.Application xlApp ;
Excel.Workbook xlWorkBook ;
Excel.Worksheet xlWorkSheet ;
object misValue = System.Reflection.Missing.Value;
xlApp = new Excel.ApplicationClass();
xlWorkBook = xlApp.Workbooks.Open("csharp.net-informations.xls", 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
source : http://csharp.net-informations.com/excel/csharp-open-excel.htm
ruden
It's easier to help you if you say what's wrong as well, or what fails when you run it.
But from a quick glance you've confused a few things.
The following doesn't work because of a couple of issues.
if (Directory("C:\\csharp\\error report1.xls") = "")
What you are trying to do is creating a new Directory object that should point to a file and then check if there was any errors.
What you are actually doing is trying to call a function named Directory() and then assign a string to the result. This won't work since 1/ you don't have a function named Directory(string str) and you cannot assign to the result from a function (you can only assign a value to a variable).
What you should do (for this line at least) is the following
FileInfo fi = new FileInfo("C:\\csharp\\error report1.xls");
if(!fi.Exists)
{
// Create the xl file here
}
else
{
// Open file here
}
As to why the Excel code doesn't work, you have to check the documentation for the Excel library which google should be able to provide for you.
Microsoft.Office.Interop.Excel.Application excapp;
excapp = new Microsoft.Office.Interop.Excel.Application();
object misval=System.Reflection.Missing.Value;
Workbook wrkbuk = new Workbook();
Worksheet wrksht = new Worksheet();
wrkbuk = excapp.Workbooks._Open(#"C:\Users\...\..._template_v1.0.xlsx", misval, misval,
misval, misval, misval, misval, misval, misval, misval, misval, misval, misval);
wrksht = (Microsoft.Office.Interop.Excel.Worksheet)wrkbuk.Worksheets.get_Item(2);
Is this a commercial application or some hobbyist / open source software?
I'm asking this because in my experience, all free .NET Excel handling alternatives have serious problems, for different reasons. For hobbyist things, I usually end up porting jExcelApi from Java to C# and using it.
But if this is a commercial application, you would be better off by purchasing a third party library, like Aspose.Cells. Believe me, it totally worths it as it saves a lot of time and time ain't free.
Code :
private void button1_Click(object sender, EventArgs e)
{
textBox1.Enabled=false;
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Excell File |*.xlsx;*,xlsx";
if (ofd.ShowDialog() == DialogResult.OK)
{
string extn = Path.GetExtension(ofd.FileName);
if (extn.Equals(".xls") || extn.Equals(".xlsx"))
{
filename = ofd.FileName;
if (filename != "")
{
try
{
string excelfilename = Path.GetFileName(filename);
}
catch (Exception ew)
{
MessageBox.Show("Errror:" + ew.ToString());
}
}
}
}
For editing Excel files from within a C# application, I recently started using NPOI.
I'm very satisfied with it.

Categories