OpenXML 2.0 Gets wrong cell value - c#

I'm having a bit of a problem reading a value from an Excel 2010 worksheet.
On a standard Excel 2010 worksheet I have a cell with the currency format with two decimal places and the value 1270,14 €.
When I read this value on OpenXML 2.0 (C# code) I get 1270.1400000000001 instead of the original 1270.14.
The same happens with other values on any cell with the same formating.
Get value from cell OpenXML code:
private string GetCellValue(string column, int row)
{
column = column.ToUpper();
var targetCell = cells.Where(p => p.CellReference == (column + row)).SingleOrDefault();
var value = String.Empty;
if (targetCell.DataType != null && targetCell.DataType.Value == CellValues.SharedString)
{
var index = int.Parse(targetCell.CellValue.Text);
value = cellValues[index].InnerText.Trim();
}
else
{
if (targetCell.CellValue != null)
{
value = targetCell.CellValue.Text.Trim();
}
else
{
value = null;
}
}
return value;
}
The specific value passes over the 'if' DataType is not null condition and retrieves the value with the line:
value = targetCell.CellValue.Text.Trim();
How can this be fixed ?
Why is this error even possible ?

As the number is stored as double in Excel, you can first parse the string as double, then convert back to string to get the value for display:
string s = Convert.ToDouble(value).ToString();
Let Microsoft handle its own problem.

Though it may not fit your application, the easiest fix would be simply rounding off the value you get back and assigning it or returning it where applicable. somevarhere=Math.Round(Convert.ToDouble(value), 2)

Related

Coudn't get value from textbox

I have a textbox called txtUprice which gets the value from a data-grid view, but when I tried get value of the txtUprice-textbox in a message box (with or without changing the text box value) I'm getting an error:
Input string was not in a correct format
I have tried changing the data type in sql where i get the value to the datagrid.
To get the value for textbox from datagrid i have used this:
txtUprice.Text = datagridview.SelectedRows[0].Cells[4].Value.ToString()
To take the textbox value to message-box i have used this:
int unitprice;
unitprice = int.Parse(txtUprice.Text);
MessageBox.Show(unitprice.ToString());
You are getting error beacuse of this line
unitprice = int.Parse(txtUprice.Text);
Reason is, you are trying to parse some string to integer which cannot. like 10%.
Instead of that use like this.
//int unitprice;
//unitprice = int.Parse(txtUprice.Text);
MessageBox.Show(txtUprice.Text);
Or still you want to convert that to int, use try parse
int num1;
bool res = int.TryParse(txtUprice.Text, out num1);
if (res == false)
{
MessageBox.Show("String is not a number");
}
else{
MessageBox.Show(num1.ToString());
}

Reading a Number from an Excel Sheet is changing the value

I have a C# program that reads in an excel workbook, and then builds an XML file that can be ran against an XSLT. The problem that has cropped up is that one of the fields is a number, and when reading it out of the excel sheet the value is being changed. Here is the example:
The excel spreadsheet is read in, and the data is loaded into a data table. One of the ways I do this is by taking the spreadsheet document I create, and pass the cell reference into this method here:
dataRow[columnIndex] = GetCellValue(spreadSheetDocument, cell);
private static string GetCellValue(SpreadsheetDocument document, Cell cell)
{
//This process uses the OpenXML SDK to get individual cells values to populate the DataTable
SharedStringTablePart stringTablePart = document.WorkbookPart.SharedStringTablePart;
string value = "";
//One of the things that needed to be accounted for was empty cells
try
{
value = cell.CellValue.InnerXml;
}
catch (Exception)
{
value = "";
}
//Setting cell data type right now just sets everything to strings
//Later, the better option will be to work on the Date Conversions and Data Types here
if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
{
return stringTablePart.SharedStringTable.ChildElements[Int32.Parse(value)].InnerText;
}
else
{
return value;
}
}
So as an example, if the cell that it is reading in is 115, then the output looks like this:
114.99999999999999
Then at other times if the value is 125 then the output looks like this:
125.00000000000001
the inconsistency in the output is a bit perplexing. Was hoping maybe I could get some insight into what is causing this, rather than just fixing it in the XSLT later on.
So I found a workaround, more than an actual solution. Apparently this is a bug in the OpenXML SDK. I found the initial documentation that pointed me in this direction here
What I found as a way to work around was this:
private static string GetCellValue(SpreadsheetDocument document, Cell cell)
{
//This process uses the OpenXML SDK to get individual cells values to populate the DataTable
SharedStringTablePart stringTablePart = document.WorkbookPart.SharedStringTablePart;
string value = "";
//One of the things that needed to be accounted for was empty cells
try
{
value = cell.CellValue.InnerXml;
}
catch (Exception)
{
value = "";
}
//Checking to see if this string contains a decimal with values on either side
if (Regex.IsMatch(value, regexpattern))
{
value = Math.Round(Double.Parse(value), 0, MidpointRounding.AwayFromZero).ToString();
}
//Setting cell data type right now just sets everything to strings
//Later, the better option will be to work on the Date Conversions and Data Types here
if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
{
return stringTablePart.SharedStringTable.ChildElements[Int32.Parse(value)].InnerText;
}
else
{
return value;
}
}
I'm using Regex to determine if this bug is being encountered and then compensating using some rounding. It is interesting to note that only appears to happen with integers.
Thanks!

Can't read Excel cell value in Visual C#

I read How to read single Excel cell value and tried it myself. But when I gets to
string s = (myExcelWorkSheet.Cells[3, "E"] as Excel.Range).Value2.ToString();
Everything was terminated and the form was shown.
//Everything worked fine here.
string s = (myExcelWorkSheet.Cells[3, "E"] as Excel.Range).Value2.ToString();
//Everything after this was all skipped!
Why is this, and how can I fix it?
The problem with reading excel cell is that if there is nothing in it, the cell object is Null. Thus, it does not have .Value2 neither .Value.
To find a way how to avoid the check for Null, you may use Convert.ToString() which evaluates the Null to an empty string and thus does not return an error:
for (int i = 1; i < 5; i++)
{
string a = Convert.ToString(wk.Cells[i, 1].Value2);
Console.WriteLine(a);
}
When the cell has a value, you need the ToString().
And when the cell doesn't has a value, then you don't need the ToString()!
Otherwise the whole program will skip out and everything after that was NEVER executed!!!
So I guess it's just a problem of if the system was trying to cast a null value into a string or not!!!

C# Use variable from loop in next loop run

I have a problem with my winforms application and I didn`t find a way to solve it: I am running a while loop which is fetching a value from a webserver.
Then this value should be substracted from the value which was fetched by the loop the run before.
while(true)
{
valuecurrent = webclient.DownloadString("http://ipadress/value");
double result = (valuebefore - valuecurrent);
}
Is there a way to save the value from the run before and use it in the next run of the loop?
Thanks in advance!
Tim
Just add a variable outside/before the loop and set it on each pass.
var valuebefore = 0;
while(true)
{
valuecurrent = webclient.DownloadString("http://ipadress/value");
double result = (valuebefore - valuecurrent);
valuebefore = valuecurrent;
}
// Assign a null value before
double? valuebefore = null;
while (true)
{
// Get the current value from the webserver
valuecurrent = webclient.DownloadString("http://ipadress/value");
// Use the current value if we don't have any previous values
// Subtract the current value from previous value if it exists
double result = valuebefore.HasValue == false
? valuecurrent
: valuebefore.Value - valuecurrent;
// Save the result to our value before to be used in next loop
valuebefore = result;
}
You can leverage nullable types and a simple if/then logic to save the first value then subtract subsequent values.

Input string was not in a correct format. Expected type in Decimal type

I am not inserting any value in VOUCHER_NO column and updating it.
But it is giving me error as
Input string was not in a correct format.Couldn't store <> in VOUCHER_NO Column. Expected type is Decimal.
Below is my code
drpayinfo[0]["VOUCHER_NO"] = e.Record["VOUCHER_NO"];
Update
I am using Oracle DB and its datatype is NUMBER (10)
Seems your e.Record["VOUCHER_NO"] have some unwanted content which is not convertible to decimal. Try this way checking before assignment or conversion
if(e.Record["VOUCHER_NO"] != "")
{
drpayinfo[0]["VOUCHER_NO"] = Convert.ToDecimal(e.Record["VOUCHER_NO"]);
}
But more safer way to detect and ignore bad content is
decimal result;
if (Decimal.TryParse(e.Record["VOUCHER_NO"], out result))
{
drpayinfo[0]["VOUCHER_NO"] = result;
}
else
{
// do stuff if failed to parese
}
Based on your comments on other answers, your value is an empty string. This cannot directly be converted to a decimal. You must decide some action to take instead.
They following code will try to convert it, and take an action if not. TryParse is your friend for conversions!
decimal num = 0;
if (!Decimal.TryParse(e.Record["VOUCHER_NO"], out num))
{
//Throw some error, maybe set num to some default and assign...
//The appropriate action in this situation depends on your needs.
}
else
{
//You can safely assign the value
drpayinfo[0]["VOUCHER_NO"] = num;
}

Categories