c# Excel losing formulae after save - c#

Excel formula get lost after saving, were replaced by last calculation result.
Question: Is there a special save option in order to keep formulas ?
rangeTarget = workSheetTeam.get_Range(workSheetTeam.Cells[40, BG], workSheetTeam.Cells[40, BG]);
rangeTarget.Formula = "=MAX(BF8:BF25)";

Related

Microsoft Excel on save changes decimal point to 8

when i open on save excel the value displayed in excel is 596207726.09 but actual code behind value is 596207726.09000003.
why this change happaned?
But 596207726.09 in excel changed to 596207726.09000003 in code.
How 000003 getting added in code and how to solve the issue in c# code so it can take exact decimal point as given in Excel
For Example
596207726.09 - 596207726.09
596207726.092 - 596207726.092

how to convert exponential string to normal string in c#

I am reading a column number from csv where the number is 123456791234567 however due to format it gets converted to
number="1.23457E+14" in the csv file.
is there any way where we can change it to original string using c# ?
I am trying with below code :
decimal number = Decimal.Parse(number,System.Globalization.NumberStyles.Any);
but the number i am getting is 123457000000000M and the actual number is 123456791234567
any idea on this?
If I understand correctly, excel is converting 123456791234567 to 1.23457E+14. In that case, you just need to format the excel cell (or potentially the column) containing the value to string, before you set the value.
If the C# program opens the csv to find the value to be 1.23457E+14, then there is no way for you to convert it back to 123456791234567, since the precision is already lost - unless of course the same value exists (or can be recreated) in other cells (columns)

Format Code for European currency number format in Open XML without symbol

My application is developed in C# MVC and I am using Open XML for
Exporting Grid's data in Excel Sheet. Grid has various columns which
holds Amount fields. I have two buttons on page, one is "NA" for north
american format and another is "EU" for European format. Both button
exports excel sheet.
When "NA" is pressed exported excel Amount column values are converted
as following and working good,
1000000 ----------> 1,000,000 (Format Code used : #,##0)
But when "EU" is pressed exported excel amount values are not
converted as per expectation and is not working.
1000000 ----------> 1000000.0 (Format Code used : #.##0)
In Open XML, I configured stylesheet.xml file as
<x:numFmt numFmtId="169" formatCode="[>=1000]#,##0" /> // This works
<x:numFmt numFmtId="170" formatCode="[>=1000]#.##0" /> // This doesn't work
Do anyone has any suggestions here to solve this. I even try to change
the Cell Formatting in Excel Sheet for European Currency through
Custom Format option but that also doesn't work.
My expected result is following which I couldn't achieved.
1000000 -----------> 1.000.000
There is no way to change the decimal/thousands separators per workbook or per worksheet or per cell range.
You have to use the [>=1000]#,##0 format.
How it is shown depends on system's locale settings or on the Excel's settings for separator (File/Excel Options/Advanced).
If the exported data is the same both for NA and EU, you can leave one button for export. The users usually have the separators set up to ones they are used to.
https://social.technet.microsoft.com/Forums/office/en-US/eaa4c7f6-197a-4b33-bc5f-20896e5a7e3a/workbook-or-worksheet-specific-decimal-separator?forum=excel

Excel Dna - Refresh all Data Source and Formula Calculation

I have couple of formulas and data coming from database. I want to refresh all the formulas programmatically through ExcelDna. All these formulas are ExcelFunctions and I have put ExcelCommand name = "Refresh" on which i want to issue recalculate to excel sheet..
I use following but it refresh only native excel functions e.g. NOW(), SUM() etc. it does not invoke refresh on ExcelDna Functions ?
[ExcelCommand(MenuName="Refresh", MenuText="Refresh" )]
public static void GetPositionCommand()
{
XlCall.Excel(XlCall.xlcCalculateNow);
}
Thanks in advance...
xlcCalculateNow will only calculate formulae that Excel knows have to be recalculated. You can mark an Excel function as 'Volatile' for it to behave like Excel's NOW() function, which is recalculated every time. With Excel-DNA you can do this:
[ExcelFunction(IsVolatile=true)]
public static string MyVolatileNow()
{
return DateTime.Now.ToString("HH:mm:ss.fff");
}
and compare with the default non-volatile case:
[ExcelFunction]
public static string MyNow()
{
return DateTime.Now.ToString("HH:mm:ss.fff");
}
Another way to push data to Excel is to create an RTD server or use the new Reactive Extensions for Excel (RxExcel) support in the latest Excel-DNA check-ins. Some info here - http://exceldna.codeplex.com/wikipage?title=Reactive%20Extensions%20for%20Excel.
I have to hit Ctrl + Alt + F9 (at least in Excel 2013) to refresh the cells!
This works (at least in Excel 2013):
Excel.Application excelApp = ExcelDnaUtil.Application as Excel.Application;
excelApp.CalculateFull();
or
Excel.Application excelApp = ExcelDnaUtil.Application as Excel.Application;
excelApp.CalculateFullRebuild();
The first one recalculates all Workbooks (similar like you press Ctrl + Alt + F9), the second one is similar to reentering all formulas.
Try setting IsVolatile=false in the attribute for the ExcelDNA function:
[ExcelFunction(Description = "Subscribe to real time data.", IsVolatile = false, Category = UDF_CATEGORY)]
public static object XSub(
string param1)
{
// Implementation here.
}
This simple change dramatically drops CPU usage. In one big spreadsheet I was working with, CPU usage dropped from 100% (i.e. continuously recalculating, and never catching up) down to 20%.
With IsVolatile=true, Excel will recalculate the output value of the function regularly, even if the inputs did not change.
With IsVolatile=false, Excel will only recalculate the output value of the function if the inputs change.
With IsVolatile=false, everything is an order of magnitude more efficient, as Excel can skip recalculating 90% of the spreadsheet most of the time.
Having said this, some functions might need IsVolatile=true, for example, a function that returned the current time.

Paste from Excel into C# app, retaining full precision

I have data in an Excel spreadsheet with values like this:
0.69491375
0.31220394
The cells are formatted as Percentage, and set to display two decimal places. So they appear in Excel as:
69.49%
31.22%
I have a C# program that parses this data off the Clipboard.
var dataObj = Clipboard.GetDataObject();
var format = DataFormats.CommaSeparatedValue;
if (dataObj != null && dataObj.GetDataPresent(format))
{
var csvData = dataObj.GetData(format);
// do something
}
The problem is that csvData contains the display values from Excel, i.e. '69.49%' and '31.22%'. It does not contain the full precision of the extra decimal places.
I have tried using the various different DataFormats values, but the data only ever contains the display value from Excel, e.g.:
DataFormats.Dif
DataFormats.Rtf
DataFormats.UnicodeText
etc.
As a test, I installed LibreOffice Calc and copy/pasted the same cells from Excel into Calc. Calc retains the full precision of the raw data.
So clearly Excel puts this data somewhere that other programs can access. How can I access it from my C# application?
Edit - Next steps.
I've downloaded the LibreOffice Calc source code and will have a poke around to see if I can find out how they get the full context of the copied data from Excel.
I also did a GetFormats() call on the data object returned from the clipboard and got a list of 24 different data formats, some of which are not in the DataFormats enum. These include formats like Biff12, Biff8, Biff5, Format129 among other formats that are unfamiliar to me, so I'll investigate these and respond if I make any discoveries...
Also not a complete answer either, but some further insights into the problem:
When you copy a single Excel cell then what will end up in the clipboard is a complete Excel workbook which contains a single spreadsheet which in turn contains a single cell:
var dataObject = Clipboard.GetDataObject();
var mstream = (MemoryStream)dataObject.GetData("XML Spreadsheet");
// Note: For some reason we need to ignore the last byte otherwise
// an exception will occur...
mstream.SetLength(mstream.Length - 1);
var xml = XElement.Load(mstream);
Now, when you dump the content of the XElement to the console you can see that you indeed get a complete Excel Workbook. Also the "XML Spreadsheet" format contains the internal representation of the numbers stored in the cell. So I guess you could use Linq-To-Xml or similar to fetch the data you need:
XNamespace ssNs = "urn:schemas-microsoft-com:office:spreadsheet";
var numbers = xml.Descendants(ssNs + "Data").
Where(e => (string)e.Attribute(ssNs + "Type") == "Number").
Select(e => (double)e);
I've also tried to read the Biff formats using the Excel Data Reader however the resulting DataSets always came out empty...
The BIFF formats are an open specification by Microsoft. (Note, that I say specification not standard). Give a read to this to get an idea of what is going on.
Then those BIFF you see correspond to the some Excel formats. BIFF5 is XLS from Excel 5.0 and 95, BIFF8 is XLS from Excel 97 to 2003, BIFF12 is XLSB from Excel 2003, note that Excel 2007 can also produce them (I guess Excel 2010 too). There is some documentation here and also here (From OpenOffice) that may help you make sense of the binary there...
Anyways, there is some work has been done in past to parse this documents in C++, Java, VB and for your taste in C#. For example this BIFF12 Reader, the project NExcel, and ExcelLibrary to cite a few.
In particular NExcel will let you pass an stream which you can create from the clipboard data and then query NExcel to get the data. If you are going to take the source code then I think ExcelLibrary is much more readable.
You can get the stream like this:
var dataobject = System.Windows.Forms.Clipboard.GetDataObject();
var stream = (System.IO.Stream)dataobject.GetData(format);
And read form the stream with NExcel would be something like this:
var wb = getWorkbook(stream);
var sheet = wb.Sheets[0];
var somedata = sheet.getCell(0, 0).Contents;
I guess the actual Office libraries from Microsoft would work too.
I know this is not the whole tale, please share how is it going. Will try it if I get a chance.

Categories