How to convert string system collection to int? - c#

I have a windows form chart that retrieve the x value in mysql database and plot it on a bar graph. This is the the first time I'm doing this so I don't really have an idea why I am getting this error.
public void loadChart()
{
string conn = "server=localhost;user=root;password='';database=cashieringdb;";
string cmdstring = "SELECT sum FROM salessum";
MySqlDataAdapter adapter = new MySqlDataAdapter(cmdstring, conn);
DataTable dt = new DataTable();
adapter.Fill(dt);
chart1.DataSource = dt;
this.chart1.Palette = ChartColorPalette.SeaGreen;
this.chart1.Titles.Add("Daily Record");
int[] pointsArray = a.mysqlSelect("select sum from salessum"); // error in this line
string[] seriesArray = { "Mon", "Tue", "Wed", "Th", "Fri" };
for (int i = 0; i < seriesArray.Length; i++)
{
Series series =this.chart1.Series.Add(seriesArray[i]);
series.Points.Add(pointsArray[i]);
}
Here's the error shows: No matter how much time searching for solution on the internet, but still I ca'nt get this working. Or is there any easy way to retrieve data from database and plot it on the windows form chart?
Error 2 Cannot implicitly convert type 'System.Collections.Generic.List<string>[]' to 'int[]'
EDIT
I change my code to this:
List<string>[] pointsArray = a.mysqlSelect("select sum from salessum"); //no error
Error in this line:
series.Points.Add(pointsArray[i]);

This error occurs because you are converting a List to int[]. You can not implicitly do this, you have to do this explicitly. you can do this easily using Linq.
I assume that a.mysqlSelect("select sum from salessum"); is a method call. and out put a list of strings(each string representing a number)
Something Like this:
int[] pointsArray = a.mysqlSelect("select sum from salessum").Select(i => int.Parse(i)).ToArray();
This link will be helpful to you as well.
Edited:
Take a look at the LINK I have added earlier and get an idea on what you are going to accomplish. :)
in this code,
series.Points.Add(pointsArray[i]);
Points.Add method do not expect a string it expects a int. What you have tried to do earlier is correct. So point Array has to be a int[].
I mean this code:
int[] pointsArray = a.mysqlSelect("select sum from salessum");
I think I have found the exact same thing that you want to accomplish. Please take a look at this LINK. This will be helpful to you.

Related

Error while performing compute SUM() in a column

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();

Initializing size of 2D array in runtime using C#

I need to create a 2D array where size of column is fixed as 6 but size of row may vary . How to give dynamic row size in 2D array ?
Below is the code I tried but no luck.
int n;
string num = console.ReadLine();
Int32.TryParse(num,out n);
int[,] ar = new int[n,6] ;
There's nothing wrong with the way you're constructing the mulitidimentional array. The following code is valid so I suspect your error is somewhere else:
int n = 9;
int[,] ar = new int[n,6];
I'm guessing your input is not coming through correctly so add some error checks to figure out what went wrong. First, Console.ReadLine() has to be capitalized or it wont compile. Next, make sure TryParse is actually functioning properly (it returns a bool indicating success or failure:
int n;
string num = Console.ReadLine();
if (num == null) {
// ERROR, No lines available to read.
}
if (!Int32.TryParse(num,out n)) {
// ERROR, Could not parse num.
}
int[,] ar = new int[n,6];
If issues persist, people generally appreciate more descriptive explanations than "I tried but no luck." Make sure to inform people viewing your question that it was a compilation error or a runtime error and be as specific as you can.
I would use a Dictionary as so.
Dictionary<int,List<int>> numbers = new Dictionary<int,List<int>>();
And you could add an item like this:
numbers.Add(1,new List<int>(){1,2,3,4,5,6});
And to add numbers to a particular row.
numbers[1].Add(7);
And to access a number in a specific row and column.
numbers[1][2] = 34;

Exception from HRESULT: 0x800A03EC - Writing array to range in Excel Add-In

I have the following code in an Excel Add-In in C#:
long lngArrayLength = 14;
long lngArrayLength2 = array2.Length;
Excel.Range rngValues1 = (Excel.Range)wsNew.Cells[2, 1];
Excel.Range rngValues2 = (Excel.Range)wsNew.Cells[lngArrayLength2 + 1, lngArrayLength];
Excel.Range rngValues = wsNew.get_Range(rngValues1, rngValues2);
rngValues.Value = array2;
For reference, array2 has ten elements, each of which has 14 sub-elements. Example:
array2 = { (0, "a0", "b0", "c0"... "n0"), ... {9, "a9", "b9", "c9"... "n9) }
rngValues above is sized as {[1..10,1..14]}
Every time I try to run, I get the following error:
Exception from HRESULT: 0x800A03EC
I have ruled out:
1) File format, saving Book1 as .xlsx does not help
2) Reaching the column or row limit, does the same thing with thousands of elements or 10 of them
3) [0] vs [1] - indexed arrays and/or ranges, doesn't seem to matter/help
I am still having trouble debugging this... Is it possible this has something to do with the dimensions of the array vs the range? How would I determine if that's the case or not?
UPDATE 1:
I created a loop that populates an array with data:
for (i = 1; i <= lngRows; i++)
{
for (j = 1; j <= lngCols; j++)
{
strTest[i-1, j-1] = "test (" + i.ToString() + "," + j.ToString() + ")";
}
}
...and this works fine.
It now occurs to me that may of the elements in the array contain NULL values.
I'm thinking this may be the problem... Is it?
UPDATE 2:
Okay, so I now wrote a small routine to convert any NULLs to 0 (b/c the data type is decimal? (nullable decimal) and I guess I really need decimal instead:
public decimal replaceNullDec(decimal? decInput)
{
if (decInput != null)
{
decimal rtn = (decimal)decInput;
return rtn;
}
else
{
decimal rtn = 0;
return rtn;
}
}
So, now I have confirmed that all the NULLs are being replaced, but I'M STILL GETTING THE ERROR when writing the array to a range...
UPDATE 3:
Okay, so then I thought that maybe it's a data type issue, so I rewrote the code to convert all the elements in the array to strings instead before writing to the sheet. I now get data, but instead of the actual values, I get text telling me the original TYPE (which in this case is a custom class called Response).
The interesting thing I noticed is that I'm getting 10 COLUMNS of text, and 4 COLUMNS of #N/A.
This makes me think that maybe I need to transpose the array?
Driving me crazy, but still trying.
Any help would be GREAT!
UPDATE 4:
Okay, I believe I'm getting closer. In digging into how to transpose a 2d array in C#, I was getting some errors that lead me to believe I DON'T actually have a 2d array, but instead an "array of arrays" (which is what I thought a 2d array was, honestly) and it's probably the conversion of my List to Array using the ToArray() method that's an issue.
Here's that code:
object[] array2 = listAllData.ToArray();
So the next question becomes "how to convert a list to a 2d array?"
ANSWER:
The issue came down to the fact that I was NOT writing a 2D array to the range, but instead I was building an array of Response objects and trying to write that to a range.
More details on the solution are found in this related post:
How to Convert 2D List to 2D Array in C#

Convert object to double when using GetValue method

I want to perform a windows form which act as a unit conversion, like conversion from cm to m, etc.
Basically, my main codes are like this:
first binding data to drop down list
List<String> myList = new List<String>();
myList.Add("Inch");
DropDownList1.DataSource = myList;
DropDownList1.DataBind();
Int32 index1 = DropDownList1.SelectedIndex;
Int32 index2 = DropDownList2.SelectedIndex;
Double [,] key = new Double[7,7];
key.SetValue(1, 0, 0);
key.SetValue(1,1,2);
........
Double input_Number = Convert.ToDouble(input.Text);
Double ratio = Convert.ToDouble(key.GetValue(index1, index2));
Double ratio = key.GetValue(index1, index2);
Double result = input_Number*ratio ; //doesn't appear correct result
Comment.Text = Convert.ToString(result);
It runs ok, but it doesn't perform the function correctly. when i type sth in the inputbox and select cm to m, it doesn't work,always returns the same number. And when i am debugging, i try to see the ratio value, it still doesn't work.
is it a problem of my conversion from object to double? Because the getvalue method returns an object.
Firstly, you've got
Double ratio = Convert.ToDouble(key.GetValue(index1, index2));
Double ratio = key.GetValue(index1, index2);
not sure how this going to work. It will not run.
Secondly, i don't think you need do: Double ratio = Convert.ToDouble(key.GetValue(index1, index2));
it should come out with double
Finally, value assignment to your array looks like this:
key.SetValue(1, 0, 0);
key.SetValue(1,1,2);
which is assign value "1" to this 2-D array, so you will get everything times "1", is that what you want to do?
I have found out what's wrong with my code. It's because I wrote in my Dropdown list data bind in page_load. Everytime when I refresh my website, it automatically reset to default, which is the dropdown list item index=0; So it won't appear correctly

Passing a .NET Datatable to MATLAB

I'm building an interface layer for a Matlab component which is used to analyse data maintained by a separate .NET application which I am also building. I'm trying to serialise a .NET datatable as a numeric array to be passed to the MATLAB component (as part of a more generalised serialisation routine).
So far, I've been reasonably successful with passing tables of numeric data but I've hit a snag when trying to add a column of datatype DateTime. What I've been doing up to now is stuffing the values from the DataTable into a double array, because MATLAB only really cares about doubles, and then doing a straight cast to a MWNumericArray, which is essentially a matrix.
Here's the current code;
else if (sourceType == typeof(DataTable))
{
DataTable dtSource = source as DataTable;
var rowIdentifiers = new string[dtSource.Rows.Count];
// I know this looks silly but we need the index of each item
// in the string array as the actual value in the array as well
for (int i = 0; i < dtSource.Rows.Count; i++)
{
rowIdentifiers[i] = i.ToString();
}
// convenience vars
int rowCount = dtSource.Rows.Count;
int colCount = dtSource.Columns.Count;
double[,] values = new double[rowCount, colCount];
// For each row
for (int rownum = 0; rownum < rowCount; rownum++)
{
// for each column
for (int colnum = 0; colnum < colCount; colnum++)
{
// ASSUMPTION. value is a double
values[rownum, colnum] = Conversion.ConvertToDouble(dtSource.Rows[rownum][colnum]);
}
}
return (MWNumericArray)values;
}
Conversion.ConvertToDouble is my own routine which caters for NULLS, DBNull and returns double.NaN, again because Matlab treats all NULLS as NaNs.
So here's the thing; Does anyone know of a MATLAB datatype that would allow me to pass in a contiguous array with multiple datatypes? The only workaround I can conceive of involves using a MWStructArray of MWStructArrays, but that seems hacky and I'm not sure how well it would work in the MATLAB code, so I'd like to try to find a more elegant solution if I can. I've had a look at using an MWCellArray, but it gives me a compile error when I try to instantiate it.
I'd like to be able to do something like;
object[,] values = new object[rowCount, colCount];
// fill loosely-typed object array
return (MWCellArray)values;
But as I said, I get a compile error with this, also with passing an object array to the constructor.
Apologies if I have missed anything silly. I've done some Googling, but information on Matlab to .NET interfaces seems a little light, so that is why I posted it here.
Thanks in advance.
[EDIT]
Thanks to everyone for the suggestions.
Turns out that the quickest and most efficient way for our specific implementation was to convert the Datetime to an int in the SQL code.
However, of the other approaches, I would recommend using the MWCharArray approach. It uses the least fuss, and it turns out I was just doing it wrong - you can't treat it like another MWArray type, as it is of course designed to deal with multiple datatypes you need to iterate over it, sticking in MWNumerics or whatever takes your fancy as you go. One thing to be aware of is that MWArrays are 1-based, not 0-based. That one keeps catching me out.
I'll go into a more detailed discussion later today when I have the time, but right now I don't. Thanks everyone once more for your help.
As #Matt suggested in the comments, if you want to store different datatypes (numeric, strings, structs, etc...), you should use the equivalent of cell-arrays exposed by this managed API, namely the MWCellArray class.
To illustrate, I implemented a simple .NET assembly. It exposes a MATLAB function that receives a cell-array (records from a database table), and simply prints them. This function would be called from our C# application, which generates a sample DataTable, and convert it into a MWCellArray (fill table entries cell-by-cell).
The trick is to map the objects contained in the DataTable to the supported types by the MWArray-derived classes. Here are the ones I used (check the documentation for a complete list):
.NET native type MWArray classes
------------------------------------------
double,float,int,.. MWNumericArray
string MWCharArray
DateTime MWNumericArray (using Ticks property)
A note about the date/time data: in .NET, the System.DateTime expresses date and time as:
the number of 100-nanosecond intervals that have elapsed since January
1, 0001 at 00:00:00.000
while in MATLAB, this is what the DATENUM function has to say:
A serial date number represents the whole and fractional number of
days from a specific date and time, where datenum('Jan-1-0000
00:00:00') returns the number 1
For this reason, I wrote two helper functions in the C# application to convert the DateTime "ticks" to match the MATLAB definition of serial date numbers.
First, consider this simple MATLAB function. It expects to receive a numRos-by-numCols cellarray containing the table data. In my example, the columns are: Name (string), Price (double), Date (DateTime)
function [] = my_cell_function(C)
names = C(:,1);
price = cell2mat(C(:,2));
dt = datevec( cell2mat(C(:,3)) );
disp(names)
disp(price)
disp(dt)
end
Using deploytool from MATLAB Builder NE, we build the above as a .NET assembly. Next, we create a C# console application, then add a reference to the MWArray.dll assembly, in addition to the above generated one. This is the program I am using:
using System;
using System.Data;
using MathWorks.MATLAB.NET.Utility; // MWArray.dll
using MathWorks.MATLAB.NET.Arrays; // MWArray.dll
using CellExample; // CellExample.dll assembly created
namespace CellExampleTest
{
class Program
{
static void Main(string[] args)
{
// get data table
DataTable table = getData();
// create the MWCellArray
int numRows = table.Rows.Count;
int numCols = table.Columns.Count;
MWCellArray cell = new MWCellArray(numRows, numCols); // one-based indices
// fill it cell-by-cell
for (int r = 0; r < numRows; r++)
{
for (int c = 0; c < numCols; c++)
{
// fill based on type
Type t = table.Columns[c].DataType;
if (t == typeof(DateTime))
{
//cell[r+1,c+1] = new MWNumericArray( convertToMATLABDateNum((DateTime)table.Rows[r][c]) );
cell[r + 1, c + 1] = convertToMATLABDateNum((DateTime)table.Rows[r][c]);
}
else if (t == typeof(string))
{
//cell[r+1,c+1] = new MWCharArray( (string)table.Rows[r][c] );
cell[r + 1, c + 1] = (string)table.Rows[r][c];
}
else
{
//cell[r+1,c+1] = new MWNumericArray( (double)table.Rows[r][c] );
cell[r + 1, c + 1] = (double)table.Rows[r][c];
}
}
}
// call MATLAB function
CellClass obj = new CellClass();
obj.my_cell_function(cell);
// Wait for user to exit application
Console.ReadKey();
}
// DateTime <-> datenum helper functions
static double convertToMATLABDateNum(DateTime dt)
{
return (double)dt.AddYears(1).AddDays(1).Ticks / (10000000L * 3600L * 24L);
}
static DateTime convertFromMATLABDateNum(double datenum)
{
DateTime dt = new DateTime((long)(datenum * (10000000L * 3600L * 24L)));
return dt.AddYears(-1).AddDays(-1);
}
// return DataTable data
static DataTable getData()
{
DataTable table = new DataTable();
table.Columns.Add("Name", typeof(string));
table.Columns.Add("Price", typeof(double));
table.Columns.Add("Date", typeof(DateTime));
table.Rows.Add("Amro", 25, DateTime.Now);
table.Rows.Add("Bob", 10, DateTime.Now.AddDays(1));
table.Rows.Add("Alice", 50, DateTime.Now.AddDays(2));
return table;
}
}
}
The output of this C# program as returned by the compiled MATLAB function:
'Amro'
'Bob'
'Alice'
25
10
50
2011 9 26 20 13 8.3906
2011 9 27 20 13 8.3906
2011 9 28 20 13 8.3906
One option, is to just open up .NET code directly from matlab, and have matlab query the database directly, using your .net interface instead of trying to go through this serialization process you describe. I have done this repeatedly in our environment with great success. In such an an endeavor
Net.addAssembly is your biggest friend.
Details are here.
http://www.mathworks.com/help/matlab/ref/net.addassembly.html
A second option would be to go with Matlab Cell Array's. You can set it up, so the columns are different data types, each column forming a cell. That is a trick matlab itself uses in the textscan function. I'd recommend reading the documentation for that function here:
http://www.mathworks.com/help/techdoc/ref/textscan.html
A third option, is to use textscan completely. Write a text file out from your .net code, and let textscan handle the parsing of it. Textscan is very powerful mechanism for getting this kind of data into matlab. You can point textscan to a file, or to a bunch of strings.
I have tried the functions written by #Amro but the result for certain dates are not correct.
What I tried was:
Create a date in C#
Use function to convert to Matlab date num as supplied by #Amro
Use that number in Matlab to check its correctness
It seems to have problems with date with 1 Jan 00:00:00 for some years e.g. 2014, 2015. For example,
DateTime dt = new DateTime(2014, 1, 1, 0, 0, 0);
double dtmat = convertToMATLABDateNum(dt);
I got dtmat = 735599.0 from this.
I used in Matlab as follow:
datestr(datenum(735599.0))
I got this in return:
ans = 31-Dec-2013
When I tried 1 Jan 2012 it was OK. Any suggestion or why this happens?
I had the same issue as #Johan.
The problem is in Leap years that not calculate correctly the date
To fix it I change the code that converts the DateTime to the following:
private static long MatlabDateConversionFactor = (10000000L * 3600L * 24L);
private static long tickDiference = 367;
public static double convertToMATLABDateNum(DateTime dt) {
var converted = ((double)dt.Ticks / (double)MatlabDateConversionFactor);
return converted + tickDiference;
}
public static DateTime convertFromMATLABDateNum(double datenum) {
var ticks = (long)((datenum - 367) * MatlabDateConversionFactor);
return new DateTime(ticks, DateTimeKind.Utc);
}

Categories

Resources