In the control properties, new row has name equals to Volume Row 62 and Row Index equals to 61 - as recorded and add values in few columns.
When I insert a new row with external data and fill the respective columns, it tries to override the column data in the row which was used in the recording and not the one that is being inserted.
If i remove the 62 and 61 from the Row Properties and make that general, it goes to the first row in the grid and tries to edit.
What properties should be changed or searched for so that columns is populated correctly in the the new row (whose name and row index is not known).
any help is appreciated.
Thanks.
To solve this in our application we exported the UI map method and created a temp list using VAR I don't know if this will work for you or not but solved several of our issues around dynamic grid rows and columns:
public void DoubleClickLaunch_UOW()
{
var temp = this.UIWindow.UIUnitGridTable.GetChildren().ToList();
temp.RemoveAt(0);
var rows = temp.Select(t => t.GetChildren().Select(s => s.GetValue()).ToList()).ToList();
var tractLetters = rows.Select(s => s[1]).ToList();
var index = tractLetters.IndexOf(DoubleClickLaunch_UOWParams.UITESTUNIT_TPText);
if (index >= 0)
{
var textbox = temp[index].GetChildren()[1].GetChildren()[0];
Mouse.DoubleClick(textbox);
}
else
{
Mouse.DoubleClick(this.UIWindow.UIUnitGridTable.UIItemRow.UIUnitNameCell.UITESTUNIT_TPText);
}
Related
A looking for a way to get specific columns by name from several tables. My data comes in several sheets with different number of columns upto 38 columns so i cannot use getColumnById. I only need 7 columns from this.
First am converting all sheet ranges to tables, then am getting all tables.
What I want is to get specific columns by names and merge all into one table on a new sheet.
I followed example from Docs but am stuck at getting column name for each Table.
I know my header Values, shown in example below.
function main(workbook: ExcelScript.Workbook) {
let sheets = workbook.getWorksheets();
for (let sheet of sheets) {
sheet.getTables()[0].convertToRange();
sheet.addTable(sheet.getRange('A1').getUsedRange().getAddress(),true)
}
workbook.getWorksheet('Combined')?.delete();
const newSheet = workbook.addWorksheet('Combined');
const tables = workbook.getTables();
const headerValues = [['Column1', 'Column6', 'Column8', 'Column9','Column11', 'Column16', 'Column18', 'Column19']];
const targetRange = newSheet.getRange('A1').getResizedRange(headerValues.length - 1, headerValues[0].length - 1);
targetRange.setValues(headerValues);
const combinedTable = newSheet.addTable(targetRange.getAddress(), true);
for (let table of tables) {
let dataValues = table.getColumnByName( // this where am stuck //).getRangeBetweenHeaderAndTotal().getTexts();
let rowCount = table.getRowCount();
// If the table is not empty, add its rows to the combined table.
if (rowCount > 0) {
combinedTable.addRows(-1, dataValues);
}
}
}
Thanks for your help.
George
A few things:
In most circumstances for this scenario, I'd recommend iterating
through a specific set of table objects. Unfortunately, that's
difficult to do here. Every time you unlink and recreate a new table,
Excel may give your table a new name. That makes it difficult to
work with the table. You can get around this in your code by
capturing the table name before you unlink it, unlinking the table,
recreating the table, and setting the table name to the original one
captured. If you go that route then you could reliably work with the
table names
Because table names in this scenario can be a bit tricky, I'm going
to use the sheet names so that I can work with the sheets that contain
the underlying tables. This will allow us to use and get data from the
tables regardless of what they're named in the sheets.
Please see my code below:
function main(workbook: ExcelScript.Workbook) {
//JSON object called SheetAndColumnNames. On the left hand side is the sheet name.
//On the right hand side is an array with the column names for the table in the sheet.
//NOTE: replace the sheet and column names with your own values
let columnNames : string[] = ["ColA","ColB","ColC"]
const sheetAndColumnNames = {
"Sheet1": columnNames,
"Sheet2": columnNames
}
//JSON object called columnNamesAndCellValues. On the left hand side is the column name.
//On the right hand side is an array that will hold the values for the column in the table.
//NOTE: replace these column names with your own values
const columnNamesAndCellValues = {
"ColA": [],
"ColB": [],
"ColC": []
}
//Iterate through the sheetAndColumnNames object
for (let sheetName in sheetAndColumnNames) {
//Use sheet name from JSON object to get sheet
let sheet: ExcelScript.Worksheet = workbook.getWorksheet(sheetName)
//get table from the previously assigned sheet
let table: ExcelScript.Table = sheet.getTables()[0]
//get array of column names to be iterated on the sheet
let tableColumnNames: string[] = sheetAndColumnNames[sheetName]
//Iterate the array of table column names
tableColumnNames.forEach(columnName=> {
//get the dataBodyRange of the tableColumn
let tableColumn : ExcelScript.Range = table.getColumn(columnName).getRangeBetweenHeaderAndTotal()
//iterate through all of the values in the table column and add them to the columnNamesAndCellValues array for that column name
tableColumn.getValues().forEach(value=>{
columnNamesAndCellValues[columnName].push(value)
})
})
}
//Delete previous worksheet named Combined
workbook.getWorksheet("Combined")?.delete()
//Add new worksheet named Combined and assign to combinedSheet variable
let combinedSheet : ExcelScript.Worksheet = workbook.addWorksheet("Combined")
//Activate the combined sheet
combinedSheet.activate()
//get the header range for the table
let headerRange : ExcelScript.Range = combinedSheet.getRangeByIndexes(0,0,1,columnNames.length)
//set the header range to the column headers
headerRange.setValues([columnNames])
//iterate through the arrays returned by the columnNamesAndCellValues object to write to the Combined sheet
columnNames.forEach((column,index)=>{
combinedSheet.getRangeByIndexes(1, index, columnNamesAndCellValues[column].length, 1).setValues(columnNamesAndCellValues[column])
})
//Get the address for the current region of the data written from the tableColumnData array to the sheet
let combinedTableAddress : string = combinedSheet.getRange("A1").getSurroundingRegion().getAddress()
//Add the table to the sheet using the address and setting the hasHeaders boolean value to true
combinedSheet.addTable(combinedTableAddress,true)
}
I have data which users submit in columns. I am trying to convert them from columnar into stacked rows so a database can read them as single columns, rather than having to pull in X columns to capture the data.
You can see in the Columnar Example screenshot where I am presently, and in the Stacked Example where I want to be.
I can do this in either Google Sheets using App Script - load the data as columnar then convert to stacked and move to BigQuery - OR - use Google Cloud Storage to load the columnar data then use Node to convert to stacked when moving to BigQuery.
Either way, this needs to get into BigQuery as the Stacked Example.
Any ideas on how to do this?
The function below does the following:
Get all data from the sheet where your original data is located (called Source, please change accordingly) with getDataRange.
Remove the headers from the retrieved array and append them to your destination sheet (called Target) with shift, slice and appendRow.
Iterate through the rest of rows with a forEach and, for each row, iterate through each successive group of four columns with a for loop, appending (1) the first for columns of each row and (2) each successive group of four columns in a new row in your destination sheet.
function myFunction() {
var ss = SpreadsheetApp.getActive();
var sourceSheet = ss.getSheetByName('Source'); // Change accordingly
var targetSheet = ss.getSheetByName('Target'); // Change accordingly
targetSheet.clearContents(); // Removes all old content from target sheet before appending new data (remove this if you don't want that)
var sourceValues = sourceSheet.getDataRange().getValues();
var numCols = 4; // Number of desired columns in destination spreadsheet
var headers = sourceValues.shift().slice(0, numCols * 2);
targetSheet.appendRow(headers); // Remove if the destination sheet already has headers
sourceValues.forEach(function(row) { // Iterate through each row in source sheet
for (var i = numCols; i < row.length; i += numCols) { // Iterate through each group of four columns (excluding first four) in each row
var part1 = row.slice(0, numCols); // First four columns
var part2 = row.slice(i, i + numCols); // Each successive group of four
var targetRow = part1.concat(part2); // Concatenate the four first columns with each group of four
targetSheet.appendRow(targetRow); // Append row (8 columns)
}
});
}
I have an Excel file where I want to group the columns based on multiple columns in C#. I am using EPPlus and have followed this link (Selecting grouped max and min in a Epplus worksheet with Linq), but it shows only the group by based on one column. I am stuck on extending it to group by multiple coulmns, let's say here Group and Date (Column A and Column B).
So, the following worked for me where I have grouped by based on first three columns of the Excel file:
var rowcellgroups = skus.Cells["A:G"].GroupBy(c => c.Start.Row);
var group = rowcellgroups.Skip(2).GroupBy(x => new { FirstKey = x.ElementAt(0).Value, SecondKey = x.ElementAt(1).Value, ThirdKey = x.ElementAt(2).Value }); //starts with 0
I have an excel file which gets updated on a daily basis i.e the data is always different every time.
I am pulling the data from the Excel sheet into the table using Talend. I have a primary key Company_ID defined in the table.
The error I am facing is that the Excel sheet has few duplicate Company_ID values. It will also pick up more duplicate values in the future as the Excel file will be updated daily.
I want to choose the first record where the Company ID field is 1 and the record doesn't have null in the rest of the columns. Also, for a Company_ID of 3 there is a null value for one column which is ok since it is a unique record for that company_id.
How do I choose a unique row which has maximum no. of column values present ie for eg in the case of Company ID of 1 in Talend ?
tUniqRow is usually the easiest way to handle duplicates.
If you are worried that the first row coming to tUniqRow may not be the first row that you want there, you can sort your rows, so they enter tUniqRow in your preferred order:
(used components: tFileInputExcel, tJavaRow, tSortRow, tUniqRow, tFilterColumns)
In your particular case, the tJava could look like this:
// Code generated according to input schema and output schema
output_row.company_id = input_row.company_id;
output_row.name = input_row.name;
output_row.et_cetera = input_row.et_cetera;
// End of pre-generated code
int i = 0;
if (input_row.company_id == null) { i++; }
if (input_row.name == null) { i++; }
if (input_row.et_cetera == null) { i++; }
output_row.priority = i;
eg:-
var Rows = (from row in dt1.AsEnumerable()
orderby row["Amount"] descending
select row);
if table like this
RegId Name
101 jone
102 Raj
103 guru
i want output like this using c# DataTable
RegId Name
103 jone
102 Raj
101 guru
i want sort only the regid column rows
So you want to order one column but keep the rest of the column in their old order? Strange requirement, are the columns not related to each other?
However, following code will select the desired column and order it descending. Then the DataTable will be updated with the new values of this column:
List<int> amountsOrdered = dt1.AsEnumerable()
.Select(r => r.Field<int>("Amount"))
.OrderByDescending(i => i)
.ToList();
for (int i = 0; i < dt1.Rows.Count; i++)
dt1.Rows[i].SetField("Amount", amountsOrdered[i]);
Note that the Field extension method is strongly typed what is a good thing. But it can cause an exception if your column's type is string. Then you first need to Parse it to int anyway.
var regIds = dt1.AsEnumerable()
.Cast<DataRow>()
.Select(r => (int)r["Amount"])
.OrderByDescending(id => id)
.ToArray();
for(int i=0; i < dt1.Rows.Count; i++)
{
DataRow row = dt1.Rows[i];
row["Amount"] = regIds[i];
}
Make sure you disable the constraints (if any) on the uniqueness of Amount column of your data table. More info in the documentation page.
if you can use dataview, then you can simple use dataview.sort = "expression"
otherwise i think there is no default option to sort data table, other than looping