Move Columns Based on Array of Column Numbers - google-apps-script

I have an array of columns that I want to keep. I've got that code below:
//Keep only columns user wants.
if(keepColumnsArray != ""){
for (var col = sourceShtLC; col > 0; col--) {
if (keepColumnsArray.indexOf(col) == -1) {
// This isn't a keeper, delete it
destSht.deleteColumn(col);
}
}
}
What I'd like to do now is arrange the columns following the order the keepColumnsArray has them.
Samples:
var keepColumnsArray = [3,2,1,4,5]
Using the above sample I want column 3 to be the first column, column 2 to be the second, column 1 to be the 3rd, column 4 to be the 4th and column 5 to be the 5th.
Current Order:
The order I want it. As you can see it's the same order the array is in.
Solution:
Rather than deleting the columns first I used code from the accepted answer to move the columns I want to keep to the front. In this case Columns 1 through 5 I kept and then I deleted the rest because all that was left were columns I did not need. Here is my final code.
//Use order of array to reorder columns and then delete the rest of the columns
var offset = keepColumnsArray.length;
destSht.insertColumns(1, offset);
keepColumnsArray.forEach(function(e, i) {
destSht.getRange(1, (e + offset), destSht.getLastRow(), 1).copyTo(destSht.getRange(1, i + 1));
});
destSht.deleteColumns(offset + 1, sourceShtLC); //Keep only columns user wants.

You want to arrange the columns on the sheet with var keepColumnsArray = [3,2,1,4,5].
For example, you want to arrange from the columns 1, 2, 3, 4, 5 to 3, 2, 1, 4, 5.
You want to achieve this using Google Apps Script.
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
Pattern 1:
In this case, moveColumns is used. The flow of this script is as follows.
Create an array object including the original index and destination index of the columns.
Sort the array.
The columns are arranged using moveColumns.
Sample script:
function myFunction() {
var keepColumnsArray = [3,2,1,4,5];
var obj = keepColumnsArray.reduce(function(ar, e, i) {
ar.push({from: i + 1, to: e});
return ar;
}, []);
obj.sort(function(a, b) {return a.to < b.to ? -1 : 1});
var sheet = SpreadsheetApp.getActiveSheet();
obj.forEach(function(o) {
var columnSpec = sheet.getRange(1, o.from);
if (o.from != o.to) sheet.moveColumns(columnSpec, o.to);
for (var j = 0; j < obj.length; j++) {
if (obj[j].from < o.from) obj[j].from += 1;
}
});
}
Pattern 2:
In this case, each column is copied with the order of keepColumnsArray using a temporal sheet, and put the arranged columns to the original sheet.
Sample script:
function myFunction() {
var keepColumnsArray = [3,2,1,4,5];
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var temp = ss.insertSheet("temp");
sheet.activate();
keepColumnsArray.forEach(function(e, i) {
sheet.getRange(1, e, sheet.getLastRow(), 1).copyTo(temp.getRange(1, i + 1));
});
temp.getDataRange().copyTo(sheet.getRange(1, 1));
ss.deleteSheet(temp);
}
Reference:
moveColumns(columnSpec, destinationIndex)
Added:
From OP's comment, In this sample script, the columns are inserted and put the arranged columns.
Instead of creating a temp sheet can we not add 5 columns to the beginning and then copy them to those new columns?
Sample script:
function myFunction() {
var keepColumnsArray = [3,2,1,4,5];
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var offset = keepColumnsArray.length;
sheet.insertColumns(1, offset);
keepColumnsArray.forEach(function(e, i) {
sheet.getRange(1, e + offset, sheet.getLastRow(), 1).copyTo(sheet.getRange(1, i + 1));
});
sheet.deleteColumns(offset, offset);
}

Problem
Filtering out columns by criteria
Reordering columns by criteria
Solution
First, add logic that filters and sorts your values. One of the possible algorithms is as follows: map source such that each row is mapped such that each cell is cell by order index from source and filter columns such that its index is a keep index.
var input = [3,2,1,4,5];
var initial = [
['Column1','Column2','Column3','Column4','Column5','Column6','Column7'],
['2first','2second','2third','2fourth','2fifth','2sixth','2seventh'],
];
function filterAndReorder (source,order) {
return source
.map(function(row,r){
return row.map(function(cell,c){
return source[r][order[c]-1];
})
.filter(function(cell,c){
return cell !== undefined;
});
})
}
var output = filterAndReorder(initial,input);
console.log(output);
Then, use the fact that setValues() accepts 2D Array and replaces Range contents:
var lrow = destSht.getLastRow();
var range = destSht.getRange(1,1,lrow,5);
var inputVals = range.getValues();
var keepColumnsArray = []; //obtain the keep Array somehow;
var outputVals = filterAndReorder(inputVals,keepColumnsArray);
var range.setValues(outputVals);
Notes
keepColumnsArray is an Array so the != "" is redundant (unless you actually expect it to be an empty string in which case I would suggest rewriting the logic that outputs the Array - it will save you at least 1 op + save you debug time in the future).
As a general rule of thumb, please, avoid using I/O as much as possible (especially in a loop) and keep input close to start of the logic and output to the end. deleteColumn is an I/O and thus should at least be performed in batch.
UPD if you reorder is partial (that is, there are columns unchanged), you can fold the resulting empty columns via deleteColumns()
References
filter() method ref on MDN
map() method ref on MDN

Related

Exception: The number of columns in the data does not match the number of columns in the range. The data has 0 but the range has 1

I am very new to javascript and have searched around a ton for this and can't seem to find the issue with my code. I am attempting to simply write a code that will copy the values in a column from a pivot table sheet in Google Sheet and then paste the values in another sheet. However, before pasting the values, I want each individual value to be duplicated 12 times (for 12 months). So, assuming I have 10 unique values (A, B, C, D, E, F, G, H, I, J) that I am copying, I want to return value A 12 times in a row, then value B 12 times in a row, etc.
I run getValues, which seems to put the values in a 2 dimensional array. I've then taken this temp_array that I had created and used a for loop to duplicate each value 12 times in a new array.
However, when I setValues, I am pasting the values in my spreadsheet correctly, but I get this error message regardless (The number of columns in the data does not match the number of columns in the range. The data has 0 but the range has 1.), any ideas why?
Here is a small example of what my input could look like (1st image) and what I would want the output to look like (2nd image)
function test2() {
// activating current spreadsheet for use
var spreadsheet = SpreadsheetApp.getActive();
//empty array
var array_dept_temp = [];
// returns cell position (ex: C5) of the last row of the pivot table 1 sheet that has content in column 1
var last_row = spreadsheet.getSheetByName("Pivot Table 1").getRange("A:A").getNextDataCell(SpreadsheetApp.Direction.DOWN).getRowIndex();
//subtracting 1 from last row because we are excluding the headers. This gives us our row_length
var row_length = last_row - 1
var array_dept = [[]]
array_dept = new Array(row_length*12)
//new Array(row_length*12);
// Get value in pivot table 1 from range of row 2 (dept name, but exclude the header), column 1, all the way to last row
// Then paste it in sheet5 from row 1, column 3, all the way to the last row defined above
array_dept_temp = spreadsheet.getSheetByName("Pivot Table 1").getRange(2,1, last_row).getValues();
for (var i = 1; i < row_length; i++ )
{
//get value and then paste it in a destination
array_dept.fill(array_dept_temp[i-1], (-12 + (12*i)) , 12*i);
}
var destination_dept = spreadsheet.getSheetByName("Sheet5").getRange(2,3,row_length*12);
destination_dept.setValues(array_dept);
}
Suggestion / Alternate solution:
Try:
function test() {
  var spreadsheet = SpreadsheetApp.getActive();
  var sheet = spreadsheet.getSheetByName("Pivot Table 1");
  var array_dept_temp = sheet.getRange(2,1, sheet.getLastRow()-1).getValues();
  var array_dept = [];
  for (var i = 0; i < array_dept_temp.length; i++) {
    array_dept = [...array_dept, ...Array.apply(null, Array(12)).map(function(){return array_dept_temp[i]})]
  }
  var destination_dept = spreadsheet.getSheetByName("Sheet5").getRange(2,3,array_dept.length);
  destination_dept.setValues(array_dept);
}
Result:
Another way without using fill or from.
Also some modification, you can just use .getLastRow() function to get the last row, however take not that if there is data below it will count all the rows including the blank until the row that has data. And you may also use .length on your data to setValue.
From your showing sample input and output situations, how about the following modified script?
Modified script:
function test2_sample() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var srcSheet = ss.getSheetByName("Pivot Table 1");
var dstSheet = ss.getSheetByName("Sheet5");
var srcValues = srcSheet.getRange("A2:A" + srcSheet.getLastRow()).getValues();
var dstValues = srcValues.flatMap(a => Array(12).fill(a));
dstSheet.getRange(2, 3, dstValues.length).setValues(dstValues);
}
When this script is run using your sample input sheet, I think that your expected output values are obtained.
Now, I thought that var dstValues = srcValues.flatMap(([a]) => Array(12).fill(a).map(e => [e])); can be modified to var dstValues = srcValues.flatMap(a => Array(12).fill(a));. This is simpler.
From your reply of Are you able to explain what this does? var dstValues = srcValues.flatMap(([a]) => Array(12).fill(a).map(e => [e]));, in this script, var dstValues = srcValues.flatMap(([a]) => Array(12).fill(a).map(e => [e])); can be also modified as follows. I thought that this might also help to understand it.
function test2_sample() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var srcSheet = ss.getSheetByName("Pivot Table 1");
var dstSheet = ss.getSheetByName("Sheet5");
var srcValues = srcSheet.getRange("A2:A" + srcSheet.getLastRow()).getValues();
var dstValues = [];
for (var i = 0; i < srcValues.length; i++) {
dstValues = dstValues.concat(Array(12).fill(srcValues[i]));
}
dstSheet.getRange(2, 3, dstValues.length).setValues(dstValues);
}
Note:
As additional information, when your showing script is modified, how about the following modification? In your script, I thought that it is required to add the values to array_dept in the loop. And, it is required to flatten the elements in the array.
function test2() {
var spreadsheet = SpreadsheetApp.getActive();
var array_dept_temp = [];
var last_row = spreadsheet.getSheetByName("Pivot Table 1").getRange("A:A").getNextDataCell(SpreadsheetApp.Direction.DOWN).getRowIndex();
var row_length = last_row - 1
var array_dept = []
array_dept_temp = spreadsheet.getSheetByName("Pivot Table 1").getRange(2, 1, last_row).getValues();
for (var i = 0; i < row_length; i++) {
array_dept = [...array_dept, ...Array(12).fill(array_dept_temp[i])];
}
var destination_dept = spreadsheet.getSheetByName("Sheet5").getRange(2, 3, array_dept.length);
destination_dept.setValues(array_dept);
}
Reference:
flatMap()

Google Sheets - How can I find the first row number containing specific text, and then clear/delete all content to end?

I'm currently importing a bunch of data and then splitting it into multiple columns and then attempting to clear or delete any erroneous rows (it's a raw data import that contains a bunch of scrap rows).
So far I've got the data imported, split, & sorted. Now I'm trying to find the row number, based on a value in column A, and then select all rows to the end of the sheet to either delete or clear the content.
I'm to the point where all of my data has been split into the columns I need (A:J) and sorted so that all relevant data is at the top (it's a variable data set) so now I'm just trying to find the first row that contains "----------------------" as this will be my first 'garbage' row.
outputrange.setValues(output);
pull1.deleteRows(1, 40);
pull1.getRange(2, 1, pull1.getLastRow()-1,
pull1.getLastColumn()).activate().sort({column:2, ascending: true});
var removalValues = range.getValues()
for (var j=0; j<removalValues.length; j++) {
var rowArray = removalValues[j];
for (var k=0; k<rowArray.length; k++) {
var columnValue = rowArray[k];
if (rowArray[0] === "----------------------") {
var rowNumber = i;
pull1.getRange(rowNumber, 1, 1, pull1.getLastColumn()).activate()
}
}
}
I've attempted the code above to loop through and find the correct cell reference, and just temporarily highlight the row so I make sure it's functioning correctly. Currently this part of my code processes but otherwise doesn't do anything. Really I just need something that will look through my data in column A and find the matching data, then return the row number for me so that I can apply it to other formulas.
Edit: I updated my code using some additional resources and came up with the following. It seems to work correctly but I'm not sure if it's the most efficient solution:
var outputrange = pull1.getRange(startRow, 1, LR-startRow+1, 10)
outputrange.setValues(output);
pull1.deleteRows(1, 40);
pull1.getRange(2, 1, pull1.getLastRow()-1,
pull1.getLastColumn()).activate().sort({column:2, ascending: true});
var rangeData = pull1.getDataRange();
var lastColumn = rangeData.getLastColumn();
var lastRow = rangeData.getLastRow();
var searchRange = pull1.getRange(1,1,lastRow-1,lastColumn-1);
var removalValues = searchRange.getValues();
for (j=0; j < lastColumn-1; j++) {
for (k=0; k < lastRow-1; k++) {
if(removalValues[k][j] === "----------------------") {
pull1.getRange(k+1, 1, pull1.getLastRow(), 10).deleteCells(SpreadsheetApp.Dimension.ROWS);
}
}
}
Requirement:
Find specified text then delete all rows below said text.
Solution:
Use textFinder to find the text then pass the result row to deleteRows().
function findAndClear() {
var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lastRow = sh.getLastRow() + 1;
var range = sh.getRange(1, 1, lastRow);
//find specified text and return row number
var row = range.createTextFinder('----------------------').findNext().getRow();
//calculate number of rows to delete
var delRows = lastRow - row;
//delete rows
sh.deleteRows(row, delRows);
}
Explanation:
First of all, sorry but I've scrapped the script you were using. There's no need to get all of the values in the column then loop through each one, it's over-complicated and slow.
Using textFinder is much quicker, no looping through arrays, just finding the first occurrence of your string in column A and getting the row number.
Notes:
If you did want to keep the row containing your string, use:
sh.deleteRows(row + 1, delRows);
References:
textFinder Documentation

What is the most efficient way to clear row if ALL cells have a value with Apps Script?

I'm trying to come up with a function that will clear contents (not delete row) if all cells in a range have values. The script below isn't functioning as expected, and I would really appreciate any help/advice you all have. It's currently only clearing out a single line, and doesn't appear to be iterating over the whole dataset. My thought was to iterate over the rows, and check each cell individually. If each of the variables has a value, clear that range and go to the next row.
Here's a link to a sample Google Sheet, with data and the script in Script Editor.
function MassRDDChange() {
// Google Sheet Record Details
var ss = SpreadsheetApp.openById('1bcrEZo3IkXiKeyD47C_k2LIRy9N9M6SI2h2MGK1Cj-w');
var dataSheet = ss.getSheetByName('Data Entry');
// Initial Sheet Values
var newLastColumn = dataSheet.getLastColumn();
var newLastRow = dataSheet.getLastRow();
var dataToProcess = dataSheet.getRange(2, 1, newLastRow, newLastColumn).getValues().filter(function(row) {
return row[0]
}).sort();
var dLen = dataToProcess.length;
// Clear intiial sheet
for (var i = 0; i < dLen; ++i) {
var row = 2;
var orderNumber = dataToProcess[i][0].toString();
var rdd = dataToProcess[i][1].toString();
var submittedBy = dataToProcess[i][2].toString();
var submittedOn = dataToProcess[i][3].toString();
if (orderNumber && rdd && submittedBy && submittedOn) {
dataSheet.getRange(row, 1, 1, newLastColumn).clear();
row++;
} else {
row++; // Go to the next row
continue;
}
}
}
Thanks!
Since you don't want to delete the rows, just clear() them, and they're all on the same worksheet tab, this is a great use case for RangeLists, which allow you to apply specific Range methods to non-contiguous Ranges. Currently, the only way to create a RangeList is from a an array of reference notations (i.e. a RangeList is different than an array of Range objects), so the first goal we have is to prefix our JavaScript array of sheet data to inspect with a usable reference string. We could write a function to convert array indices from 0-base integers to A1 notation, but R1C1 referencing is perfectly valid to pass to the RangeList constructor, so we just need to account for header rows and the 0-base vs 1-base indexing difference.
The strategy, then, is to:
Batch-read sheet data into a JavaScript Array
Label each element of the array (i.e. each row) with an R1C1 string that identifies the location where this element came from.
Filter the sheet data array based on the contents of each element
Keep elements where each sub-element (the column values in that row) converts to a boolean (i.e., does not have the same value as an empty cell)
Feed the labels of each of the kept rows to the RangeList constructor
Use RangeList methods on the RangeList
Because this approach uses only 3 Spreadsheet calls (besides the initial setup for a batch read), vs 1 per row to clear, it should be considerably faster.
function clearFullyFilledRows() {
// Helper function that counts the number of populated elements of the input array.
function _countValues(row) {
return row.reduce(function (acc, val) {
var hasValue = !!(val || val === false || val === 0); // Coerce to boolean
return acc + hasValue; // true == 1, false == 0
}, 0);
}
const sheet = SpreadsheetApp.getActiveSheet();
const numHeaderRows = 1,
numRows = sheet.getLastRow() - numHeaderRows;
const startCol = 1,
numCols = sheet.getLastColumn();
// Read all non-header sheet values into a JavaScript array.
const values = sheet.getSheetValues(1 + numHeaderRows, startCol, numRows, numCols);
// From these values, return a new array where each row is the origin
// label and the count of elements in the original row with values.
const labeledCounts = values.map(function(row, index) {
var rNc = "R" + (numHeaderRows + 1 + index) + "C";
return [
rNc + startCol + ":" + rNc + (startCol + numCols - 1),
_countValues(row)
];
});
// Filter out any row that is missing a value.
const toClear = labeledCounts.filter(function (row) { return row[1] === numCols; });
// Create a RangeList from the first index of each row (the R1C1 label):
const rangeList = sheet.getRangeList(toClear.map(function (row) { return row[0]; }));
// Clear them all:
rangeList.clear();
}
Note that because these cleared rows are possibly disjoint, your resulting sheet may be littered with rows having data, and rows not having data. A call to sheet.sort(1) would sort all the non-frozen rows in the sheet, moving the newly-empty rows to the bottom (yes, you can programmatically set frozen rows). Depending how this sheet is referenced elsewhere, that may not be desirable though.
Additional references:
Array#filter
Array#reduce
Array#map
JavaScript Logical Operators
JavaScript Comparison Operators

converting nonadjacent columns to proper/title case in Google Sheets

I found something online and it works for changing text to title case; however, it only works on adjacent columns and I need to apply this to multiple nonadjacent columns. I will paste in the script. If you can give a fix to being able to take care of letting the script run on multiple nonadjacent columns that I specify, that would be great. I found some stuff online that says it can do that, but it is not clear to me.
Here is the script that works:
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var range = sheet.getRange("A_range");
range.activate();
var values = range.getValues();
if (values.map) {
range.setValues(values.map(function(row) {
return row.map(titleCase);
}));
}
else {
range.setValue(titleCase(values));
}
}
function titleCase(str) {
return str.toString().split(/\b/).map(function(word) {
return word ? word.charAt(0).toUpperCase() + word.slice(1).toLowerCase() : '';
}).join('');
}
This was from other people on this concept:
The stuff to make it run on other columns is this:
var range1=sheet.getRange("A1:A19").getValues();
var range2=sheet.getRange("C1:C19").getValues();
var range=[],i=-1;
while ( range1[++i] ) {
range.push( [ range1[i][0], range2[i][0] ] );
}
where range will have content from both columns.
data = sheet.getRange("A1:C19").getValues();
for (i = 0; i < data[0].length; i++) {
// do something with data[0][i]
// do something with data[2][i]
}
I am not sure how to implement these 2 other ideas listed above. If you could be really specific, like actually put something into the first script that lets it run on Col. A and Col. D,for example, it would be much better than generalities, as I am really really new to this and have spent an enormous amount of time trying to learn it/get a handle on it. Thanks!
Because making as few calls as possible to the SpreadsheetApp API is better for speed, i'd prefer to simply take a Range of all the cells between the first and the last column, apply the transformation to selected columns and then write the whole lot back again. The only place to edit then if the columns change is a single pattern array.
var columnPattern = [1,5,6,7] // Equivalent to [A,E,F,G]
The script then runs a simple map over the two-dimensional array representing the sheet.
function transform() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
// Rows (Could be first row and last row, OP isn't clear.
var startRow = 1, endRow = sheet.getLastRow();
// An array with Column indexes for those you want in Title Case.
var columnPattern = [1,5,6,7];
var firstColumn = parseInt(columnPattern.slice(0,1));
var lastColumn = parseInt(columnPattern.slice(-1));
// The whole range
var range = sheet.getRange(startRow,
firstColumn,
endRow,
lastColumn - firstColumn)
// Apply Title Case to selected columns.
var data = range.getValues().map(function(row, i, rows) {
row = row.map(function(col, j, row) {
if(columnPattern.indexOf(j + firstColumn) >= 0) {
col = titleCase(col);
}
return col;
});
return row;
});
range.setValues(data);
}
The only point I'd perhaps clarify is the line where it identifies the columns to amend.
if(columnPattern.indexOf(j + firstColumn) >= 0) {
This just corrects for the columnPattern array not being the same dimension as your sheet. An alternative would be to have an array that did match the x-dimension with boolean values, but this would be less adaptable to your sheet changing size.
I'd resist putting this in an onEdit() function but it depends on your use case as to how often data changed.

How can I store a range of cells to an array?

If I have a list of data in cells A1:A150 (but the amount can vary), is there a way to push that into an array without looking at each cell individually to determine if it is empty? I exceed my execution time by doing this and I need a faster way to store the data and stop when it hits an empty cell.
Below is how I currently do it:
for (var i = 1; i < 500; i++) {
if(datasheet.getRange("A" + i).getValue() == ""){
break;
}
else{
addedlist_old.push(datasheet.getRange("A" + i).getValue())
}
If you're using only one column, I'd suggest:
// my2DArrayFromRng = sh.getRange("A2:A10").getValues();
var my2DArrayFromRng = [["A2"],["A3"],["A4"],["A5"],[],[],["A8"],["A9"],[]];
var a = my2DArrayFromRng.join().split(',').filter(Boolean);
The methods .join() and .split(',') together convert the 2D array to a plain array (["A2","A3","A4","A5",,,"A8","A9",]).
Then the method .filter(Boolean) strips the empty elements. The code above returns [A2, A3, A4, A5, A8, A9].
Try this:
var sheet = SpreadsheetApp.openById(SHEET_ID).getSheetByName(SHEET_NAME);
var lastRow = sheet.getLastRow();
var data = sheet.getRange(1, 1, lastRow, 1).getValues(); //getRange(starting Row, starting column, number of rows, number of columns)
for(var i=0;i<(lastRow-1);i++)
{
Logger.log(data[0][i]);
}
the variable data stores all the cells of column A.
Cell A1 is stored in data[0][0], cell A2 is stored in data[0][1], cell A3 is stored in data[0][2] and so on.
The getRange(starting Row, starting column, number of rows, number of columns) is a batch operation so it is much faster when you have a large dataset.
If you don't have empty cells in between it's actually pretty easy.
var lastRow = sheet.getLastRow();
var array = sheet.getRange('A1:A' + lastRow).getValues();
If you need to weed out empty entries after that, you can use a for statement, or to be faster, filter like an earlier answer shows.
var filteredArray = array.filter(function(n){ return n != '' });
The main difference between this answer and the one posted earlier that I mentioned is that getValues() will give you an array.
I've tested this and it works in google apps script, and it does not time out when I use the array, or even when I put in large amounts of data (I tested it with an array that has about 20-50 characters per entry and about 500 entries). Just make sure to define the var sheet or put in your own variable.
Try this:
It will allow you to select any column on the sheet.
var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
function onOpen() {
ui.createMenu('Sheet Functions')
.addItem('Get values from column', 'getVals')
.addToUi();
}
function getVals() {
var sheet = ss.getActiveSheet();
var getColumnLetter = ui.prompt('Select column..' , 'Enter the letter of the target column..', ui.ButtonSet.OK_CANCEL);
if(getColumnLetter.getSelectedButton() == ui.Button.CANCEL) {
return } else {
getColumnLetter = getColumnLetter.getResponseText().toUpperCase();
}
var columnNo = getColumnLetter.charCodeAt(0) - 64;
try { var data = sheet.getRange(1, columnNo, sheet.getMaxRows()).getValues().filter(String); } catch (e) { ui.alert('Invalid input please try again.', ui.ButtonSet.OK); return;}
/*
*
* Do what ever you need to do down here
*
*/
}