I write some data into csv file from List but some list indexes has empty string but another indexes has value
in these cases the data compared with another list wrote in the same csv file
this is my csv file opened using excel sheet
in the third column there exist ID for the the second column cell so in the coming rows i want to detect the name of the ID based on previous rows
like in row 3 it's ID is 19 and name is I/O so in the 7th row the ID is 19 and want to fill the second cell now
info : the IDs is already known above and any next ID will be exist before
by the follwing code.
bool isInList = ms.IndexOf(ShapeMaster) != -1;
if (isInList)
{
savinglabelnamefortextbox = t.InnerText;
string replacement =
Regex.Replace(savinglabelnamefortextbox, #"\t|\n|,|\r", "");
xl.Add("");
dl.Add(replacement);
ms.Add(ShapeMaster);
}
and I use the following code to write to the csv file
using (StreamWriter sw = File.CreateText(csvfilename))
{
for (int i = 0; i < dl.Count; i++)
{
var line = String.Format("{0},{1},{2}", dl[i], xl[i],ms[i]);
sw.WriteLine(line);
}
}
Try this
for (int x = 0; x < ms.Count; x++)
{
if (xl[x] != "")
{
continue;
}
else if (xl[x] == "")
{
for (int y = 0; y<xl.Count; y++)
{
if (ms[y] == ms[x])
{
xl[x] = xl[y];
break;
}
}
continue;
}
}
Related
I want to delete some of the particular lines from a sales order documents Lines part by Add On using c# .
You need to first get the document you want to alter using DocEntry.
You then have to set the line number that needs deletion. See below
Documents oDoc = oCompany.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oOrders);
int docEntry = 109;
int lineNum = 2;
// Load your sales orders
if (oDoc.GetByKey(docEntry))
{
// Go through your line items
for (int i = 0; i < oDoc.Lines.Count; i++)
{
oDoc.Lines.SetCurrentLine(i);
if (oDoc.Lines.LineNum == lineNum) //Find your line number that you want delete.
{
oDoc.Lines.Delete(); //Delete
break;
}
}
// Update your sales order
if (oDoc.Update() != 0)
MessageBox.Show(oCompany.GetLastErrorDescription());
}
private void Delete_Single_Line_Row(string docentry, int lNum)
{
SAPbobsCOM.Documents oSalesOrd = null;
oSalesOrd = (SAPbobsCOM.Documents)SBOC_SAP.G_DI_Company.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oOrders);
int docEntry = Convert.ToInt32(docentry);
int lineNum = lNum;
// Load your sales orders
if (oSalesOrd.GetByKey(docEntry))
{
// Go through your line items
for (int i = 0; i < oSalesOrd.Lines.Count; i++)
{
oSalesOrd.Lines.SetCurrentLine(i);
if (oSalesOrd.Lines.LineNum == lineNum) //Find your line number that you want delete.
{
oSalesOrd.Lines.Delete(); //Delete
break;
}
}
// Update your sales order
int result = oSalesOrd.Update();
}
} enter code here
Documents oDoc = Utils.oCompany.GetBusinessObject(BoObjectTypes.oOrders);
oDoc.GetByKey(123);
oDoc.Lines.SetCurrentLine(0);
oDoc.Lines.Delete();
int lret = oDoc.Update();
if (lret != 0)
{
//HANDLE ERROR
}
This is pretty straight forward I think.
I have a DataTable with 1 column and a List of DataTables with 2 columns each.
I want to compare the Value of the DataTable with the first 6 digits of the Value of each DataTable in the List row by row.
This is my Code:
for(int fs = 0; fs < dataTable.Rows.Count; fs++)
{
for(int fs2 = 0; fs < dataTableList.Count; fs2++)
{
for(int fs3 = 0; fs3 < dataTableList[fs2].Rows.Count; fs3++)
{
if(dataTable.Rows[fs]["columnName"].ToString().Equals(dataTableList[fs2].Rows[fs3]["otherColumnName"].ToString().Substring(0,6)))
{
//do sth.
}
}
}
}
When the program reaches if(dataTable.Rows[fs]["columnName"].ToString().Equals(dataTableList[fs2].Rows[fs3]["otherColumnName"].ToString().Substring(0,6))) it stops and i get an System.ArgumentOutOfRangeException error.
Does anybody know what I am doing wrong? When I MessageBox the substring it is working.
So, first of all, I suggest refactoring this monstrosity to foreach loops.
foreach(var row in dataTable.Rows)
{
foreach(var otherDataTable in dataTableList)
{
foreach(var otherRow in otherDataTable.Rows)
{
/* ... */
}
}
}
And then checking if the string you're trying to get a substring of actually has length of 6 or more.
const int compareLength = 6;
const string columnName = "columnName";
const string otherColumnName = "otherColumnName";
foreach(var row in dataTable.Rows)
{
foreach(var otherDataTable in dataTableList)
{
foreach(var otherRow in otherDataTable.Rows)
{
var value = row[columnName].ToString();
var otherValue = otherRow[otherColumnName].ToString();
if(otherValue.Length >= compareLength &&
value == otherValue.Substring(0, compareLength))
{
/* Do something. */
}
}
}
}
My bet is that Substring call when the compared value was shorter than 6 was the problem. See if this helps.
I try to read excel file using NPOI library.
Here is the code:
public void ReadDataFromXL()
{
try
{
for (int i = 1; i <= sheet.LastRowNum; i++)
{
IRow row = sheet.GetRow(i);
for (int j = 0; j < row.Cells.Count(); j++)
{
var columnIndex = row.GetCell(j).ColumnIndex;
var cell = row.GetCell(j);
if (cell != null)
{
switch (cell.CellType)
{
case CellType.Numeric:
var val = cell.NumericCellValue; ;
break;
case CellType.String:
var str = cell.StringCellValue;
break;
}
}
}
}
}
catch (Exception)
{
throw;
}
}
Here the content of .xlsx file that I try to read:
As you can see column X and column Y are numeric columns.
But when I start to read this columns using the code above some of the numeric values in X and Y column have been recognizes by code as string values.
For example in picture above the cell B4 is numeric type but, on cell.CellType it shows String and the value of the string is 31.724732480727\n. '\n' is appended to the value.
Any idea why some numeric values appeared as string and why '\n' appended to the value?
It looks like the datatype of the column is of String, so if you wanted to check for the double datatype (assuming its going to be in the num+'\n' format, you could try the following snippet of code.
String number = "1512421.512\n";
double res;
if (double.TryParse(number.Substring(0, number.Length - 1), out res))
{
Console.WriteLine("It's a number! " + res);
}
I'm reading an xlsx file using NPOI lib, with C#. I need to extract some of the excel columns and save the extracted values into some kind of data structure.
I can successfully read the file and get all the values from the 2nd (the first one contains only headers) to the last row with the following code:
...
workbook = new XSSFWorkbook(fs);
sheet = (XSSFSheet)workbook.GetSheetAt(0);
....
int rowIndex = 1; //--- SKIP FIRST ROW (index == 0) AS IT CONTAINS TEXT HEADERS
while (sheet.GetRow(rowIndex) != null) {
for (int i = 0; i < this.columns.Count; i++){
int colIndex = this.columns[i].colIndex;
ICell cell = sheet.GetRow(rowIndex).GetCell(colIndex);
cell.SetCellType(CellType.String);
String cellValue = cell.StringCellValue;
this.columns[i].values.Add(cellValue); //--- Here I'm adding the value to a custom data structure
}
rowIndex++;
}
What I'd like to do now is check if the excel file is empty or if it has only 1 row in order to properly handle the issue and display a message
If I run my code against an excel file with only 1 row (headers), it breaks on
cell.SetCellType(CellType.String); //--- here cell is null
with the following error:
Object reference not set to an instance of an object.
I also tried to get the row count with
sheet.LastRowNum
but it does not return the right number of rows. For example, I have created an excel with 5 rows (1xHEADER + 4xDATA), the code reads successfully the excel values. On the same excel I have removed the 4 data rows and then I have launched again the code on the excel file. sheet.LastRowNum keeps returning 4 as result instead of 1.... I think this is related to some property bound to the manually-cleaned sheet cells.
Do you have any hint to solve this issue?
I think it would be wise to use sheet.LastRowNum which should return the amount of rows on the current sheet
Am I oversimplifying?
bool hasContent = false;
while (sheet.GetRow(rowIndex) != null)
{
var row = rows.Current as XSSFRow;
//all cells are empty, so is a 'blank row'
if (row.Cells.All(d => d.CellType == CellType.Blank)) continue;
hasContent = true;
}
You can retrieve the number of rows using this code:
public int GetTotalRowCount(bool warrant = false)
{
IRow headerRow = activeSheet.GetRow(0);
if (headerRow != null)
{
int rowCount = activeSheet.LastRowNum + 1;
return rowCount;
}
return 0;
}
Here is a way to get both the actual last row index and the number of physically existing rows:
public static int LastRowIndex(this ISheet aExcelSheet)
{
IEnumerator rowIter = aExcelSheet.GetRowEnumerator();
return rowIter.MoveNext()
? aExcelSheet.LastRowNum
: -1;
}
public static int RowsSpanCount(this ISheet aExcelSheet)
{
return aExcelSheet.LastRowIndex() + 1;
}
public static int PhysicalRowsCount(this ISheet aExcelSheet )
{
if (aExcelSheet == null)
{
return 0;
}
int rowsCount = 0;
IEnumerator rowEnumerator = aExcelSheet.GetRowEnumerator();
while (rowEnumerator.MoveNext())
{
++rowsCount;
}
return rowsCount;
}
I am trying to parse a column (File is composed of only 1 column filled with double numbers.) in a .csv file but C# throws me error when it encounters an empty cell.
{"Input string was not in a correct format."}
I want program to continue with the next cell when this happens. Is there a way?
Note: I tried
if(array[i] != null)
but this does not seem to work.
I use this block to read from .csv:
var column = new List<string>();
using (var rd = new StreamReader(#"pathofthecsvfile"))
{
while (!rd.EndOfStream)
{
var splits = rd.ReadLine().Split(';');
column.Add(splits[0]);
}
}
string[] arr = column.ToArray();
double[] array = new double[arr.Length];
//problem is in this block
for (int i = 0; i < array.Length; i++)
{
if (arr[i] != null)
{
array[i] = Convert.ToDouble(arr[i]);
}
}
I would check it when inserting:
if split[0] != null && split[0] != "" {
column.Add(splits[0]);
}
You are not validating the data you are loading into the array to see if it is in a valid format - Convert.ToDouble will fail for a number of reasons other than just null value and empty string.
If you are happy just to skip to next column, use a TryParse instead in the for loop:
double.TryParse(arr[i], out array[i]);