I have a function that returned a list of unique names in a spreadsheet column. I was looking for a way that I could make the check not case sensitive without forcing everything lowercase. Here is my original code:
function testGetUniqueClassNames(){
var sheet = getRosterSheet();
var dataRange = sheet.getDataRange();
var indices = returnIndices();
dataRange = dataRange.getValues();
var classNames = getUniqueClassNames(dataRange, indices.clsNameIndex, indices.crfIdIndex);
Logger.log(classNames);
}
function getUniqueClassNames(dataRange, clsNameIndex, crfIdIndex) {
var classNames = [];
for (var i=2; i<dataRange.length; i++) {
var thisClassName = dataRange[i][clsNameIndex];
var thisClassRoot = dataRange[i][crfIdIndex];
if ((classNames.indexOf(thisClassName)==-1)&&(thisClassName!='')&&(thisClassRoot!='')) {
classNames.push(thisClassName);
}
}
classNames.sort();
return classNames;
}
To solve this I created a second lowercase array to check against, but used the original one in the return.
function testGetUniqueClassNames(){
var sheet = getRosterSheet();
var dataRange = sheet.getDataRange();
var indices = returnIndices();
dataRange = dataRange.getValues();
var classNames = getUniqueClassNames(dataRange, indices.clsNameIndex, indices.crfIdIndex);
Logger.log(classNames);
}
function getUniqueClassNames(dataRange, clsNameIndex, crfIdIndex) {
var classNames = [];
var classNamesLC = [];
for (var i=2; i<dataRange.length; i++) {
var thisClassName = dataRange[i][clsNameIndex];
var thisClassNameLC = thisClassName.toLowerCase();
var thisClassRoot = dataRange[i][crfIdIndex];
if ((classNamesLC.indexOf(thisClassNameLC)==-1)&&(thisClassName!='')&&(thisClassRoot!='')) {
classNames.push(thisClassName);
classNamesLC.push(thisClassNameLC);
}
}
classNames.sort();
return classNames;
}
Related
Hello so I am trying to get values from the 'book' sheet then copy it to 'Completed' sheet. It takes the values form book stores it in the data array and copy them to the 'Completed' sheet. Its working fine but very slow which jeopardizes my work in time-wise. How can I make this run faster ?
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var clear_sheet = spreadsheet.getSheetByName('Completed_Orders'); // clear the destination sheet first
clear_sheet.getRange('A2:X').clear();
var sheet = spreadsheet.getSheetByName('book'); //source sheet
var Datarange = sheet.getRange('Q3:Q'); //range to check
var Datavalue = (Datarange.getValues());
var dest = spreadsheet.getSheetByName('Completed_Orders'); //destination sheet
var data = [];
for (i=0; i<Datavalue.length;i++) {
if ( Datavalue[i] == "Completed") {
data.push.apply(data,sheet.getRange(i+3,1,1,24).getValues());
}
}
dest.getRange(2,1,data.length,data[0].length).setValues(data);
var column = dest.getRange('A3:A');
var values = column.getValues(); // get all data in one call
var ct = 0;
while ( values[ct][0] != "" ) { // to find the last row correctly, getLastRow is not working perfectly
ct++;
}
var endRow = ct+2;
}
Try this:
Don't use this syntax var values=sheet.getRange('A3:A').getValues() because it get's the data all the way down to getMaxRows(). Instead use var values=sheet.getRange(3,1,sheet.getLastRow()-2,1).getValues().
Also Datavalue[i] is a whole row
function myfunction() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var clear_sheet = spreadsheet.getSheetByName('Completed_Orders');
clear_sheet.getRange(2,1,clear_sheet.getLastRow()-1,24).clear();
var sheet = spreadsheet.getSheetByName('book'); //source sheet
var Datarange = sheet.getRange(3,17,sheet.getLastRow()-2,1); //range to check
var Datavalue = Datarange.getValues();
var dest = spreadsheet.getSheetByName('Completed_Orders'); //destination sheet
var data = [];
for (var i=0;i<Datavalue.length;i++) {
if (Datavalue[i]["************You need another index here**************"] == "Completed") { //need another index Datavalue is 2d
data.push(sheet.getRange(i+3,1,1,24).getValues());
}
}
dest.getRange(2,1,data.length,data[0].length).setValues(data);
}
I think this version will be a lot faster.
function myfunction() {
var ss=SpreadsheetApp.getActiveSpreadsheet();
var ssh=ss.getSheetByName('book');
var dsh=ss.getSheetByName('Completed_Orders');
dsh.getRange(2,1,dsh.getLastRow()-1,24).clear();
var dv=ssh.getRange(3,1,ssh.getLastRow()-2,24).getValues();//this version just gets this data one time so it should a lot faster.
var data=[];
for (var i=0;i<dv.length;i++) {
if (dv[i][16]=="Completed") {
data.push(dv[i]);
}
}
dsh.getRange(2,1,data.length,data[0].length).setValues(data);
}
I have some data containing, Dates, Usernames and an average percent that i want to save in a certain way. My problem is that the order of the usernames can change depending on if new ones are added. I therefore need to "find" a specific username and then save the percentage data in the correct column.
I have found some code that partially helps me save the data that i need. But i could use some help in the "find" the corresponding username and save it in a certain Column part.
function save() {
var sss = SpreadsheetApp.getActive();
var ss = sss.getSheetByName('Result');
var range = ss.getRange('B1:B10');
var data = range.getValues();
var tss = SpreadsheetApp.getActive();
var ts = tss.getSheetByName('Archive');
ts.getRange(ts.getLastRow()+1, 1,data[0].length,data.length)
.setValues(Object.keys(data[0]).map ( function (columnNumber) {
return data.map( function (row) {
return row[columnNumber];
});
}));
}
Basically from this:
To a result that looks like this:
Thank you for your assistance.
Alright for anyone out there that may have a similar problem, this is what i ended up with.
function extractAttendance() {
var currentSheet = SpreadsheetApp.getActive();
var attendanceTab = currentSheet.getSheetByName('Data_Filtered');
var userData = attendanceTab.getRange('B1:B').getValues();
var percentageData = attendanceTab.getRange('I1:I').getValues();
var archiveTab = currentSheet.getSheetByName('Archive');
var existingUsersRow = archiveTab.getRange('1:1');
var newRowNumber = archiveTab.getLastRow() + 1;
archiveTab.getRange(newRowNumber, 1).setValue(new Date());
for (var i = 1; i < userData.length; i++) {
var user = userData[i][0];
if (user === '') {
continue;
}
var existingUsers = existingUsersRow.getValues()[0];
var exists = false;
var existingColumnNumber = -1;
for (var j = 0; j < existingUsers.length; j++) {
if (existingUsers[j] === user) {
exists = true;
existingColumnNumber = j + 1;
break;
}
}
if (exists) {
archiveTab.getRange(newRowNumber, existingColumnNumber).setValue(percentageData[i]);
} else {
var newColumnNumber = archiveTab.getLastColumn() + 1;
archiveTab.getRange(1, newColumnNumber).setValue(user);
archiveTab.getRange(newRowNumber, newColumnNumber).setValue(percentageData[i]);
}
}
}
It might be easier to implement your desired functionality through looping rather than through mapping.
The following code retrieves all users ad their percentage data in ‘Result’ and transfers the data (in the format you desire) to "Archive" with the percentages data pasted with the corresponding timestamp into the first empty row.
function save() {
var sss = SpreadsheetApp.getActive();
var ss = sss.getSheetByName('Result');
var range = ss.getRange('B1:B');
var percentageRange = ss.getRange('G1:G');
var userData = range.getValues();
var percentageData = percentageRange.getValues();
var tss = SpreadsheetApp.getActive();
var ts = tss.getSheetByName('Archive');
var userRow=1;
var percentageRow=(ts.getLastRow()+1)
for(var i=0; i<=userData.length; i++)
{
{
var j=(i+2);
ts.getRange(userRow, j).setValue(userData[i])
ts.getRange(percentageRow, 1).setValue(new Date())
ts.getRange(percentageRow, j).setValue(percentageData[i])
}
}
}
Very new to this, I am trying to Find and Replace on row1 only
I want to find aa and replace it with ZZZ
I am trying two different ways but neither work
Thanks
first way:
function replace3() {
var sheet = SpreadsheetApp.getActiveSheet();
var lc = sheet.getMaxColumns();
var range = sheet.getRange("a1:z1");
var values = range.getValues();
for (var col in values[1]) {
if (values[0][col] ='aa') {
values[0][col] = 'ZZZ';
}
}
range.setValues(values);
}
Second Way:
function replace2() {
var sheet = SpreadsheetApp.getActiveSheet();
var lc = sheet.getMaxColumns();
var range = sheetname.getRange(1, 1, 1, lc);
var values = range.getValues();
for (var i = 0; i <= lc; i++) {
if (values[0][i] ='aa') {
values[0][i] = 'ZZZ';
}
}
range.setValues(values);
}
How about the following modofications?
For replace3()
The index of array starts 0.
When values are compared at if, please use ==.
Modified script :
function replace3() {
var sheet = SpreadsheetApp.getActiveSheet();
var lc = sheet.getMaxColumns();
var range = sheet.getRange("a1:z1");
var values = range.getValues();
for (var col in values[0]) { // Modified
if (values[0][col] =='aa') { // Modified
values[0][col] = 'ZZZ';
}
}
range.setValues(values);
}
For replace2()
sheetname is not declared.
When values are compared at if, please use ==.
Modified script :
function replace2() {
var sheet = SpreadsheetApp.getActiveSheet();
var lc = sheet.getMaxColumns();
var range = sheet.getRange(1, 1, 1, lc); // Modified
var values = range.getValues();
for (var i = 0; i <= lc; i++) {
if (values[0][i] == 'aa') { // Modified
values[0][i] = 'ZZZ';
}
}
range.setValues(values);
}
Other method :
Also you can achieve it using map().
Sample script :
function sample() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("a1:z1");
var values = range.getValues();
var data = values[0].map(function(e){return e == 'aa' ? 'ZZZ' : e});
range.setValues([data]);
}
If I misunderstand your question, please tell me. I would like to modify.
I want to identify equal rows in two different sheets on same spreadsheet. I tried below code, it doesn't work.
function getMyEqualRows()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheets()[0];
var sheet2 = ss.getSheets()[1];
var sheetOneValues = sheet1.getRange('A1:G20').getValues();
var sheetTwoValues = sheet2.getRange('A1:G20').getValues();
var equalRows = [];
for (var i = 0; i <= sheetOneValues.length; i++) {
for(var j = 0; j <= sheetTwoValues.length; j++){
if(sheetOneValues[i] == sheetTwoValues[j]) {
equalRows.push(sheetOneValues[i]);
}
}
return equalRows;
}
}
You can't compare two arrays for equality with ==. Instead you can use .join() method. It concatenates all elements in these arrays to a string. This check string arrays for equality. I'm not sure if this is the best way.
function getMyEqualRows()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheets()[0];
var sheet2 = ss.getSheets()[1];
var sheetOneValues = sheet1.getRange('A1:G20').getValues();
var sheetTwoValues = sheet2.getRange('A1:G20').getValues();
var equalRows = [];
for(var i in sheetOneValues)
{
var anEqualRow = false;
for(var j in sheetTwoValues)
{
if(sheetOneValues[i].join() == sheetTwoValues[j].join()){
anEqualRow = true;
}
}
if(anEqualRow){
equalRows.push(sheetOneValues[i]);
}
}
return equalRows;
}
Hope this would work!
I have started studying GAS recently.
I wrote Auto number script using Low number.
There is spreadsheet has some datas, I want put A Column including batch ID number at one time.
function autoID() {
var sheet = SpreadsheetApp.getActiveSheet();
var lastrow = sheet.getLastRow();
for(i=1; i<= lastrow-1; i++)
{
var num = sheet.getRange(i,1);
num.setValue(i);
}
Browser.msgBox("This is end!");
}
This in no good example,it takes too much time.
I wonder I should use Array() ..
may be ↓ this is hint..
https://developers.google.com/apps-script/best_practices
But this Best Practices doesn't work, I tried this...
function autoID() {
var sheet = SpreadsheetApp.getActiveSheet();
var lastrow = sheet.getLastRow();
var num = new Array();
idrange = sheet.getRamge("A2:A"+(lastrow-1));
idrange = idrange.getValues();
for(i=1; i<= lastrow-1; i++)
{
var num = sheet.getRange(i,1);
num[(i)]=i;
}
Browser.messageBox(num[1]); // this is 1;
idrange.setValues(num); // this is error
}
How is change type?
Please help me..
I think this must be so easy.
Not sure I understood exactly what you want to do but here is how it works without code errors :
function autoID() {
var sheet = SpreadsheetApp.getActiveSheet();
var lastrow = sheet.getLastRow();
var num = new Array();
var idrange = sheet.getRange("A2:A"+(lastrow));
var idrangeVal = idrange.getValues()
for(var i in idrangeVal){
num.push([i]);
}
idrange.setValues(num);
}
edit following your comment :
Here is a version the (I hope) does what you expected...
function autoID() {
var sheet = SpreadsheetApp.getActiveSheet();
var valuesInrangeA = sheet.getRange('A2:A').getValues();
var maxA = 0
for(var n=0 ;n<valuesInrangeA.length ; n++){
if(valuesInrangeA[n][0]!=''){maxA=n+2};
};
var num = new Array();
for(var i=1 ; i<maxA ; i++){
num.push([i]);
}
sheet.getRange("B2:B"+maxA).setValues(num);
}