Working with a multi-line Excel Cell into a C# Program - c#

My problem seems to be a simple case, but I can't seem to find any answers on it. I'm trying to write a program that will allow me to read Excel files using C# and the Interop method. These Excel files can contain information that has been entered with the use of "Alt-Enter" to create multiple lines within the cell, each line denoting a different value.
Currently my program spits out the contents of the whole cell, but how do I separate out the multiple values in the single cell, so that I am able to work on the individual values? Sorry if this has a simple answer, I'm a noob at this!

You can use String.Split function:
string[] values = ((string) multiLineCell.Value).Split('\n');

Related

Cannot export formula to .xlsx spreadsheet using c#

So I'm trying to use COUNTIF function to reference several different worksheets and count all occurrences of a keyword. I'm using the C# NuGet Package ClosedXML to export the data and the formula, but every time I do so, I get the following error in Numbers:
The formula couldn’t be imported and was replaced by the last calculated value. Original formula: =COUNTIF(2 WHATUP::Table 1::A2:A85,A6) + COUNTIF(3 Movies::Table 1::A2:A28,A6)
Excel gives me something similar. The only way to get it to accept it is to copy the formula, clear the cell, and paste the formula back. Here is the formula exactly as it is exported within my C# code (disregard the test worksheet names):
COUNTIF(2 WHATUP::Table 1::A2:A85,A4) + COUNTIF(3 Movies::Table 1::A2:A28,A4)
I've also tried the ! notation:
COUNTIF(2 WHATUP!A2:A85,A2) + COUNTIF(3 Movies!A2:A28,A2)
I've also tried using SUM to add them both together instead of +:
=SUM(COUNTIF(2WHATUP::Table 1::A2:A85,A2),COUNTIF(3Movies::Table 1::A2:A28,A2))
Yes, I've even tried adding more arguments within a single COUNTIF. This returns the same error as well.
=COUNTIF(1 Jello::Table 1::A2:A328, 3 Movies::Table 1::A2:A28, A2)
The only time I can get it to work is when I only use one COUNTIF to calculate a single range (without adding the results of another COUNTIF). But I need to add together the occurrences of a keyword throughout several worksheets, hence the use of several COUNTIFS/several arguments within a COUNTIF.
Please help! I have tried everything I can think of.
Thank you so much.
Looks like you have some space characters in the worksheet names, which then require beeing enclosed by single quotes.
Adopting your second example, following should work just fine:
=COUNTIF('2 WHATUP'!A2:A85,A2) + COUNTIF('3 Movies'!A2:A28,A2)

Word merge field in header loses value in print preview

I have an ASP WebForms app where I use a word template that contains merge fields, to replace them with data extracted from the database. The app works great, the word document is exported, but when trying to print the document, one of the merge fields, which exists in the header, loses it's value and restores to the initial merge field name. Is this something that has to be fixed from the application's code or is this a word settings issue.
Any help is greatly appreciated.
Thank you!
I have managed to solve this problem using OpenXML Productivity Tool. It turns out that you can't add a merge field in the header, so what I did was to put it inside of a textbox. I forgot to mention that part in the initial description. Thus, the text element was buried deep in open xml. When I managed to find it and log what was inside, I found out that I inserted the MERGEFIELD <> MERGEFORMAT. Every time I tried to insert the value that I wanted in this <>, it got reset when I hit print preview. So what I did, based on a suggestion from someone who had a similar problem, was to delete this textbox and create a clean one where I only entered "Test". It needs to have a string inside so that open xml created the element Text (instrTxt).
In C# I did this:
foreach (var hPart in firstDoc.MainDocumentPart.HeaderParts)
{
foreach (var txt in hPart.Header.Descendants<Text>())
{
if(txt.Text == "Test")
{
txt.Text = "My custom text";
}
}
}
So for each header part (because I can't tell for sure in which one it is..it could even be in multiple ones), get all descendants of type text.
I got a few more than I wanted. I also got a few that contained the page number (since I have it in the header as well). So I added an if to check if it's the text element that I wanted. Once I found it, I added the text I wanted.
So long story short, instead of using a merge field in the header, I just used a text. Perhaps it's not the most efficient way of doing this. Maybe the question still remains, (if I could have inserted a merge field in the header and actually made it work without having word reset the value upon print preview? idk), but this worked for me.

Use c# Microsoft.Office.Interop.Word.Revision to list changes between two versions of document

I am creating a C# Windows application that will compare two versions of a Word document and save the differences to a file,
So far so good - using the Microsoft.Office.Interop.Word.Revision interface I am able to get the type of change, line and page number of the change, and the text that changed
Problem with this is the changed text returns all of the text (original text and current text) as a single string - I want to be able to split this so I can see the differences more clearly
EG:
If a line is changed from 'hello' to 'Hi how are you', the text I get output from that revision is 'hello hi how are you'
I would like to be able to output this something like "'hello' has been changed to 'Hi how are you'"
is there any part of Microsoft.Office.Interop.Word.Revision interface that can do this?

Fillable doc files

I have a samples of some documents in .doc format. So I need to create some "fillable# areas instead of certain values in samples. Then I need to automatically fill this documents using C#. So what do you think about it? Is that possible? Thanks in advance, guys! P.S.: if you need some information from me please feel free to ask me about additions to my question.
Besides simply injecting/replacing text into the document itself you could also utilize docvariables. You can define/create them in your document and then you can codewise set the values.
Using docvariables you seperate the design of the worddoc (where is the text shown) from setting the values which might be usefull for your case.
You can certainly manipulate them using C# but a bit more info using a vba sample can found at What is a DOCVARIABLE in word
One little warning when using c# to edit them. If you set the value of a docvariable to "" (empty string) it results in the docvariable being deleted from the document. If you want to keep the docvariable around set it's value to a " " (space)
Yes this is possible, you can create in your Document a placeholder areas which you search and change when you access the file. Check these results on how to modify the word document using C#

How to show long numbers in Excel?

I have to build a C# program that makes CSV files and puts long numbers (as string in my program). The problem is, when I open this CSV file in Excel the numbers appear like this:
1234E+ or 1234560000000 (the end of the number is 0)
How I retain the formatting of the numbers? If I open the file as a text file, the numbers are formatted correctly.
Thanks in advance.
As others have mentioned, you can force the data to be a string. The best way for that was ="1234567890123". The = makes the cell a formula, and the quotation marks make the enclosed value an Excel string literal. This will display all the digits, even beyond Excel's numeric precision limit, but the cell (generally) won't be able to be used directly in numeric calculations.
If you need the data to remain numeric, the best way is probably to create a native Excel file (.xls or .xlsx). Various approaches for that can be found in the solutions to this related Stack Overflow question.
If you don't mind having thousands separators, there is one other trick you can use, which is to make your C# program insert the thousands separators and surround the value in quotes: "1,234,567,890,123". Do not include a leading = (as that will force it to be a string). Note that in this case, the quotation marks are for protecting the commas in the CSV, not for specifying an Excel string literal.
Format those long numbers as strings by putting a ' (apostrophe) in front or making a formula out of it: ="1234567890123"
You can't. Excel stores numbers with fifteen digits of precision. If you don't mind not having the ability to perform calculations on the numbers from within Excel, you can store them as Text, and all of the digits will display.
When I generate data to imported into Excel, I do not generate a CSV file if I want control over how the data are displayed. Instead, I write out an Excel file where the properties of the cells are set appropriately. I do not know if there is a library out there that would do that for you in C# without requiring Excel to be installed on the machine generating the files, but it is something to look into.
My two cents:
I think it's important to realize there is a difference between "Data" and "Formatting". In this example you are kind of trying to store both in a data-only file. This will, as you can tell from other answers, change the nature of the data. (In other words cause it to be converted to a string. A CSV file is a data only file. You can do some tricks here and there to merge formatting in with data, but to my way of thinking this essentially corrupts the data by merging it with non-data values: ie: "Formatting".
If you really need to be able to store formatting information I suggest that, if you have time to develop it out, you switch to a file type capable of storing formatting info separately from the data. It sounds like this problem would be a good candidate for a XML Spreadsheet solution. In this way you can not only specify your data, but also it's type and any formatting you choose to use.

Categories