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?
Related
I have below loop trying to printout keys and values stored in a hashmap
// Create the first row corresponding to the header
Row header = Sheet.createRow(0);
int headerIndex = 0;
for (Map.Entry<String, List<String>> entry : resultsToPrint.entrySet()) {
String key = entry.getKey();
header.createCell(headerIndex).setCellValue(key);
int rowIndex = 1;
for (String value : entry.getValue()) {
// Creating row
Row row = Sheet.createRow(rowIndex);
// create cell
row.createCell(headerIndex).setCellValue(value);
rowIndex++;
}
headerIndex++;
}
the results I am getting looks like this:
This is what gets printed
what I need this loop to do, is to populate the values of the second column as well and if I add a third column, it needs to populate the values for the third column etc.
Please assist
I have been looking endlessly for a method to compare values on different columns in the same row, to know which cell I should update.
The speradsheet is a simple model of stock management (it's quite simple and I've been doing it manually), but I wanted a 'faster'(*) ou automated way of updating the amounts os each item, and the timestamps (which are two: one for adding units to the stock, and one for withdrawing).
The obstacles so far are:
The onEdit() function won't work on automated changes like macros, so it's off the table;
I need to scan the whole spreadsheet to find every filled cell on column D, which carries the value i'm adding to or subtracting from my column C;
-For this i have already setup do filter the column 'from Z to A' to get all the cells with values on them, but the amount of items changed can vary, so i cant set a search with a fixed number of rows.
Since my sheet has over 90 entries (likely to increase) of at least 6 columns each, a for loop with if statements takes too long, (*)but execution time is not exactly the main concern right now.
The code is as follows, and I'll be attaching a picture of the sheet I'm working with.
/** #OnlyCurrentDoc */
function geral() {
filtro();
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('G2').activate();
spreadsheet.getCurrentCell().setFormula('=C2+D2');
spreadsheet.getActiveRange().autoFill(spreadsheet.getRange('G2:G92'), SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
var currentCell = spreadsheet.getCurrentCell();
spreadsheet.getSelection().getNextDataRange(SpreadsheetApp.Direction.DOWN).activate();
currentCell.activateAsCurrentCell();
spreadsheet.getRange('C2').activate();
spreadsheet.getRange('G2:G').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
spreadsheet.getRange('G:G').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
//adds the input OR output timestamp depending on the value in D column
//!!WORK IN PROGRESS!! --> here's where it gets tricky, and that's what I got so far (which doesn't work)
/*
for (var i = 2; i < 100; i++) {
spreadsheet.getRange('J2').setValue("TESTE");
var cell1 = spreadsheet.getRange('????').getValue(); //from this point on, I don't know how to proceed
var cell2 = spreadsheet.getRange('????').getValue();
spreadsheet.getRange('J2').setValue("TESTE2");
if(cell1 > cell2){
spreadsheet.getRange('????').activate();
spreadsheet.getActiveCell().setValue(new Date());
}
else if(cell1 < cell2){
spreadsheet.getRange('????').activate();
spreadsheet.getActiveCell().setValue(new Date());
}
}
*/
spreadsheet.getRange('D2:D').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
};
function filtro() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('D:D').activate();
spreadsheet.getActiveSheet().sort(4, false);
};
EDIT: With my review after #IrvingJayG.'s comment, I noticed a few mistakes and unnecessary extra steps, so instead of doing all the copy-paste-delete dance and then compare results, I'd go for the pseudocode below:
//Ci's value pre-exists in the sheet, where i is the row index
//manually input Di value
//set formula for Gi = Ci+Di
//and then compare either Ci and Gi, or Di and 0
if(Di > 0){
//the following steps can be defined as a new function for each case, (e.g. updateIn() and updateOut())
copy Gi to Ci;
update Ei with new Date();
delete Gi and Di;
}
else if(Di < 0){
copy Gi to Ci;
update Fi with new Date();
delete Gi and Di;
}
Unfortunately, it still doesn't solve my problem, just simplifies the code by a lot.
Sheet example
RECOMMENDATION:
I've created a sample sheet (based on your attached example sheet) with 6 rows of data and with 4 random sample cell values on Column D. Then, I've created a sample script below, where you can use a reference:
NOTE: This script will scan every row on your sheet that has data (e.g. if you have 30 rows of data, it will scan every row one-by-one until it reaches the 30th row) and may slow-down once you have bunch of data on it. That's the catch because it's an expected behavior
SAMPLE SHEET:
SCRIPT:
function onOpen() { //[OPTIONAL] Created a custom menu "Timestamp" on your Spreadsheet, where you can run the script
var ui = SpreadsheetApp.getUi();
ui.createMenu('Timestamp')
.addItem('Automate Timestamp', 'mainFunction')
.addToUi();
}
function mainFunction() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('D:D').activate();
spreadsheet.getActiveSheet().sort(4, false);
automateSheetCheck();
}
function automateSheetCheck(){
var d = new Date();
var formattedDate = Utilities.formatDate(d, "GMT", "MM/dd/yyyy HH:mm:ss");
var spreadsheet = SpreadsheetApp.getActive();
var currentRow = spreadsheet.getDataRange().getLastRow(); //Get the last row with value on your sheet data as a whole to only scan rows with values
for(var x =2; x<=currentRow; x++){ //Loop starts at row 2
if(spreadsheet.getRange("D"+x).getValue() == ""){ //Checks if D (row# or x) value is null
Logger.log("Cell D"+x+" is empty"); //Logs the result for review
}else{
var res = spreadsheet.getRange("C"+x).getValue() + spreadsheet.getRange("D"+x).getValue(); //SUM of C & D values
if(spreadsheet.getRange("D"+x).getValue() > 0){ // If D value is greater than 0, E cell is updated with new timestamp and then C value is replaced with res
Logger.log("Updated Timestamp on cell E"+x + " because D"+x+ " with value of "+ spreadsheet.getRange("D"+x).getValue() +" is greater than 0"); //Logs the result for review
spreadsheet.getRange("E"+x).setValue(formattedDate);
spreadsheet.getRange("C"+x).setValue(res); //Replace C value with "res"
spreadsheet.getRange("D"+x).setValue(""); //remove D value
}else{ // If D value is less than 0, F cell is updated with a new timestamp
Logger.log("Updated Timestamp on cell F"+x + " because D"+x+ " with value of "+ spreadsheet.getRange("D"+x).getValue() +" is less than 0"); //Logs the result for review
spreadsheet.getRange("F"+x).setValue(formattedDate);
spreadsheet.getRange("C"+x).setValue(res); //Replace C value with "res"
spreadsheet.getRange("D"+x).setValue(""); //remove D value
}
}
}
}
RESULT:
After running the script, the will be the result on the sample sheet:
Here's the Execution Logs, where that you can review what happened after running the code:
I'd like to be able to delete an entire row in a Google Spreadsheets if the value entered for say column "C" in that row is 0 or blank. Is there a simple script I could write to accomplish this?
Thanks!
I can suggest a simple solution without using a script !!
Lets say you want to delete rows with empty text in column C.
Sort the data (Data Menu -> Sort sheet by column C, A->Z) in the sheet w.r.t column C, so all your empty text rows will be available together.
Just select those rows all together and right-click -> delete rows.
Then you can re-sort your data according to the column you need.
Done.
function onEdit(e) {
//Logger.log(JSON.stringify(e));
//{"source":{},"range":{"rowStart":1,"rowEnd":1,"columnEnd":1,"columnStart":1},"value":"1","user":{"email":"","nickname":""},"authMode":{}}
try {
var ss = e.source; // Just pull the spreadsheet object from the one already being passed to onEdit
var s = ss.getActiveSheet();
// Conditions are by sheet and a single cell in a certain column
if (s.getName() == 'Sheet1' && // change to your own
e.range.columnStart == 3 && e.range.columnEnd == 3 && // only look at edits happening in col C which is 3
e.range.rowStart == e.range.rowEnd ) { // only look at single row edits which will equal a single cell
checkCellValue(e);
}
} catch (error) { Logger.log(error); }
};
function checkCellValue(e) {
if ( !e.value || e.value == 0) { // Delete if value is zero or empty
e.source.getActiveSheet().deleteRow(e.range.rowStart);
}
}
This only looks at the value from a single cell edit now and not the values in the whole sheet.
I wrote this script to do the same thing for one of my Google spreadsheets. I wanted to be able to run the script after all the data was in the spreadsheet so I have the script adding a menu option to run the script.
/**
* Deletes rows in the active spreadsheet that contain 0 or
* a blank valuein column "C".
* For more information on using the Spreadsheet API, see
* https://developers.google.com/apps-script/service_spreadsheet
*/
function readRows() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var rowsDeleted = 0;
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
if (row[2] == 0 || row[2] == '') {
sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
rowsDeleted++;
}
}
};
/**
* Adds a custom menu to the active spreadsheet, containing a single menu item
* for invoking the readRows() function specified above.
* The onOpen() function, when defined, is automatically invoked whenever the
* spreadsheet is opened.
* For more information on using the Spreadsheet API, see
* https://developers.google.com/apps-script/service_spreadsheet
*/
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{
name : "Remove rows where column C is 0 or blank",
functionName : "readRows"
}];
sheet.addMenu("Script Center Menu", entries);
};
Test spreadsheet before:
Running script from menu:
After running script:
I was having a few problems with scripts so my workaround was to use the "Filter" tool.
Select all spreadsheet data
Click filter tool icon (looks like wine glass)
Click the newly available filter icon in the first cell of the column you wish to search.
Select "Filter By Condition" > Set the conditions (I was using "Text Contains" > "word")
This will leave the rows that contain the word your searching for and they can be deleted by bulk selecting them while holding the shift key > right click > delete rows.
This is what I managed to make work. You can see that I looped backwards through the sheet so that as a row was deleted the next row wouldn't be skipped. I hope this helps somebody.
function UpdateLog() {
var returnSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('RetLog');
var rowCount = returnSheet.getLastRow();
for (i = rowCount; i > 0; i--) {
var rrCell = 'G' + i;
var cell = returnSheet.getRange(rrCell).getValue();
if (cell > 0 ){
logSheet.
returnSheet.deleteRow(i);
}
}
}
quite simple request. Try this :
function try_It(){
deleteRow(2); //// choose col = 2 for column C
}
function deleteRow(col){ // col is the index of the column to check for 0 or empty
var sh = SpreadsheetApp.getActiveSheet();
var data = sh.getDataRange().getValues();
var targetData = new Array();
for(n=0;n<data.length;++n){
if(data[n][col]!='' && data[n][col]!=0){ targetData.push(data[n])};
}
Logger.log(targetData);
sh.getDataRange().clear();
sh.getRange(1,1,targetData.length,targetData[0].length).setValues(targetData);
}
EDIT : re-reading the question I'm not sure if the question is asking for a 'live' on Edit function or a function (like this above) to apply after data has been entered... It's not very clear to me... so feel free to be more accurate if necessary ;)
There is a simpler way:
Use filtering to only show the rows which you want to delete. For example, my column based on which I want to delete rows had categories on them, A, B, C. Through the filtering interface I selected only A and B, which I wanted to delete.
Select all rows and delete them. Doing this, in my example, effectively selected all A and B rows and deleted them; now my spreadsheet does not show any rows.
Turn off the filter. This unhides my C rows. Done!
There is a short way to solve that instead of a script.
Select entire data > Go to menu > click Data tab > select create filter > click on filter next to column header > pop-up will appear then check values you want to delete > click okay and copy the filtered data to a different sheet > FINISH
reading your question carefully, I came up with this solution:
function onOpen() {
// get active spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
// create menu
var menu = [{name: "Evaluate Column C", functionName: "deleteRow"}];
// add to menu
ss.addMenu("Check", menu);
}
function deleteRow() {
// get active spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
// get active/selected row
var activeRow = ss.getActiveRange().getRowIndex();
// get content column C
var columnC = ss.getRange("C"+activeRow).getValue();
// evaluate whether content is blank or 0 (null)
if (columnC == '' || columnC == 0) {
ss.deleteRow(parseInt(activeRow));
}
}
This script will create a menu upon file load and will enable you to delete a row, based on those criteria set in column C, or not.
This simple code did the job for me!
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet(); // get active spreadsheet
var activeRow = ss.getActiveRange().getRowIndex(); // get active/selected row
var start=1;
var end=650;
var match='';
var match2=0; //Edit this according to your choice.
for (var i = start; i <= end; i++) {
var columnC = ss.getRange("C"+i).getValue();
if (columnC ==match || columnC ==match2){ ss.deleteRow(i); }
}
}
The below code was able to delete rows containing a date more than 50 days before today in a particular column G , move these row values to back up sheet and delete the rows from source sheet.
The code is better as it deletes the rows at one go rather than deleting one by one. Runs much faster.
It does not copy back values like some solutions suggested (by pushing into an array and copying back to sheet). If I follow that logic, I am losing formulas contained in these cells.
I run the function everyday in the night (scheduled) when no one is using the sheet.
function delete_old(){
//delete > 50 day old records and copy to backup
//run daily from owner login
var ss = SpreadsheetApp.getActiveSpreadsheet();
var bill = ss.getSheetByName("Allotted");
var backss = SpreadsheetApp.openById("..."); //backup spreadsheet
var bill2 = backss.getSheetByName("Allotted");
var today=new Date();
//process allotted sheet (bills)
bill.getRange(1, 1, bill.getMaxRows(), bill.getMaxColumns()).activate();
ss.getActiveRange().offset(1, 0, ss.getActiveRange().getNumRows() - 1).sort({column: 7, ascending: true});
var data = bill.getDataRange().getValues();
var delData = new Array();
for(n=data.length-1; n>1; n--){
if(data[n][6] !=="" && data[n][6] < today.getTime()-(50*24*3600*1000) ){ //change the condition as per your situation
delData.push(data[n]);
}//if
}//for
//get first and last row no to be deleted
for(n=1;n<data.length; n++){
if(data[n][6] !=="" && data[n][6] < today.getTime()-(50*24*3600*1000) ){
var strow=n+1 ; //first row
break
}//if
}//for
for(n=data.length-1; n>1; n--){
if(data[n][6] !=="" && data[n][6] < today.getTime()-(50*24*3600*1000) ){
var ltrow=n+1 ; //last row
break
}//if
}//for
var bill2lr=bill2.getLastRow();
bill2.getRange((bill2lr+1),1,delData.length,delData[0].length).setValues(delData);
bill.deleteRows(strow, 1+ltrow-strow);
bill.getRange(1, 1, bill.getMaxRows(), bill.getMaxColumns()).activate();
ss.getActiveRange().offset(1, 0, ss.getActiveRange().getNumRows() - 1).sort({column: 6, ascending: true}); //get back ordinal sorting order as per column F
}//function
I created an XSSFTable with below example code:
https://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateTable.java
One column in my XSSFTable is a formula that referencing to another column in this table.
For example, in XSSFTable TBL column ColumnA, the formula is: =[#[ColumnB]], I can set the formula on each cell in ColumnA via cell.setCellFormula("TBL[[#This Row],[ColumnB]]"), but it will have problem while opened in Excel and Excel has to remove the formula in order to display the worksheet correctly.
This problem only happened in creating blank new XSSFWorkbook, if it is loaded from an existing .xlsx file created by Excel, it is able to modify the formula via cell.setCellFormula() and able to open in Excel correctly.
If there are any sample code can work correctly in this situation?
Main problem with the linked example is that it names all columns equal "Column":
...
for(int i=0; i<3; i++) {
//Create column
column = columns.addNewTableColumn();
column.setName("Column");
column.setId(i+1);
...
So formula parser cannot difference between them.
But the whole logic of filling the table column headers and filling the sheet contents using one loop is not really comprehensible. So here is a more appropriate example:
public class CreateTable {
public static void main(String[] args) throws IOException {
Workbook wb = new XSSFWorkbook();
XSSFSheet sheet = (XSSFSheet) wb.createSheet();
//Create
XSSFTable table = sheet.createTable();
table.setDisplayName("Test");
CTTable cttable = table.getCTTable();
//Style configurations
CTTableStyleInfo style = cttable.addNewTableStyleInfo();
style.setName("TableStyleMedium2");
style.setShowColumnStripes(false);
style.setShowRowStripes(true);
//Set which area the table should be placed in
AreaReference reference = new AreaReference(new CellReference(0, 0),
new CellReference(4,2));
cttable.setRef(reference.formatAsString());
cttable.setId(1);
cttable.setName("Test");
cttable.setTotalsRowCount(1);
CTTableColumns columns = cttable.addNewTableColumns();
columns.setCount(3);
CTTableColumn column;
XSSFRow row;
XSSFCell cell;
//Create 3 columns in table
for(int i=0; i<3; i++) {
column = columns.addNewTableColumn();
column.setName("Column"+i);
column.setId(i+1);
}
//Create sheet contents
for(int i=0; i<5; i++) {//Create 5 rows
row = sheet.createRow(i);
for(int j=0; j<3; j++) {//Create 3 cells each row
cell = row.createCell(j);
if(i == 0) { //first row is for column headers
cell.setCellValue("Column"+j);
} else if(i<4){ //next rows except last row are data rows, last row is totals row so don't put something in
if (j<2) cell.setCellValue((i+1)*(j+1)); //two data columns
else cell.setCellFormula("Test[[#This Row],[Column0]]*Test[[#This Row],[Column1]]"); //one formula column
}
}
}
FileOutputStream fileOut = new FileOutputStream("ooxml-table.xlsx");
wb.write(fileOut);
fileOut.close();
wb.close();
}
}
I am using openxml to create an excel report. The openxml operates on a template excel file using named ranges.
The client requires a totals row at the end of the list of rows. Sounds like a reasonable request!!
However, the data table I'm returning from the db can contain any number of rows. Using template rows and 'InsertBeforeSelf', my totals row is getting overridden.
My question is, using openxml, how can I insert rows into the spreadsheet, causing the totals row to be be moved down each time a row is inserted?
Regards ...
Assuming you're using the SDK 2.0, I did something similiar by using this function:
private static Row CreateRow(Row refRow, SheetData sheetData)
{
uint rowIndex = refRow.RowIndex.Value;
uint newRowIndex;
var newRow = (Row)refRow.Clone();
/*IEnumerable<Row> rows = sheetData.Descendants<Row>().Where(r => r.RowIndex.Value >= rowIndex);
foreach (Row row in rows)
{
newRowIndex = System.Convert.ToUInt32(row.RowIndex.Value + 1);
foreach (Cell cell in row.Elements<Cell>())
{
string cellReference = cell.CellReference.Value;
cell.CellReference = new StringValue(cellReference.Replace(row.RowIndex.Value.ToString(), newRowIndex.ToString()));
}
row.RowIndex = new UInt32Value(newRowIndex);
}*/
sheetData.InsertBefore(newRow, refRow);
return newRow;
}
I'm not sure how you were doing it with InsertBeforeSelf before, so maybe this isn't much of an improvement, but this has worked for me. I was thinking you could just use your totals row as the reference row. (The commented out part is for if you had rows after your reference row that you wanted to maintain. I made some modifications, but it mostly comes from this thread: http://social.msdn.microsoft.com/Forums/en-US/oxmlsdk/thread/65c9ca1c-25d4-482d-8eb3-91a3512bb0ac)
Since it returns the new row, you can use that object then to edit the cell values with the data from the database. I hope this is at least somewhat helpful to anyone trying to do this...
[Can someone with more points please put this text as a comment for the M_R_H's Answer.]
The solution that M_R_H gave helped me, but introduces a new bug to the problem. If you use the given CreateRow method as-is, if any of the rows being moved/re-referenced have formulas the CalcChain.xml (in the package) will be broken.
I added the following code to the proposed CreateRow solution. It still doesn't fix the problem, because, I think this code is only fixing the currently-being-copied row reference:
if (cell.CellFormula != null) {
string cellFormula = cell.CellFormula.Text;
cell.CellFormula = new CellFormula(cellFormula.Replace(row.RowIndex.Value.ToString(), newRowIndex.ToString()));
}
What is the proper way to fix/update CalcChain.xml?
PS: SheetData can be gotten from your worksheet as:
worksheet.GetFirstChild<SheetData>();
You have to loop all rows and cells under the inserted row,change its rowindex and cellreference. I guess OpenXml not so smart that help you change index automatically.
static void InsertRow(string sheetName, WorkbookPart wbPart, uint rowIndex)
{
Sheet sheet = wbPart.Workbook.Descendants<Sheet>().Where((s) => s.Name == sheetName).FirstOrDefault();
if (sheet != null)
{
Worksheet ws = ((WorksheetPart)(wbPart.GetPartById(sheet.Id))).Worksheet;
SheetData sheetData = ws.WorksheetPart.Worksheet.GetFirstChild<SheetData>();
Row refRow = GetRow(sheetData, rowIndex);
++rowIndex;
Cell cell1 = new Cell() { CellReference = "A" + rowIndex };
CellValue cellValue1 = new CellValue();
cellValue1.Text = "";
cell1.Append(cellValue1);
Row newRow = new Row()
{
RowIndex = rowIndex
};
newRow.Append(cell1);
for (int i = (int)rowIndex; i <= sheetData.Elements<Row>().Count(); i++)
{
var row = sheetData.Elements<Row>().Where(r => r.RowIndex.Value == i).FirstOrDefault();
row.RowIndex++;
foreach (Cell c in row.Elements<Cell>())
{
string refer = c.CellReference.Value;
int num = Convert.ToInt32(Regex.Replace(refer, #"[^\d]*", ""));
num++;
string letters = Regex.Replace(refer, #"[^A-Z]*", "");
c.CellReference.Value = letters + num;
}
}
sheetData.InsertAfter(newRow, refRow);
//ws.Save();
}
}
static Row GetRow(SheetData wsData, UInt32 rowIndex)
{
var row = wsData.Elements<Row>().
Where(r => r.RowIndex.Value == rowIndex).FirstOrDefault();
if (row == null)
{
row = new Row();
row.RowIndex = rowIndex;
wsData.Append(row);
}
return row;
}
Above solution got from:How to insert the row in exisiting template in open xml. There is a clear explanation might help you a lot.