Formula to import multiple columns to 1 column if a name from a different list matches any name in those columns - google-sheets

Looking for a way to import a long range of columns in to 1 list if a name from a different list matches any name in that particular column. I've tried a couple variations of query, filter, vlookup... Can't seem to find the right combination. Example..
List A on sheet 1 contains the names Jim, John and James. On a separate sheet, there are 5 columns containing names. Column 1 contains Jim, Alex and Ben. Column 2 contains Harold, Bob and Jimmy. Column 3 contains James, Jeremy and Felix. Column 4 contains James, Eric and Evan. Column 5 contains Sara, Jamie and Xavier. The end result should display the list in 1 column to contain the names - Jim, John, James, Alex, Ben, Jeremy, Felix, Eric and Evan. Columns 1, 3 and 4 would be imported to a single list because at least 1 name within those columns matched a name in the original list.
Example sheet.

UPDATED
You can try this sample implementation below using Apps Script custom function. Just copy and paste it to your spreadsheet file as a bound script:
NOTE: This script will check each name listed on the "Main List" & if each of them has matches on multiple columns on the second sheet Sheet2, then it will place all of the names on columns that contains any matched name on the "Imported List". The only catch using this implementation is that it'll run a bit slow when there's a huge amount of data to be processed.
SCRIPT
function onOpen(){ //Runs every time you open the spreadsheet
FINDMATCH();
}
function onEdit(){//Runs every time you make an edit to the sheet
FINDMATCH();
}
function FINDMATCH() { //Function to check each columns on "Sheet2" to see if it has names that match any names on the "Main List"
var main = SpreadsheetApp.getActive().getSheetByName("Sheet1");
var mainList = [].concat.apply([], main.getRange("A4:A").getValues()).filter(String); //Main list data starts at A4
var sheet2 = SpreadsheetApp.getActive().getSheetByName("Sheet2"); //Name of the Sheet2
var result = mainList;
for(col=1; col <= sheet2.getDataRange().getLastColumn(); col++){
// E.G. if you only want to set the maximum of 2 rows as seen below, the "currentCol" code will only scan range A1:F3 on Sheet2 because the number 3 on the third parameter of the getRange() method will be the maximum row to be scanned.
var currentCol = [].concat.apply([], sheet2.getRange(1,col,2,1).getValues()).filter(String);
mainList.forEach(function(list){
currentCol.forEach(function(data){
if(data == list){
result.push(currentCol.toString());
return;
}
});
});
}
var data = FILTER(result.toString().trim().split(","));
main.getRange("AG4:AG").clearContent(); //Clears the old "Imported List" data before pasting updated list of names
main.getRange(4,33,data.length,1).setValues(data); //Updates the "Imported List"
}
function FILTER(array) { //Function that filters duplicate names
var data = array;
var newData = [];
var formattedData = [];
for (var i in data) {
var row = data[i];
var duplicate = false;
for (var j in newData) {
if (row === newData[j] && row === newData[j]) {
duplicate = true;
}
}
if (!duplicate) {
newData.push(row);
}
}
newData.forEach(function(i){
formattedData.push([i]);
});
return formattedData;
}
Sample Result:
Sample Sheet
When spreadsheet gets updated with new data

Related

Google Sheets: Group rows and columns into cells by an ID

I have a table of tasks where rows are grouped using ID's. I want to represent these groupings in another table where there is one row for each ID and all data rows and columns are grouped for each ID in a single cell. I need a formula that can group certain rows into a cell using newlines, and certain columns into cells using delimiters. My data source is something like this:
The formula needs to:
Filter rows by Condition.
Put Task ID's in their own column, one row for each individual ID.
Put all data in Hours, Mins, Customer and Description columns into a cell next to ID so that:
Hours and Mins are joined with a ":" as a delimiter to represent time values
Customer and Description values are then concatenated to time values using space as a delimiter.
The result should look like:
A Google Sheet containing example of the source table and desired result:
https://docs.google.com/spreadsheets/d/14p_HYpfb7XlWhRRgo3JN7SPRerwEaB2A7Dz1KWuBgL8/edit#gid=299935838
SUGGESTION:
You can try this custom formula GROUPDATA using the script below. Just add it as a bound script on your spreadsheet file:
Script:
function GROUPDATA(data) {
var temp = "";
var filtered = [];
var container = [];
var col2 =[];
var final = [];
data.forEach(function(data) {
if(data[0] == true){
filtered.push(data[1])
container.push([data[1],data[2]+":"+data[3]+" "+data[4]+" "+data[5]])
}
});
const unique = (value,index,self) =>
{return self.indexOf(value) ===index;}
var unique_list=filtered.filter(unique);
for(i=0; i<unique_list.length; i++){
container.forEach(function(x) {
if(x[0]== unique_list[i]){
temp = temp+ x[1]+"\n";
}
});
col2.push(temp);
temp = "";
}
for(y=0; y<unique_list.length; y++){
final.push([unique_list[y],col2[y]]);
}
return final;
}
DEMONSTRATION:
Used the custom formula =GROUPDATA(A:F) on cell G14

Best way to compare 2 colums in google sheets and then email mismatched data

I have a Google sheet that is the answer sheet to a form sent to students for registration purposes. A= Timestamp B= Email address of student c= Students answer D= All emails of invited students What i need to achieve is column B to check if the email exists in column D and if so move the cell to column E. If it moves it would leave a gap so I would need it to move and then move cells up by 1. I can then import the cells into another sheet to see only the students who have not replied or is there a way to email those automatically.
Your assistance would be greatly appreciated
https://docs.google.com/spreadsheets/d/1XfyKP5EbxoGYOiWgPiRWA_OvPGN9hOjICXp_iuJrwIg/edit?usp=sharing
You want to do the following:
Remove values from column D that also exist in column B (shift up values so that no blank cells are kept).
Send emails to the resulting column D values.
If that's the case, you can do the following with Apps Script: create a bound script by selecting Tools > Script editor and copy and execute the following code (check inline comments):
function sendEmailsToNonRespondents() {
var ss = SpreadsheetApp.getActive(); // Get spreadsheet
var sheetName = "Sheet1"; // Your sheet name (change if necessary)
var sheet = ss.getSheetByName(sheetName); // Get sheet
var allAddresses = getColumnValues(sheet, 2, 4); // Get non-empty values from column D (excluding row 1)
var respondents = getColumnValues(sheet, 2, 2); // Get non-empty values from column B (excluding row 1)
var nonRespondents = allAddresses.filter(address => !respondents.includes(address)).map(address => [address]); // Retrieve list of emails of non-respondents
sheet.getRange("D2:D").clearContent(); // Clear old column D content (excluding row 1)
sheet.getRange(2, 4, nonRespondents.length, 1).setValues(nonRespondents); // Write new column D content (non-respondents)
nonRespondents.forEach(email => {
var subject = "Mail subject"; // Change according to your preferences
var body = "Mail body"; // Change according to your preferences
MailApp.sendEmail(email[0], subject, body); // Send email for each non-respondent
});
}
function getColumnValues(sheet, firstRow, colIndex) {
return sheet.getRange(firstRow, colIndex, sheet.getLastRow() - firstRow + 1, 1).getValues().filter(value => value[0] != "").map(value => value[0]);
}
Note:
In this sample, no data is moved to column E (I don't see why that's necessary, since the respondent emails are recorded in column B anyway).
In this sample, every time the script runs, all content in column D gets removed, and the filtered content is written again, instead of just removing the undesired values.
Reference:
Spreadsheet Service
MailApp.sendEmail(recipient, subject, body)

Should this be a SUMIF formula?

I'm trying to make a formula that can recognize in Column A the name Brooke B for instance here, from there I'd like to SUM the values listed in Column I Cash Discounts for that specific user.
(Yes this user has no Cash Discounts, thus column I states "Non-Cash Payment").
There's about 80 users total here, so I'd prefer to automate the name recognition in Column A.
Sheet: https://docs.google.com/spreadsheets/d/1xzzHT7VjG24UJ4ZXaiZWsfzroTpn7jCJLexuTOf6SQs/edit?usp=sharing
Desired Results listed in Cash Discounts sheet, listed per user in column C.
You are trying to calculate the total amount of the Cash Discount per person given to people in a list. You have data that has been exported from a POS system to which that you have added a formula to calculate the amout of the discount on a line by line basis. You have speculated whether the discount totals could be calculated using SUMIFS formulae.
In my view, the layout of the spreadsheet and the format of the POS report do not lend themselves to isolating discrete data elements though Google sheets functions (though, no doubt, someone with greater skills than I will disprove this theory). Column A, containing names, also includes sub-groupings (and their sub-totals) as well as transaction dates. There are 83 unique persons and over 31,900 transaction lines.
This answer is a script-based solution which updates a sheet with the names and values of the discount totals. The elapsed execution time is #11 seconds.
function so5882893202() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// get the Discounts sheet
var discsheetname = "Discounts";
var disc = ss.getSheetByName(discsheetname);
//get the Discounts data
var discStartrow = 3;
var discLR = disc.getLastRow();
var discRange = disc.getRange(discStartrow, 1, discLR-discStartrow+1, 9);
var discValues = discRange.getValues();
// isolate Column A
var discnameCol = discValues.map(function(e){return e[0];});//[[e],[e],[e]]=>[e,e,e]
//Logger.log(discnameCol); // DEBUG
// isolate Column I
var discDiscounts = discValues.map(function(e){return e[8];});//[[e],[e],[e]]=>[e,e,e]
//Logger.log(discDiscounts); // DEBUG
// create an array to build a names list
var names =[]
// get the number of rows on the Discounts sheet
var discNumrows = discLR-discStartrow+1;
// Logger.log("DEBUG: number of rows = "+discNumrows);
// identify search terms
var searchPercent = "%";
var searchTotal = "Total";
// loop through Column A
for (var i=0; i<discNumrows; i++){
//Logger.log("DEBUG: i="+i+", content = "+discnameCol[i]);
// test if value is a date
if (Object.prototype.toString.call(discnameCol[i]) != "[object Date]") {
//Logger.log("it isn't a date")
// test whether the value contains a % sign
if ( discnameCol[i].indexOf(searchPercent) === -1){
//Logger.log("it doesn't have a % character in the content");
// test whether the value contains the word Total
if ( discnameCol[i].indexOf(searchTotal) === -1){
//Logger.log("it doesn't have the word total in the content");
// test whether the value is a blank
if (discnameCol[i] != ""){
//Logger.log("it isn't empty");
// this is a name; add it to the list
names.push(discnameCol[i])
}// end test for empty
}// end test for Total
} // end for percentage
} // end test for date
}// end for
//Logger.log(names);
// get the number of names
var numnames = names.length;
//Logger.log("DEBUG: number of names = "+numnames)
// create an array for the discount details
var discounts=[];
// loop through the names
for (var i=0;i<numnames;i++){
// Logger.log("DEBUG: name = "+names[i]);
// get the first row and last rows for this name
var startrow = discnameCol.indexOf(names[i]);
var endrow = discnameCol.lastIndexOf(names[i]+" Total:");
var x = 0;
var value = 0;
// Logger.log("name = "+names[i]+", start row ="+ startrow+", end row = "+endrow);
// loop through the Cash Discounts Column (Column I) for this name
// from the start row to the end row
for (var r = startrow; r<endrow;r++){
// get the vaue of the cell
value = discDiscounts[r];
// test that it is a value
if (!isNaN(value)){
// increment x by the value
x = +x+value;
// Logger.log("DEBUG: r = "+r+", value = "+value+", x = "+x);
}
}
// push the name and the total discount onto the array
discounts.push([names[i],x]);
}
//Logger.log(discounts)
// get the reporting sheet
var reportsheet = "Sheet10";
var report = ss.getSheetByName(reportsheet);
// define the range (allow row 1 for headers)
var reportRange = report.getRange(2,1,numnames,2);
// clear any existing content
reportRange.clearContent();
//update the values
reportRange.setValues(discounts);
}
Report Sheet - extract
Not everyone wants a script solution to their problem. This answer seeks to supply a repeatable solution using common garden-variety formula/functions.
As noted elsewhere, the layout of the spreadsheet does not lend itself to a quick/simple solution, but it IS possible to break down the data to compile a non-script answer. Though it may "seem" as though the following formula are less than "simple, when taken one-at-a-time they are logical, very easy to create, and very easy to verify successful outcomes.
Note: It is important to know at the outset that the first row of data = row#3, and the last row of data = row#31916.
Step#1 - get Text values from ColumnA
Enter this formula in Cell J3, and copy to row 31916
=if(isdate(A3),"",A3):
evaluates Column A, if the content is a date, returns blank, otherwise, returns the context
Taking Customer "AJ" as an example, the content at this point includes:
AJ
10% BuildingDiscount
10% BuildingDiscount Total:
Northwestern 10%
Northwestern 10% Total:
AJ Total:
Step#2 - ignore the values that contain "10%" (this removes both headings and sub-subtotals
Enter this formula in Cell K3 and copy to row 31916
=iferror(if(search("10%",J3)>0,"",J3),J3): searches for "10%" in Column J. Returns all values except those that containing "10%".
Taking Customer "AJ" as an example, the content at this point includes:
AJ
AJ Total:
**Step#3 - ignore the values that contain the word "Total"
Enter this formula in Cell L3 and copy to row 31916.
=iferror(if(search("total",K3)>0,"",K3),K3)
Taking Customer "AJ" as an example, the content at this point includes:
AJ
Results after Step#3
You might wonder, "couldn't this be done in a single formula?" and/or "an array formula would be more efficent". Both those thoughts are true, but we're looking at simple and easy, and a single formula is NOT simple (as shown below); and given that, an array formula is out-of-the-question unless/until an expert can wave a magic wand over the data.
FWIW - Combining Steps#1, 2 & 3
each of the Steps#1, 2 and 3 build on each other. So it is possible to create a single formula that combines these steps.
enter this formula in Cell J3, and copy dow to row #31916.
=iferror(if(search("total",iferror(if(search("10%",if(isdate(A3),"",A3))>0,"",if(isdate(A3),"",A3)),if(isdate(A3),"",A3)))>0,"",iferror(if(search("10%",if(isdate(A3),"",A3))>0,"",if(isdate(A3),"",A3)),if(isdate(A3),"",A3))),iferror(if(search("10%",if(isdate(A3),"",A3))>0,"",if(isdate(A3),"",A3)),if(isdate(A3),"",A3)))
As the image showed, step#3 concludes with mainly empty cells in Column L; the only populated cell is the first instance of the customer name at the start of their transactions - such as "Alec" in this example. However (props to #Rubén) it is possible to populate the blank transaction Cells in Column L. An arrayformula to find the previous non-empty cell in another column on Webapps explains how.
Step#4 - Create a customer name for each transaction row.
Enter this formula in Cell M3, it will automatically populate the cells to row#31916
=ArrayFormula(vlookup(ROW(3:31916),{IF(LEN(L3:L31916)>0,ROW(3:31916),""),L3:L31916},2))
Step#5 - Get the discount amount for each transaction value
The discount values are already displayed in Column I. They are interspersed with text values, so the formula for tests if this is a total line by testing the value in Column D; only if there is a vale (Product item) does the formula then test of there is a value in column I.
Enter this formula in Cell N3, it will automatically populate the cells to row#31916
=ArrayFormula(if(len(D3:D31914)>0,if(ISNUMBER(I3:I31916),I3:I31916,0),""))
Screenshot after step#5
Reporting by Query
Reporting is done via queries. These can go anywhere, but it is probably more convenient to put it on a separate sheet.
Step#6.1 - query the results to create report showing total by ALL customers
=query(Discounts_analysis!$M$2:$N$31916,"select M, sum(N) where N is not null group by M label M 'Customer', sum(N) 'Total Discount' ",1)
Step#6.2 - query the results to create report showing total by customer where the customer received a discount
=query(Discounts_analysis!$M$2:$N$31916,"select M, sum(N) where N >0 group by M label M 'Customer', sum(N) 'Total Discount' ",1)
Step#6.3 - query the results to create report showing customers with no discount
- `=query(query(Discounts_analysis!$M$2:$N$31916,"select M, sum(N) where N is not null group by M label M 'Customer', sum(N) 'Total Discount' ",1),"select Col1 where Col2=0")`
Queries screenshot

How to transpose some rows to columns?

There were a lot of questions with transpose but I have some specifics and can't create the right formula.
So I have near 100k rows in the following format
https://docs.google.com/spreadsheets/d/146-6YHv69DDOnPKheKeRFZIQeZYIgO6UwCMd7X9VeKU/edit?usp=sharing
I need ARRAYFORMULA or something like that to make this 100k rows in the format that you can see on the "Expected Outcome" tab.
=ARRAYFORMULA({UNIQUE(INDIRECT("source!A2:A"&COUNTA(source!A2:A))),
QUERY(SPLIT(TRANSPOSE(SPLIT(QUERY("♦"&INDEX(SPLIT(TRANSPOSE(SPLIT(
TRIM(QUERY(TRANSPOSE(QUERY(TRANSPOSE(
IF(source!B2:J<>"", "♦"&source!A2:A&"♠"&{"♥"&source!B2:B, source!C2:J}, ))
,,999^99)),,999^99)), "♦")), "♠"),,2),,999^99), "♥")), "♦"),
"where Col2 is not null", 0)})
You have a vast number of records but there are 19 data fields to each record spread over 10 columns & 12 rows. You suggested an arrayformula (and much more clever people than I can probably do that), but I suggest a script which takes the data in its current form on one sheet (say the 'source'), and which outputs the data to a new sheet (say, the 'target').
There are a couple of issues to be addressed in "mapping" the data:
how many records are represented on the input sheet - required to enable looping. I used the Javascript Math.floor method to calculate the number of products.
identify the correct row/column combination for each field. The data is in three segments
8 fields in contiguous columns in the first row,
2 fields in 2 rows in the ninth column, and
9 fields in nine contiguous rows in the tenth column.
Total = 12 rows/10 columns. To do this, in order to navigate the rows, I took the counter (i) multiplied by the number of rows, plus 1; the columns are more intuitive.
for efficiency,
get data once only at the beginning of the script;
use arrays to progressively build the output; and
update the output (setValues) once at the end of the script.
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourcesheetname = "source";
var targetsheetname = "target";
var source = ss.getSheetByName(sourcesheetname);
var target = ss.getSheetByName(targetsheetname);
var sourcerange = source.getDataRange();
var sourcedata = sourcerange.getValues();
var sourceheaders = 1;
var rowsperproduct = 12;
var sourcelr = source.getLastRow();
var integerPart = Math.floor((sourcelr-sourceheaders)/rowsperproduct);
//Logger.log("DEBUG: number of products = "+integerPart);
var rowdata = [];
// look thought the number of products
for (var i = 0; i<integerPart; i++){
// use a temporary array to build the data for the row.
var temp = [];
// row 1, copy first eight columns (0-7)
temp.push(sourcedata[(i*12)+1][0]);//ID
temp.push(sourcedata[(i*12)+1][1]);//GID
temp.push(sourcedata[(i*12)+1][2]);//NAME
temp.push(sourcedata[(i*12)+1][3]);//PRICE
temp.push(sourcedata[(i*12)+1][4]);//BRAND
temp.push(sourcedata[(i*12)+1][5]);//URL
temp.push(sourcedata[(i*12)+1][6]);//country
temp.push(sourcedata[(i*12)+1][7]);//instock
// row 2 & 3 in Column I(8)
temp.push(sourcedata[(i*12)+2][8]);//url1
temp.push(sourcedata[(i*12)+3][8]);//url2
// rows 4 - 12 in Column J(9)
temp.push(sourcedata[(i*12)+4][9]);// tech name
temp.push(sourcedata[(i*12)+5][9]);// size
temp.push(sourcedata[(i*12)+6][9]);// inches
temp.push(sourcedata[(i*12)+7][9]);// mm
temp.push(sourcedata[(i*12)+8][9]);// depth
temp.push(sourcedata[(i*12)+9][9]);// BB
temp.push(sourcedata[(i*12)+10][9]);// ref1
temp.push(sourcedata[(i*12)+11][9]);// ref2
temp.push(sourcedata[(i*12)+12][9]);// ref3
// Update the rowdata for this row
rowdata.push(temp);
}
// update data to target
target.getRange(2,1,integerPart,19).setValues(rowdata);
}

Generate string like Q,R,S...AB where AB is last column in Google Sheet

I have a complex Google Sheet query that works great except when a Google Sheet doesn't have as many columns as I use in my formula.
Here's what the formula looks like now:
=sum(filter(query(INDIRECT("'" & A2 & "'!$A$7:$23"),"select Q,R,S,T,U,V,W,X,Y,Z,AA,AB,AC,AD,AE,AF,AG,AH where B='"&C2&"'",0),query(INDIRECT("'" & A2 & "'!$A$7:$23"),"select Q,R,S,T,U,V,W,X,Y,Z,AA,AB,AC,AD,AE,AF,AG,AH where B='PROJECT'",0) >=date(2017,1,1),query(INDIRECT("'" & A2 & "'!$A$7:$23"),"select Q,R,S,T,U,V,W,X,Y,Z,AA,AB,AC,AD,AE,AF,AG,AH where B='PROJECT'",0) <=date(2017,12,31)))
It works great. But the problem is I run it against many worksheets and some don't have e.g. column AG,AH and end at AF at which point I get an error.
So what I need is a way to generate the string Q,R,S....[Name of Last Column in Sheet] and then I can use that instead of my hard-coded Q,R,S,T,U,V,W,X,Y,Z,AA,AB,AC,AD,AE,AF,AG,AH but I cannot figure out how to do that.
Any help is greatly appreciated. Thanks!
Per comments above, final formula was:
LEFT("Q,R,S,T,U,V,W,X,Y,Z,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,A‌​L,AM,AN,AO,AP,AQ,AR,‌​AS,AT,AU,AV,AW,AX,AY‌​,AZ,BA,BB,BC ",2*Columns(INDIRECT(A2&"!1:1"))-33+IF(Columns(INDIRECT(A2&"‌​!1:1"))>26,Columns(I‌​NDIRECT(A2&"!1:1"))-‌​26,0))
where column A contains the list of worksheets (tabs) in the Google Sheet. Put this in B2, and then copied it down. I am not marking this as the correct answer since others gave a correct formula-based answer but this did the trick for me.
This can be done with built-in functions:
On a helper sheet, let say you name it, helper, fill up range with letters A to Z, let say A1:A26
Let say that on B1 you write the following formula:
=ArrayFormula({A1:A26;TRANSPOSE(SPLIT(JOIN(",",SUBSTITUTE(QUERY(TRANSPOSE(A1:A26)&A1:A26,,27)," ",",")),","))}) . This will create a list of column letter headers.
On each new worksheet use columns(1:1) to get the total number of columns.
To get your string of column headers, then you could use something like :
JOIN(",",OFFSET(helper!B1,16,0,columns(1:1)-16))
QUERY(helper!B:B,"select B limit "&columns(1:1)-7&" offset 7")
NOTE:
If you decide to have only one helper sheet and use it on several spreadsheets, then use
QUERY(IMPORTRANGE(your_url,"helper!B:B"),"select Col1 limit "&columns(1:1)-7&" offset 7")
This can be done with script. Without seeing you spreadsheet, it is hard to know exactly what you need, but this should be close. I get the variables from Sheet1 and return the formula to Sheet1. Adjust the sheet name to fit your needs. This will look at your data sheets based on the variable sheet name determine the last column. Determine the column letters and build the string the query needs. It then sets the new query formula. I added a menu to run it from.
function onOpen() {
SpreadsheetApp.getActiveSpreadsheet().addMenu(
'Create Data', [
{ name: 'Run', functionName: 'formula' },
]);
}
function formula(){
var ss= SpreadsheetApp.getActiveSpreadsheet()
var s=ss.getSheetByName("Sheet1") //sheet where variables are
var sheet=s.getRange("A2").getValue()//variable sheet name
var sel=makeString(sheet) //get the select string of column letters
//Create formula and return to Sheet1 A3
var f= s.getRange("A3").setFormula('=sum(filter(query(INDIRECT("\'" & A2 & "\'!$A$7:$23"),"select '+sel+' where B=\'"&C2&"\'",0),query(INDIRECT("\'" & A2 & "\'!$A$7:$23"),"select '+sel+' where B=\'PROJECT\'",0) >=date(2017,1,1),query(INDIRECT("\'" & A2 & "\'!$A$7:$23"),"select '+sel+' where B=\'PROJECT\'",0) <=date(2017,12,31)))')
}
function makeString(sht){
var ss= SpreadsheetApp.getActiveSpreadsheet()
var s=ss.getSheetByName(sht)
var lc=s.getLastColumn()
var rng=s.getRange(1, 17, 1, lc).getValues()
var str=''
var ltr=[]
for(var i=17;i<rng[0].length+1;i++){
ltr[i]= columnToLetter(i)
str=ltr.join(',')
}
var str1=str.substr(17)
return str1
}
function columnToLetter(column)
{
var temp, letter = '';
while (column > 0)
{
temp = (column - 1) % 26;
letter = String.fromCharCode(temp + 65) + letter;
column = (column - temp - 1) / 26;
}
return letter;
}
Let me know if you have any questions.

Resources