I have a datatable problem when I reject changes on the table. I've created an example below which demonstrates the problem:
DataTable table = new DataTable();
table.Columns.Add("Name", typeof(string));
table.Columns.Add("Last_Name", typeof(string));
table.Columns.Add("Male", typeof(Boolean));
foreach (DataColumn column in table.Columns)
{
if (column.ColumnName == "Name")
{
column.Unique = true;
}
}
DataRow row;
row = table.NewRow();
row["Name"] = String.Format("Steve");
row["Last_Name"] = String.Format("Smith");
row["Male"] = true;
table.Rows.Add(row);
table.AcceptChanges();
So at this stage I have a DataTable with a unique column constraint and 1 row in that table.
I now delete that row:
row.Delete();
This sets the rowstate to Deleted.
At this stage I realise that I've made a mistake and want to add the row again. So I create the new row again and add it to the DataTable:
row = table.NewRow();
row["Name"] = String.Format("Steve");
row["Last_Name"] = String.Format("Smith");
row["Male"] = true;
table.Rows.Add(row);
At this stage my DataTable contents are in the following state:
table.Rows[0].RowState is Deleted
table.Rows[1].RowState is Added
Now, I've changed my mind about the whole thing and want to get back to how I started so I call RejectChanges:
table.RejectChanges();
When I do this I receive the following error:
Column 'Name' is constrained to be unique. Value 'Steve' is already present.
I understand that there are 2 rows with the same values but I thought reject changes would have ingored this as the RowStates are different.
Any ideas how I can get round this?
In my live code I use this to move rows between to 2 grids (like allowing the user to selected what columns are visible)
I'm using C#4.0 in Visual Studio 2012
Thanks in advance
Related
I'm trying to place a table at a bookmark in a word document using poi
the paragraph is found
CTP ctp = paragraph.getCTP();
// Get all bookmarks and loop through them
for( CTBookmark bookmark in ctp.getBookmarkStartList())
{
for(j = 0; j < viewScope.Bookmarks.length; j++)
{
if(bookmark.getName().equals(viewScope.Bookmarks[j]))
A table does get created but the word file is corrupt ... "word found unreadable content"
XmlCursor cursor = null;
cursor = paragraph.getCTP().newCursor();
// cursor.toNextSibling();
XWPFTable wTable = paragraph.getBody().insertNewTbl(cursor);
XWPFTableRow row = wTable.createRow(); //
row.addNewTableCell();
XWPFTableCell cell = row.createCell();
cell.setText("New work");
cursor.dispose();
Welcome to the nice world of XWPFTable creating methods. Instead of creating an empty table apache poi creates tables having rows and empty cells already. And what exactly it creates changes from version to version. So you cannot be sure what already exists and what not. So you always need to check. Is there a row already or needs one to create? Is there a cell already or needs one to create?
In your case:
...
if (paragraph != null) {
cursor = paragraph.getCTP().newCursor();
XWPFTable table = paragraph.getBody().insertNewTbl(cursor);
XWPFTableRow row = table.getRow(0); if (row == null) row = table.createRow();
XWPFTableCell cell = row.getCell(0); if (cell == null) cell = row.createCell();
cell.setText("New work");
cursor.dispose();
}
...
See Inserting XWPFTable in between contents where I provided a code which inserts a table in between existing paragraphs dependent on the text contents. There I have edited now because apache poi formerly had put a paragraph already in a new created cell. But now it does that not more. So now you also have to check whether is there a paragraph already or needs to be created.
I want to click on an exact row in a WinTable where my criteria meets but couldnt succeed so far. I can search criteria for an exact row but I can not get total number of rows so that I would make a loop for all rows. I tried collection and table.Rows.Count,but both brings nothing to me. Can someone help me on this ?
#region Variable Declarations
WinTable uIG1Table = this.UIProMANAGEWindow.UIDefinitionsWindow.UIG1Window.UIG1Table;
WinRow dataGridrow = uIG1Table.GetRow(0);
#endregion
UITestControlCollection rows = uIG1Table.Rows;
// MessageBox.Show(rows[5].RowIndex.ToString());
foreach (WinRow row in uIG1Table.Rows)
{
foreach (WinCell cell in row.Cells)
{
if (cell.Value.ToString() == "E81")
Mouse.Click(cell, new Point(5, 0));
}
}
and this is the code with for loop
int rows = uIG1Table.Rows.Count;
for (int i = 0; i < rows; i++)
{
foreach (WinCell cell in dataGridrow.Cells)
{
if (cell.Value.ToString() == "E81")
Mouse.Click(cell, new Point(5, 0));
}
}
When doing a GetChildren() on a row, you will notice that the first child is of type RowHeader. A user typically clicks the row header to select the row.
Following code will iterate all the rows in a DataGridView and click the row header, effectively selecting the row:
UITestControlCollection rows = YourUIMapTable.Rows;
foreach (UITestControl row in rows)
{
UITestControl rowHeader = row.GetChildren().Single(child => child.ControlType == ControlType.RowHeader);
Mouse.Click(rowHeader);
}
If you want to select a specific row, you can do something like this:
Mouse.Click(YourUIMapTable.Rows[putIndexNumberHere].GetChildren().Single(child => child.ControlType == ControlType.RowHeader));
The sample code above is based on the program I wrote in my answer to this question:
How to get cell color information of a WinCell with codedui?
I want to delete row from datagridview when user clicks the delete button.The datagridview bounded to datatable _dt so i remove the row from _dt and try to rebind the modified _dt to datagridview but instead of deleting the row gets added to the last row of the datagridview what am I doing wrong here
private void btnDelete_Click(object sender, EventArgs e)
{
if (dataGridView1 != null && dataGridView1.SelectedRows.Count == 1)
{
string key = dataGridView1.SelectedRows[0].Cells["ID"].Value.ToString();
DataColumn[] keyColumns = new DataColumn[1];
keyColumns[0] = _dt.Columns["ID"];
_dt.PrimaryKey = keyColumns;
rowToDelete = _dt.Rows.Find(key);
_dt.Rows.Remove(rowToDelete);
_dt.AcceptChanges();
SqlCommandBuilder cb = new SqlCommandBuilder(_sqlDa);
_sqlDa.Fill(_dt);
_sqlDa.Update(_dt);
dataGridView1.DataSource = null;
dataGridView1.DataSource = _dt;
}
}
No need for Fill before update and also delete this row
_dt.AcceptChanges();
because this will remove the row from memory and when you call update
only the remaining rows are updated, it will not delete the row from database.
No need to call Fill Before Update, because Fill will get data again from db and your changes will be lost. So This will work for you.
SqlCommandBuilder cb = new SqlCommandBuilder(_sqlDa);
//_sqlDa.Fill(_dt);
_sqlDa.Update(_dt);
I am creating grid view through data adapter and all columns and rows are created from data base but problem occurs that when rows all rows are created there comes another empty row i want to stop that row to be generated and when i click and some value in that extra row another new row is created i want to stop all extra rows how to do this any help???
this is the grid view code i am using
conn.ConnectionString = s;
conn.Open();
dAdapter = new SqlDataAdapter(query, s);
dTable = new DataTable();
DataView myDataView = dTable.DefaultView;
dAdapter.Fill(dTable);
BindingSource bndSource = new BindingSource();
bndSource.DataSource = dTable;
dataGrid.DataSource = bndSource;
dataGrid.Columns["StudentId"].ReadOnly = true;
dataGrid.Columns["StudentName"].ReadOnly = true;
conn.Close();
Try setting AllowUserToAddRows to false.
I have one problem. I need to get the excel sheet name in a work book, which looks on the very left sheets tab -the first one from my point of view.
I am using this code:
public static string GetFirstExcelSheetName(OleDbConnection connToExcel)
{
DataTable dtSheetName =
connToExcel.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
List<String> lstExcelSheet = new List<string>(dtSheetName.Rows.Count);
foreach (DataRow row in dtSheetName.Rows)
lstExcelSheet.Add(row["TABLE_NAME"].ToString());
return lstExcelSheet[0];
}
The problem here is it is returning the rows not in the visual tab order but in a very different order - most probably the row created date.
How can it be possible to get the sheetnames table ordered according to their tab order so that I can easily get the 1st excel sheet name?
Thanks,
kalem keki
It should be the zero-th item in the workbooks(?) collection.
I think you have the right index, wrong collection.
Sorry, didn't notice you're using the rows collection of a datatable.
That's a different problem.
How do you create the datatable?
You might have to change the sort property of the dataview.
Dim dtSheetnames As DataTable = oleDBExcelConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, New Object() {Nothing, Nothing, Nothing, "TABLE"})
Dim FirstSheetName As String = dtSheetnames.Rows(0)!TABLE_NAME.ToString
The row 0 is not the first sheet in the excel file, rows are sorted by alphabetical order in this collection :/
I recommend using the NPOI library (http://npoi.codeplex.com/) rather than OleDB to retrieve data (including metadata) from Excel.
IIRC, OleDB will also fail for sheet names that include spaces or dollar signs.
OleDbConnection oconn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Session["path"].ToString() + "; Extended Properties=Excel 12.0;Persist Security Info=False;");
oconn.Open();
myCommand.Connection = oconn;
DataTable dbSchema = oconn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
if (dbSchema == null || dbSchema.Rows.Count < 1)
{
throw new Exception("Error: Could not determine the name of the first worksheet.");
}
string firstSheetName = dbSchema.Rows[0]["TABLE_NAME"].ToString();