ASP.NET C# DataTables replace specific value in specific columns in Table - c#

I have a problem with checking the value of an specific Column in a DataTable.
My DataTable is coming from a sql query and it has in this case 8 columns.
My 3rd column is a column called Status. In the Database status is going to be saved as numbers. 1 = "open", 2 = "in work", 3 = "closed" .
Now I'm iterating my whole table until this column and I want to check whether the value is 1 2 or 3 and replace the 1 2 or 3 with the corresponding status name. (I'm iterating, because there will be more columns which are going to be modified, so not only the column 2 in every row, but also 4,5 - but they are going to be same way like column 2. So if I understand one, I can do the rest similar).
But I don't know how to check the value, I have tried the .contains and equals method.
Here is my code:
//for each row
for (int i = 0; i < dt.Rows.Count; i++)
{
//search colums
for (int j = 0; j < dt.Columns.Count; j++)
{
if (j == 2)
{
if (dt.Columns[j].Equals("1") == true)
{
// dt.Columns[j].value should be replaced with "open";
}
if (dt.Columns[j].Equals("2") == true)
{
// dt.Columns[j].value should be replaced with "in-work";
}
if (dt.Columns[j].value == "3")
{
// dt.Columns[j].value should be replaced with "closed";
}
}
}
So how could I check the value of the Column and replace with a string?
Thanks in advance!

You can try checking with this:
if(dt.Rows[i][j].ToString() == "1")
And replace with this:
dt.Rows[i][j] = "Open";

Since dt.Columns[j] is a DataColumn convert it to string:
dt.Columns[j].ToString()
and then you can do
dt.Columns[j].ToString() == "1"
To rename your column just use the property Caption
var col = dt.Columns[j];
col.Caption = "in-work";

Related

How to remove blank columns from excel using EPPlus

I wanted to remove unwanted columns towards the last or any blank columns without header in between columns, then remove formatting from excel worksheet from each rows and column using EPPlus.
Please find the sample progress.
public static class EpPlusExtension
{
public static string[] GetHeaderColumns(this ExcelWorksheet sheet)
{
List<string> columnNames = new List<string>();
foreach (var firstRowCell in sheet.Cells[sheet.Dimension.Start.Row, sheet.Dimension.Start.Column, 1, sheet.Dimension.End.Column])
columnNames.Add(firstRowCell.Text);
return columnNames.ToArray();
}
public static ExcelWorksheet RemoveCellFormatter(this ExcelWorksheet worksheet)
{
try
{
dynamic cellValue = null;
int lastColumnWithHeaderIndex = worksheet.GetHeaderColumns().Count();
for (int i = worksheet.Dimension.Start.Row; i <= worksheet.Dimension.End.Row; i++)
{
for (int j = worksheet.Dimension.Start.Column; j <= lastColumnWithHeaderIndex; j++)
{
if (worksheet.Cells[i, j].Value != null)
{
cellValue = worksheet.Cells[i, j].Value;
worksheet.Cells[i, j].Clear();
worksheet.Cells[i, j].Value = cellValue;
cellValue = null;
}
}
}
return worksheet;
}
catch (Exception ex)
{
_logger.LogError($"Error Message: Exception While clearing formatting from worksheet. |Exception: {ex.Message}");
return worksheet;
}
}
}
Sample code handles the last unwanted columns:
How to handle also null columns in-between?
Thanks in advance
I am not an EPPlus expert and was unable to find a method that would remove “empty” columns. However, as VDWWD notes, it should not be difficult to loop through the rows of a column and check to see if all the cells in that column are null and if so, then remove that column.
Obviously, if there are many rows, then this may not be the best approach. If there are many rows and columns, there is possibly another option, however, in this case, I will assume the execution time is acceptable. In my tests, the worksheet contained 735 rows and 9 columns with two (2) empty columns and it took less than a second.
Given this, a simple solution is to loop through the columns. In each column iteration, loop through all the rows. We will use two variables: a bool valueFound and set it to false. This will be used to indicate if we found a non null value in a cell. And a List<int> emptyColIndexes is a list of ints to hold the indexes of the columns that are "empty" in the worksheet.
NOTE: it should be obvious that we DO NOT want to “delete” the empty
column as soon as we find one. We only want to store its index and
delete the columns later. The reason for this… is… deleting the column
while “looping” through the columns will obviously cause problems.
Therefore, we only want to get a list of the indexes of the “empty”
columns.
When looping through the rows of a column, IF we find a value that is NOT null, then we set valueFound to true and exit the rows loop using a break command. If we loop through all the rows in a column and exit the loop, we will check the valueFound variable, IF it is false, then this would mean all the row values in that column are null, then we add that columns index to the emptyColIndexes list.
Lastly, after collecting all the “empty” column indexes, we loop through the indexes and delete the columns.
NOTE: this loop needs to start from the “last” column index and move
to the first. This should be obvious being that if we delete a column
on the left of another column in the list, then the indexes will get
messed up. Basically, we want to delete the columns from the right to
left. Therefore, the loop starts at the last index and goes to the
first index.
In addition, and it is not important, however, it appears that returning the worksheet in the RemoveCellFormatter is unnecessary.
Below is the code that demonstrates what is described above.
public static void RemoveEmptyColumns(ExcelWorksheet worksheet) {
try {
List<int> emptyColIndexes = new List<int>();
bool valueFound;
for (int curCol = worksheet.Dimension.Start.Column; curCol <= worksheet.Dimension.End.Column; curCol++) {
valueFound = false;
for (int curRow = worksheet.Dimension.Start.Row; curRow <= worksheet.Dimension.End.Row; curRow++) {
if (worksheet.Cells[curRow, curCol].Value != null) {
valueFound = true;
break;
}
}
if (!valueFound) {
emptyColIndexes.Add(curCol);
}
}
if (emptyColIndexes.Count > 0) {
for (int i = emptyColIndexes.Count - 1; i >= 0; i--) {
worksheet.DeleteColumn(emptyColIndexes[i]);
}
}
}
catch (Exception ex) {
MessageBox.Show("Error Message: Exception while removing empty columns from worksheet. " + ex.Message);
}
}

How to skip some column header text of DataTable and select the rest in datatable C#?

I have a datatable like this:
As you can see, I have a monthly report that shows Presence and Absence of a student.
Well, now I want to skip First 4 columns i.e. Id,Name,Gender, Division and take the month dates in a variable.
I tried to store the Header Text in a variable obj like this:
for(int i = 0; i<=dt.Rows.Count-1; i++)
{
for (int j = 4; j <= dt.Columns.Count-1; j++)
{
string[] obj = dt.Rows[i][j].ToString().Split(',');
}
}
But obj gives me value of the cell i.e. when it reaches the col 01-01-2020 it gives me A, but I want the header text (i.e. 01-01-2020).
How can I do that?
You want column names
var headers = LeaveReportDt.Columns
.Cast<DataColumn>()
.Skip(4)
.Select(c => c.ColumnName)
.ToArray();

How to get IDs of only checked rows of a datagridview

I have a datagridview that contains list of subjects populated from Subject table from database.Columns include
Select(checkbox),
SubjectId,
SubjectName,
SubjectGroup.
Now I want if a user Selects on any of the desired rows, the corresponding SubjectId's should be added to a List. I have made and inserted into the desired table in the database.
The problem is that the new column of checkboxes I have added to this datagridview is not being detected.
My code is:
foreach (DataGridViewRow row in gvSubjectsOpted.Rows)
{
if (Convert.ToBoolean(gvSubjectsOpted.SelectedRows[0].Cells["SelectId"].Value=true))
{
olist.Add(gvSubjectsOpted.SelectedRows[0].Cells["SubjectId"].Value.ToString());
}
}
Late to the party. I had the same issue with trying to get the checkbox column by name, use the index instead. Here is a linq example assuming the checkbox is column 0 and the stored values for TrueValue and FalseVale are true and false respectively.
var checkedRows = from DataGridViewRow r in gvSubjectsOpted.Rows
where Convert.ToBoolean(r.Cells[0].Value) == true
select r;
foreach (var row in checkedRows)
{
olist.Add(row.Cells["SubjectId"].Value.ToString());
}
I realise this is an old post but I came across it and didn't think it was really answered in an efficient way so I thought I would add my method.
I have a similar block in my windows app. I read the values from the grid when the user clicks a button, and I want to know which rows they checked. As the checkboxes are in Cell 0 and the data I want is in Cell 1, I use the following code. Note the cast: it is important as it allows us the use the Where clause and therefore just a single line of code to get the collection of data. I could use the name of the cells instead of magic index numbers but then it would not fit your app so I put numbers instead (you should use names)
var checkedRows = dataGridView
.Rows
.Cast<DataGridViewRow>()
.Where(x => x.Cells[0].Value.ToString() == "1")
.Select(x => x.Cells[1]);
Note that this will give you an IEnumerable of type DataGridViewCell. If you want you can either add something like .Value.ToString() to the select or do this when you use your collection.
You question is similar to another SO question.
Check the answer of this Datagridview checkboxcolumn value and functionality.
Try this
foreach(GridViewRow r in gvSubjectsOpted.Rows)
{
GridViewCheckBoxColumn c = r.cells[0].Controls[0] as GridViewCheckBoxColumn;
if(c.Checked)
{
//Do something.
}
}
private void button1_Click(object sender, EventArgs e)
{
string subjId;
List<string> lines = new List<string>();
for (int i = 0; i < gvSubjectsList.Rows.Count; i++)
{
bool Ischecked =Convert.ToBoolean(gvSubjectsList.Rows[i].Cells["Select"].Value);
if (Ischecked == true)
{
subjId = gvSubjectsList.Rows[i].Cells["SubjectId"].Value.ToString();
lines.Add(subjId);
}
}
comboBox1.DataSource = lines;
}
//the most important thing is to set 'true' and 'false' values against newly added checkboxcolumn instead of '0' and '1'...that is,
CBColumn.FalseValue = "false";
CBColumn.TrueValue = "true";

Remove link text in Datagridview

I have a DataGridView which is populated from a list. I then Have defined a link column in the last column which is not DataBound saying View, how do I remove this link text if a condition is met. I have the below:
dgvReport.AutoGenerateColumns = false;
dgvReport.DataSource = queries;
//locals
Int32 lastColumnIndex = this.dgvReport.Columns.Count - 1;
//hide reads links for the null queries
for (int i=0; i < queries.Count; i++) {
if (queries[i].SomeID == null || queries[i].AnotherID == null) {
this.dgvReport.Rows[i].Cells[lastColumnIndex].Value = "";
}
}
This is not working and my column text still shows View. Any ideas?
Edit: lastColumnIndex is 24 which is indeed the last column index
You might try
View.PlainTextBehaviour = true;
It will remove the link and show it as plain text

How do I pull data from a javascript populated table?

I am trying to pull data from my populated javascript table. How do I pull the value from a javascript row? I am using
for (var i = 0; i < rowCount; i++) {
var row = table.rows[i];
//This is where I am having trouble
var chkboxIndicator = row.cells[0].childNodes[1];
alert(chkboxIndicator);
//
if (chkboxIndicator == indicator && Checkbox.checked == false) {
table.deleteRow(i);
rowCount--;
i--;
}
}
which has an alert message of "undefined". I tried .value and .text as well and no progress. How do I get the text from the childNodes?
Since you're purportedly using jQuery, why not use it to get your checkboxes and simplify your life?
$("#mytableid tr").each(function() {
// find the checkbox (assuming you have only one; if not, use :eq(n))
var $checkbox = $("input:checkbox", this);
// if it's checked, delete this row
if ($checkbox.is(":checked"))
$(this).remove();
});
There are crazier ways to do it, but I thought that example would be illustrative. :)
Are you sure that chkboxIndicator is not null?
If it is null it will alert as undefined.
Try
for (var i = 0; i < rowCount; i++)
{
var row = table.rows[i];
// Add null check for row
if (row != null)
{
//This is where I am having trouble
// Add null check for cell
if (row.cells[0] != null)
{
var chkboxIndicator = row.cells[0].childNodes[1];
// Added null check for chkboxIndicator
if (chkboxIndicator != null)
{
alert(chkboxIndicator);
if (chkboxIndicator == indicator && Checkbox.checked == false)
{
table.deleteRow(i);
rowCount--;
i--;
}
}
else
{
alert('chkboxIndicator is NULL');
}
}
}
}
Depends on what your DOM actually looks like.
I suspect your problem is that childNodes[1] could be a text node.
You probably want to use a selector on the cell instead, such as:
$(row.cells[0]).find("input[type='checkbox']");
If you want it to be fast too, use jOrder (http://github.com/danstocker/jorder).
Create a jOrder table with your data. Make sure to have a field 'checked' in it with true or false values, and put an index on that column and the ID:
var table = jOrder(data)
.index('id', ['ID'])
.index('checked', ['checked'], { grouped: true });
Then, you can rebuild your grid with the unchecked rows removed using table.where([{ 'checked': true }]) as the source.
But first, populate your grid with the data from the jOrder table. Use table.flat() to obtain the flat table.
When you build the grid, bind the record IDs to the checkboxes e.g. by $('#elem').data(). When a checkbox gets (un)checked, update the 'checked' value in the table:
var before = table.where([{ 'ID': 5 }])[0];
var after = table.where([{ 'ID': 5 }])[0];
after.checked = true;
table.update(before, after);
Note that you shouldn't do this for each item on an "(un)check all" event though. In that case just simply pass on table.flat() or set the 'checked' values in the buffer returned by it, and then issue a table.reindex() and THEN call table.where(...).
The block of code that I was missing was the following
var row = table.rows.item(i).cells;
var cellLength = row.length;
var cellVal = row.item(5).innerHTML;
Thanks for leading me in the right direction

Categories

Resources