I want to set the cell formula for columns k-P by using a loop and in c# i can only loop with integers, how do you actually get the column(E.G K,L,M,N,O,P) with the index? for looping through rows its pretty easy because they are just numbers but for columns excel uses letters.
I cant think of anything other than defining my own List for letters k-P in c#
You can use CellReference, if you already have the cell object.
var temp = new CellReference(cell);
var reference = temp.FormatAsString();
Hope this works for you!
Allso you can get it directly from ICell object:
var adress = cell.Address.FormatAsString();
Ore if you need column name only add method like this:
public static string GetColumnName(this ICell cell)
{
return Regex.Match(cell.Address.FormatAsString(), #"[A-Z]+").Value;
}
And then just call it like:
var colName = cell.GetColumnName();
Related
I have an IList<Row> where Row contains a list of Cells IList<Cell>. These cells have a ToString, ToDouble etc.
I want to loop through this list of rows and check if there are rows with the same value for cell[index]. Let's say for cell 3.
If there are rows with the same value, I should merge these rows into one row. It is certain that all cells are - in case of the same key - the same except for the cell with an amount, let's say that this is cell 4. So this should be merged (so 1 deleted) with the only difference that the value is the sum of both.
I have tried to create a Dictionary<string, double>. I looped through all rows, check whether map contains key, if not -> merge (also did this with an extension method Merge, but the same idea).
After this loopthrough, I created a new list, placed the dictionary in there and looped through the old list for the other information.
Well I think that my way is way too long, that there should be a way to do this much easier, maybe by LINQ or whatsoever. Any idea's on how to do this properly? Or do you guys think that my approach isn't that bad?
Try:
var mergedRows = rows.GroupBy(x => x.Cells[0].Value.ToString())
.Select(x => new Row() { Cells = new List<Cell>
{
new Cell() { Value = x.Key },
new Cell() { Value = x.Sum(y => int.Parse(y.Cells[1].Value.ToString())) }
}
});
I am using the library LinqToExcel to read excel files in my mvc4 project. My problem is when I try to read the headers at row 4... How I can do this?
In project, exists a function that returns all the column names, but I suppose that the columns need to be at row 0.
// Summary:
// Returns a list of columns names that a worksheet contains
//
// Parameters:
// worksheetName:
// Worksheet name to get the list of column names from
public IEnumerable<string> GetColumnNames(string worksheetName);
Thanks.
Unfortunately the GetColumnNames() method only works when the header row is on row 1.
However, it should be possible to get the column names by using the WorksheetRangeNoHeader() method.
It would look something like this
var excel = new ExcelQueryFactory("excelFileName");
// Only select the header row
var headerRow = from c in excel.WorksheetRangeNoHeader("A4", "Z4")
select c;
var columnNames = new List<string>();
foreach (var headerCell in headerRow)
columnNames.Add(headerCell.ToString());
An FYI for future googlers:
It appears that GetColumnNames() has changed since the above answer was accepted.
There is now an overload in which you can define the range of the header row as a string:
// This will return a List<string>
var colNames = ExcelFile
.GetColumnNames(SheetName, "A9:AF9")
.ToList();
I have the below table sorted & i want to verify the table is sorted in an order using C# selenium
first numeric values will be sorted and alphabets will be sorted.
Display name
1
2
5
7
Abbot
Edfdsf
Fdsf
i need to to verify in c# selenium.
My Thoughts: is it easy way to convert each row value to ASCII number and compare with the next row ?
Please provide your suggestion?
I would suggest that you store the display names in a List, copy the List and sort it, and then compare it to the original list.
List<String> displayNames = new List<string>();
// grab the cells that contain the display names you want to verify are sorted
IReadOnlyList<IWebElement> cells = Driver.FindElements(locator);
// loop through the cells and assign the display names into the ArrayList
foreach (IWebElement cell in cells)
{
displayNames.Add(cell.Text);
}
// make a copy of the displayNames array
List<String> displayNamesSorted = new List<string>(displayNames);
displayNamesSorted.Sort();
Console.WriteLine(displayNames.SequenceEqual(displayNamesSorted));
Most elegant way:
var cells = WebDriver.FindElements(locator);
Assert.IsTrue(cells.OrderBy(c => c.Text).SequenceEqual(cells));
I am trying to retrieve data from an Excel spreadsheet using C#. The data in the spreadsheet has the following characteristics:
no column names are assigned
the rows can have varying column lengths
some rows are metadata, and these rows label the content of the columns in the next row
Therefore, the objects I need to construct will always have their name in the very first column, and its parameters are contained in the next columns. It is important that the parameter names are retrieved from the row above. An example:
row1|---------|FirstName|Surname|
row2|---Person|Bob------|Bloggs-|
row3|---------|---------|-------|
row4|---------|Make-----|Model--|
row5|------Car|Toyota---|Prius--|
So unfortunately the data is heterogeneous, and the only way to determine what rows "belong together" is to check whether the first column in the row is empty. If it is, then read all data in the row, and check which parameter names apply by checking the row above.
At first I thought the straightforward approach would be to simply loop through
1) the dataset containing all sheets, then
2) the datatables (i.e. sheets) and
3) the row.
However, I found that trying to extract this data with nested loops and if statements results in horrible, unreadable and inflexible code.
Is there a way to do this in LINQ ? I had a look at this article to start by filtering the empty rows between data but didn't really get anywhere. Could someone point me in the right direction with a few code snippets please ?
Thanks in advance !
hiro
I see that you've already accepted the answer, but I think that more generic solution is possible - using reflection.
Let say you got your data as a List<string[]> where each element in the list is an array of string with all cells from corresponding row.
List<string[]> data;
data = LoadData();
var results = new List<object>();
string[] headerRow;
var en = data.GetEnumerator();
while(en.MoveNext())
{
var row = en.Current;
if(string.IsNullOrEmpty(row[0]))
{
headerRow = row.Skip(1).ToArray();
}
else
{
Type objType = Type.GetType(row[0]);
object newItem = Activator.CreateInstance(objType);
for(int i = 0; i < headerRow.Length; i++)
{
objType.GetProperty(headerRow[i]).SetValue(newItem, row[i+1]);
}
results.Add(newItem);
}
}
I have a csv file I am going to read from disk. I do not know up front how many columns or the names of the columns.
Any thoughts on how I should represent the fields. Ideally I want to say something like,
string Val = DataStructure.GetValue(i,ColumnName).
where i is the ith Row.
Oh just as an aside I will be parsing using the TextFieldParser class
http://msdn.microsoft.com/en-us/library/cakac7e6(v=vs.90).aspx
That sounds as if you would need a DataTable which has a Rows and Columns property.
So you can say:
string Val = table.Rows[i].Field<string>(ColumnName);
A DataTable is a table of in-memory data. It can be used strongly typed (as suggested with the Field method) but actually it stores it's data as objects internally.
You could use this parser to convert the csv to a DataTable.
Edit: I've only just seen that you want to use the TextFieldParser. Here's a possible simple approach to convert a csv to a DataTable:
var table = new DataTable();
using (var parser = new TextFieldParser(File.OpenRead(path)))
{
parser.Delimiters = new[]{","};
parser.HasFieldsEnclosedInQuotes = true;
// load DataColumns from first line
String[] headers = parser.ReadFields();
foreach(var h in headers)
table.Columns.Add(h);
// load all other lines as data '
String[] fields;
while ((fields = parser.ReadFields()) != null)
{
table.Rows.Add().ItemArray = fields;
}
}
If the column names are in the first row read that and store in a Dictionary<string, int> that maps the column name to the column index.
You could then store the remaining rows in a simple structure like List<string[]>.
To get a column for a row you'd do csv[rowIndex][nameToIndex[ColumnName]];
nameToIndex[ColumnName] gets the column index from the name, csv[rowIndex] gets the row (string array) we want.
This could of course be wrapped in a class.
Use the csv parser if you want, but a text parser is something very easy to do by yourself if you need customization.
For you need, i would use one (or more) Dictionnary. At least one to have the PropertyString --> column index. And maybe the reverse one column index--> PropertyString if needed.
When i parse a file for csv, i usually put the result in a list while parsing, and then in an array once complete for speed reasons (List.ToArray()).