I have code that is taking information from the database to insert into a list. One piece of data that I'm taking will be used for price. (I set its type to decimal in SQL Server), for example: " 1,80".
But when I select it, my decimal variable returns the value 2 !
I want to know if there are a simple way to make decimal not automatically round numbers.
This is the code:
public decimal preco { get; set; }
while (dr.Read())
{
clsCaProd oProd = new clsCaProd();
oProd.cod = dr.GetInt32(0);
oProd.preco = dr.GetDecimal(1); // Here returns "2" instead of "1,80"
oProd.info = dr.GetString(2);
oProd.categ = dr.GetString(3);
oProd.nome = dr.GetString(4);
lProd.Add(oProd);
}
If you declare a column as decimal, the default "scale" is zero. You need to specify the precision and scale.
Try this example:
declare #d1 decimal = 1.80
declare #d2 decimal(19,4) = 1.80
select #d1, #d2;
Results:
2 1.8000
Related
so i have 2 labels. one of them is a fixed number and doesn't change but the other one changes every 5 seconds. Now i want to multiply them automatically and show them in another label as Results.
what should i do? what am i doing wrong?
i tried this code but it says "operator * cannot be applied to string and string".
label1.Text = BTC_A.Text * BTCPrice_Label.Text;
then i tried
double txt1 = Convert.ToDouble(BTC_A.Text);
double txt2 = Convert.ToDouble(BTCPrice_Label.Text);
double sum = txt1 * txt2;
label1.Text = sum.ToString();
but it says "Input string was not in a correct format"
Think it through step by step.
You have labels with a Text property. That property is of type string. C# is a strongly typed language: strings can not be multiplied like that. In the end, a label can be empty, or the user could input any random string. What would be the result of "foo" * "bar"?
Also, when you do have a double as a result of some multiplication, you want to show it to the user in another label.Text. Here you have the inverse issue: C#/.Net does not convert the variable of type double implicitly to a string.
So you will have to
check if the strings entered by the user is actually a valid double
if they are, convert those strings to double and multiply them
convert the result to a string, and assign it to the labels Text property
if the strings are not valid numbers, leave the label empty, or show some other message
The logic to achieve this would be something like this:
var validPrice = int.TryParse(BTCPrice_Label.Text, out double price);
var validAmount = int.TryParse(BTCA_Label.Text, out double amount);
if (validPrice && validAmount)
{
var result = price * amount;
label1.Text = result.ToString();
}
else
{
label1.Text = "something is wrong";
}
so the problem was a dollar sign ( $ ) that i put before the numbers.
i just deleted the sign and this is what the code looks like now:
double AA;
if (!double.TryParse(BTC_A.Text, out AA))
{
MessageBox.Show($"Unable to convert the BTC_A \"{BTC_A.Text}\" to a floating point number");
return;
}
double btcA;
if (!double.TryParse(BTCPrice_Label.Text, out btcA))
{
MessageBox.Show($"Unable to convert the price \"{BTCPrice_Label.Text}\" to a floating point number");
return;
}
label1.Text = (AA * btcA).ToString();
I've tried to compute a column in my datagrid, i will be showing these in my code as per below. I Keep getting these error.
I've go through these links
1. How To Convert The DataTable Column type?
2. Error while taking SUM() of column in datatable
3. Invalid usage of aggregate function Sum() and Type: String
//This is the column i add into my datagrid
MITTRA.Columns.Add("Min_Tol");
MITTRA.Columns.Add("Max_Tol");
MITTRA.Columns.Add("Min_Weight");
MITTRA.Columns.Add("Max_Weight");
// The following codes is working finely
// if you notice MTTRQT column, it's a data queried from database
for (int i = 0; i <= MITTRA.Rows.Count - 1; i++)
{
string item = MITTRA.Rows[i]["MTITNO"].ToString();
Tolerancechecking = database_select4.LoadUser_Tolerance(item);
MITTRA.Rows[i]["Min_Tol"] = Tolerancechecking.Rows[0]["Min_Tol"].ToString();
MITTRA.Rows[i]["Max_Tol"] = Tolerancechecking.Rows[0]["Max_Tol"].ToString();
MITTRA.Rows[i]["Min_Weight"] = Convert.ToDecimal(MITTRA.Rows[i]["MTTRQT"]) - ((Convert.ToDecimal(MITTRA.Rows[i]["MTTRQT"]) * Convert.ToDecimal(MITTRA.Rows[i]["Min_Tol"]) / 10));
MITTRA.Rows[i]["Max_Weight"] = Convert.ToDecimal(MITTRA.Rows[i]["MTTRQT"]) + ((Convert.ToDecimal(MITTRA.Rows[i]["MTTRQT"]) * Convert.ToDecimal(MITTRA.Rows[i]["Max_Tol"]) / 10));
dataGrid2.Columns.Clear();
dataGrid2.ItemsSource = null;
dataGrid2.ItemsSource = Tolerancechecking.DefaultView;
}
//Working Sum computation
Decimal Sum = Convert.ToDecimal(MITTRA.Compute("SUM(MTTRQT)", string.Empty));
MaxTol.Text = Sum.ToString(); /*** This is working as i got my value on the text box ****/
Errors when trying sum computation for different column
Initial try
1. Decimal Sum = Convert.ToDecimal(MITTRA.Compute("SUM(Min_Weight)", string.Empty));
Errors occurred
Invalid usage of aggregate function Sum() and Type: String.
Second Attempts
2. Decimal Sum = Convert.ToDecimal(MITTRA.Compute("SUM(Convert(Min_Weight,'System.Decimal'))", string.Empty));
3. Decimal Sum = Convert.ToDecimal(MITTRA.Compute("SUM(Convert(Min_Weight,'System.Decimal'))", ""));
Errors occurred
Syntax error in aggregate argument: Expecting a single column argument with possible 'Child' qualifier.
How am i going to get the compute sum function to work?
Thank you #NoChance for the solutions. Hope this post can help others too.
/***** This is the part where i declare my datacolumn data type ****/
DataColumn Min_Weight = new DataColumn("Min_Weight");
Min_Weight.DataType = System.Type.GetType("System.Decimal");
MITTRA.Columns.Add(Min_Weight);
/**** This Works finally *****/
Decimal Sum = Convert.ToDecimal(MITTRA.Compute("SUM(Min_Weight)", string.Empty));
MaxTol.Text = Sum.ToString();
I am doing below code in c#
obj.value = decimal_value / 100;
Where obj.value is a decimal variable in the model
decimal_value is a variable holding a decimal value
C# code
if (member["LOADINGS"] != "")
{
decimal loading_temp = Convert.ToDecimal(member["LOADINGS"]);
prem.loadings = loading_temp / 100m;
}
When debugged prem.loading gets correct value 0.0952 but when it get saved in sql server it shows 0.09000
loading variable in model
public decimal? loadings {get;set;}
eg: result
9.52/100 gives 0.0952 but when it stores in sql server in a column of datatype decimal(18,5) it gives the result 0.0900
Any idea for this ?
Edit
saving in database
premium prem = new premium();
if (member["LOADINGS"] != "")
{
decimal loading_temp = Convert.ToDecimal(member["LOADINGS"]);
prem.loadings = loading_temp / 100m;
}
db.premium.add(prem);
db.savechanges();
In SQL Server:
declare #v decimal(18,5)
select #v = 9.52/100
select #v
returns 0.09520
I am making a plugin that is supposed to take data from Quote Product entity.
By default, there is no discount in percent field, just discount amount. I added Discount% filed to the form (ad_discountpercent). Now I should calculate new price like this:
sum = (price - discount)*quantity*(100 - discount%)/100
I made a code for that. When i build this code there are no errors, but there are no changes in the CRM. I have also registered my plugin.
There are 3 fields manualdiscountamount , priceperunit , extendedamount that are Currency type fields. quantity is decimal and ad_discountpercent is integer. I have found a few methods for getting value from Currency, some are commented, some are not, because I don't know which one is proper.
One notice i checked fetch results, and they are as expected, so fetch is working fine. I compressed it in one line, because of the code length.
Here is the part of the code that should do the job. I have no information is there anything wrong with conversion, am I using proper way to set a new value?
I am new in this, so any comment would help me.
string fetch1 = #"<fetch count='50' ><entity name='quotedetail' ><attribute name='manualdiscountamount' /><attribute name='priceperunit' /><attribute name='ad_discountpercent' /><attribute name='quantity' /> <attribute name='extendedamount' /> <filter> <condition attribute='ad_discountpercent' operator='not-null'/> </filter > </ entity> </fetch>";
EntityCollection result = service.RetrieveMultiple(new FetchExpression(fetch1));
foreach (var c in result.Entities)
{
// int discountPer = (int)c.Attributes["ad_discountpercent"];
int discountPer = c.GetAttributeValue<int>("ad_discountpercent");
Money m = (Money)c.Attributes["priceperunit"];
decimal price = m.Value;
// decimal price = c.GetAttributeValue<decimal>("priceperunit");
Money m1 = (Money)c.Attributes["manualdiscountamount"];
decimal discount = m1.Value;
// decimal discount = c.GetAttributeValue<decimal>("manualdiscountamount");
//decimal discountPer = Convert.ToDecimal( c.Attributes["ad_discountpercent"]);
decimal quantity = Convert.ToDecimal(c.Attributes["quantity"]);
//decimal quantity = c.GetAttributeValue<decimal>("quantity");
decimal sum = (price - discount) * quantity * (100 - discountPer) / 100;
Money summTotal = new Money();
summTotal.Value = sum;
entity["extendedamount"] = summTotal;
service.Update(entity);
ExtendedAmount is an auto-calculated field based on priceperunit and quantity. So any updates to this field will be ignored by CRM.
Instead update the priceperunit and quantity to get the desired extendedamount.
entity["priceperunit"] = new Money((price - discount) * quantity * (100 - discountPer) / 100);
entity["quantity"] = 1;
service.Update(entity);
Is it possible that your query isn't returning any data, therefore your loop is never dropped into and your update never executes?
As previously suggested, take a look at how to debug a plugin via the plugin profiler.
Or, if you don't want to do that. Throw an temporary exception in your code after you do the RetrieveMultiple and in the message, add in the result.Entities.Count value to confirm how many records you're getting back.
How would you specify this:
Decimal(18,2)
In this:
SqlComm.Parameters.Add("#myValue", SqlDbType.Decimal, 0, "myValue");
Currently I have defined precision = 2 from the design side properties. I'm just curious as to how to accomplish this from the code. Thanks
There's not an overload of Add that lets you set the decimal precision inline, so you either need to create a SQlParameter object and add it to the collection:
SqlParameter param = new SqlParameter("#myValue", SqlDbType.Decimal);
param.SourceColumn = "myValue";
param.Precision = 18;
param.Scale = 2;
SqlComm.Parameters.Add(param);
or keep a reference to the parameter after adding it:
SqlParameter param = SqlComm.Parameters.Add("#myValue", SqlDbType.Decimal, 0, "myValue");
param.Precision = 18;
param.Scale = 2;
or using the parameter constructor:
SqlComm.Parameters.Add(new SqlParameter(
parameterName = "#myValue",
dbType = SqlDbType.Decimal,
precision = 18,
scale = 2,
sourceColumn = "myValue"));
var cmd = new SqlCommand()
SetDecimalParameter(cmd.Parameters.Add("#paramName", SqlDbType.Decimal), 18, 2).Value = 12.34;
SqlParameter SetDecimalParameter(SqlParameter parameter, byte precision, byte scale) {
parameter.Precision = precision;
parameter.Scale = scale;
return parameter;
}
My answer is not directly connected with the OP's question, but I've seen a lot of people asking "why set the precision since it is taken from the value".
It has to do with the way SQL Server works when comparing the decimal parameter with the text column. Imagine you have column named strNumberColumn witch is of nvarchar type. If you define a #var Decimal(1,0) = '1', comparison on the condition where strNumberColumn >= #var will work only as long, as the longest entry in that column is between "0" and "9". If any of the entries go beyond, for example "10" or "123" you will get an OverflowException while converting string to decimal. What is important, that conversion is made "behind the scenes".
Please, do not bring arguments like "if that column should contain numbers it should not be made nvarchar" - I totally agree, but that is beyond the scope of the problem (sometimes you work with a legacy system and you have no influence over the column datatype). The above example shows a real life scenario when defining precision is required in order for the query to run successfully despite having a smaller precision amount assigned to the variable (like #var Decimal(12,2) = '1.0').