问题
I have the working code below that compares two sets of data from two different sheets. One is a list of 395 phone numbers, the second is a list of around 135,000 rows of data. The following code compares the two for similarities and copies the similar row to a third sheet.
While the code does work for small scale tests, (1000 rows and 395 phone numbers) in around 10 minutes. However doing 135,000 rows makes the script time out. Here is the script below.
`function copyRowtoSheet3() {
var s1 = SpreadsheetApp.openById("1Aw11LiKzyezfrTQIuTsJPhUFtz8RPqLCc8FlIiy0ZlE").getSheetByName('Sheet1');
var s2 = SpreadsheetApp.openById("1Aw11LiKzyezfrTQIuTsJPhUFtz8RPqLCc8FlIiy0ZlE").getSheetByName('Sheet2');
var s3 = SpreadsheetApp.openById("1Aw11LiKzyezfrTQIuTsJPhUFtz8RPqLCc8FlIiy0ZlE").getSheetByName('Sheet3');
var values1 = s1.getDataRange().getValues();
var values2 = s2.getDataRange().getValues();
var resultArray = [];
for(var n=0; n < values1.length ; n++){
var keep = false;
for(var p=0; p < values2.length ; p++){
Logger.log(values1[n][0]+' =? '+values2[p][0]);
if( values1[n][1] == values2[p][0] ){
resultArray.push(values1[n]);
Logger.log('true');
//break ;
}
}
}
s3.getRange(+1,1,resultArray.length,resultArray[0].length).setValues(resultArray);
}`
I'm not the best at optimizing code, and would love it if there were any suggestions that could be inputted here. I took a look at best practices and applied them already to the best of my abilities. Any suggestions to the code here?
回答1:
- You want to compare the column "B" of "Sheet1" and the column "A" of "Sheet2".
- When the values of the column "B" of "Sheet1" and the column "A" of "Sheet2" are the same, you want to put the row of "Sheet1" to "Sheet3".
- You want to reduce the process cost of the script.
- 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.
Modification points:
- Please use
SpreadsheetApp.openById("1Aw11LiKzyezfrTQIuTsJPhUFtz8RPqLCc8FlIiy0ZlE")
one time. - In your case,
values2
is used in the for loop. Sovalues2
is looped every element ofvalues1
.- For this, an object is prepared for searching values.
- If the length of
resultArray
is large, the process cost can be reduced using Sheets API instead of Spreadsheet service likeSpreadsheetApp
. Ref
When above points are reflected to your script, the flow is as follows.
Flow:- Retrieve values from "Sheet1" and "Sheet2",
- Create an object using
values2
. - Create
resultArray
usingvalues1
and the object. - Put
resultArray
to "Sheet3" using the method of spreadsheets.values.update in Sheets API.
Modified script:
Before you use this script, please enable Sheets API at Advanced Google services.
function copyRowtoSheet3() {
var spreadsheetId = "1Aw11LiKzyezfrTQIuTsJPhUFtz8RPqLCc8FlIiy0ZlE";
var ss = SpreadsheetApp.openById(spreadsheetId);
var s1 = ss.getSheetByName('Sheet1');
var s2 = ss.getSheetByName('Sheet2');
// 1. Retrieve values from "Sheet1" and "Sheet2",
var values1 = s1.getDataRange().getValues();
var values2 = s2.getRange(1, 1, s2.getLastRow(), 1).getValues();
// 2. Create an object using values2.
var obj = values2.reduce((o, [e]) => {
o[e] = null;
return o;
}, {});
// 3. Create resultArray using values1 and obj.
var resultArray = values1.filter(([,b]) => b in obj);
// 4. Put resultArray to Sheet3.
Sheets.Spreadsheets.Values.update({values: resultArray}, spreadsheetId, "Sheet3", {valueInputOption: "USER_ENTERED"});
}
Note:
- In this case, please enable V8 at the script editor.
References:
- Benchmark: Reading and Writing Spreadsheet using Google Apps Script
- Advanced Google services
- Method: spreadsheets.values.update
If I misunderstood your question and this was not the result you want, I apologize.
来源:https://stackoverflow.com/questions/60501533/java-script-optimization-for-a-google-apps-script