First, here is the link from my Google Sheet:
https://docs.google.com/spreadsheets/d/1vROojeTBYnSQy0IeYY0vkzump-CPoDd5fyFuLwRZsjQ/edit?usp=sharing
I have 2 sheets: one (Sheet1) which contains a list of machines with an IP address, a Hostname and a switch port. The objective of my script is to read the switch and the port of sheet 1, then put a note in the corresponding cell in sheet 2 (sheet 2 contains the diagram of the switches available with their 48 ports), the note must contain hostname and IP address.
The script works but adds the notes one by one, and it might take more than 30 minutes if my number of machines increases.
Do you have an idea to speed up the process?
CodePudding user response:
Issue:
You're currently iterating through the source values in Sheet1 and using TextFinder to find the corresponding cells in Sheet2. Using TextFinder iteratively greatly increases the amount of requests to the spreadsheet, and that slows down the script a lot (see Minimize calls to other services).
Along the same lines, you are setting the notes for each cell individually via setNote, instead of setting all of them at once with setNotes(notes), as Sergey said.
Solution:
I'd like to propose an alternative approach to minimize calls to the spreadsheet and so make the script considerably faster:
- Retrieve the useful data from
Sheet1(note,switchandport), converting it to an array of objects for easier later retrieval. - Retrieve all the data in
Sheet2using getDataRange() and getValues(). - Using map, iterate through the data in
Sheet2, and for each row, check if either column A of the current row (for oddportnumbers) or from two rows above (for evenportnumbers) contain a validswitchname (you can use find for that). - If no valid
switchname is found, return an array ofnullfor thismapiteration (since providingnullas a parameter tosetNoteremoves the note). - If a valid
switchname is found, iterate through that row's ports usingmap, and for eachport, look for the valid combination ofswitchandportin the source data. - If a valid combination of
switchandportis found, return the correspondingnotefor thatmapiteration. - If a valid combination is not found (that is,
Sheet1doesn't contain data for that combination), returnnullfor that iteration. - Once you have build the 2D array of
notesusing the corresponding nestedmaps, set those notes to theportcolumns fromSheet2, usingsetNotes.
Code sample:
function actualiserNP2(){
const SWITCH_COL = 1;
const PORT_FIRST_COL = 4;
const PORT_LAST_COL = 27;
const ss = SpreadsheetApp.getActiveSpreadsheet();
const Sheet2 = ss.getSheetByName('Sheet2');
const Sheet1 = ss.getSheetByName('Sheet1');
const tabGeneral = Sheet1.getRange(10,2, Sheet1.getLastRow(), Sheet1.getLastColumn()).getValues();
const sourceData = tabGeneral.filter(row => row[7].includes("#")).map(row => {
const [sw1a, sw1b] = row[7].split("#");
const data = {
"note": `${row[0]}\n\n${row[5]}`,
"switch": sw1a,
"port": sw1b
}
return data;
});
const targetData = Sheet2.getDataRange().getValues();
const notes = targetData.map((row,i) => {
const sourceSwitch = sourceData.find(sourceRow => sourceRow["switch"] === row[SWITCH_COL-1] || (i > 1 && sourceRow["switch"] === targetData[i-2][SWITCH_COL-1]));
if (sourceSwitch) {
const currentSwitch = sourceSwitch["switch"];
const ports = row.slice(PORT_FIRST_COL-1, PORT_LAST_COL);
const rowNotes = ports.map(port => {
const sourceRow = sourceData.find(row => row["switch"] === currentSwitch && Number(row["port"]) === Number(port));
if (sourceRow) return sourceRow["note"];
else return null;
});
return rowNotes;
} else {
return new Array(PORT_LAST_COL-PORT_FIRST_COL 1).fill(null);
}
});
Sheet2.getRange(1, PORT_FIRST_COL, Sheet2.getLastRow(), PORT_LAST_COL-PORT_FIRST_COL 1).setNotes(notes);
}
CodePudding user response:
I modified lamblichus's script to adapt it to the 3 ports. It works with this new script :
function actualiserNP1()
{
const SWITCH_COL = 1;
const PORT_FIRST_COL = 4;
const PORT_LAST_COL = 27;
const ss = SpreadsheetApp.getActiveSpreadsheet();
const Sheet2 = ss.getSheetByName('Sheet2');
const Sheet1 = ss.getSheetByName('Sheet1');
const tabGeneral = Sheet1.getRange(10,2, Sheet1.getLastRow(), Sheet1.getLastColumn()).getValues();
const data = [];
const sourceData = tabGeneral.filter(row => row[7].includes("#") || row[11].includes("#") || row[15].includes("#")).map(row => { // On filtre les lignes ayant au moins un port
//§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ 001
if(row[7]=='' && row[11]=='' && row[15]!='')
{
if(row[13]!=''){
const [sw3a, sw3b] = row[15].split("#");
data.push({
"note": `${row[0]}\n\n${row[13]}`,
"switch": sw3a,
"port": sw3b
})
}else{
const [sw3a, sw3b] = row[15].split("#");
data.push({
"note": `${row[0]}\n\n${row[5]}`,
"switch": sw3a,
"port": sw3b
})
}
}
//§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ 010
if(row[7]=='' && row[11]!='' && row[15]=='')
{
if(row[9]!=''){
const [sw2a, sw2b] = row[11].split("#");
data.push({
"note": `${row[0]}\n\n${row[9]}`,
"switch": sw2a,
"port": sw2b
})
}else{
const [sw2a, sw2b] = row[11].split("#");
data.push({
"note": `${row[0]}\n\n${row[5]}`,
"switch": sw2a,
"port": sw2b
})
}
}
//§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ 011
if(row[7]=='' && row[11]!='' && row[15]!='')
{
if(row[9]!=''){
const [sw2a, sw2b] = row[11].split("#");
data.push({
"note": `${row[0]}\n\n${row[9]}`,
"switch": sw2a,
"port": sw2b
})
}else{
const [sw2a, sw2b] = row[11].split("#");
data.push({
"note": `${row[0]}\n\n${row[5]}`,
"switch": sw2a,
"port": sw2b
})
}
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
if(row[13]!=''){
const [sw3a, sw3b] = row[15].split("#");
data.push({
"note": `${row[0]}\n\n${row[13]}`,
"switch": sw3a,
"port": sw3b
})
}else{
const [sw3a, sw3b] = row[15].split("#");
data.push({
"note": `${row[0]}\n\n${row[5]}`,
"switch": sw3a,
"port": sw3b
})
}
}
//§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ 100
if(row[7]!='' && row[11]=='' && row[15]=='')
{
const [sw1a, sw1b] = row[7].split("#");
data.push({
"note": `${row[0]}\n\n${row[5]}`,
"switch": sw1a,
"port": sw1b
})
}
//§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ 101
if(row[7]!='' && row[11]=='' && row[15]!='')
{
if(row[13]!=''){
const [sw3a, sw3b] = row[15].split("#");
data.push({
"note": `${row[0]}\n\n${row[13]}`,
"switch": sw3a,
"port": sw3b
})
}else{
const [sw3a, sw3b] = row[15].split("#");
data.push({
"note": `${row[0]}\n\n${row[5]}`,
"switch": sw3a,
"port": sw3b
})
}
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
const [sw1a, sw1b] = row[7].split("#");
data.push({
"note": `${row[0]}\n\n${row[5]}`,
"switch": sw1a,
"port": sw1b
})
}
//§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ 110
if(row[7]!='' && row[11]!='' && row[15]=='')
{
if(row[9]!=''){
const [sw2a, sw2b] = row[11].split("#");
data.push({
"note": `${row[0]}\n\n${row[9]}`,
"switch": sw2a,
"port": sw2b
})
}else{
const [sw2a, sw2b] = row[11].split("#");
data.push({
"note": `${row[0]}\n\n${row[5]}`,
"switch": sw2a,
"port": sw2b
})
}
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
const [sw1a, sw1b] = row[7].split("#");
data.push({
"note": `${row[0]}\n\n${row[5]}`,
"switch": sw1a,
"port": sw1b
})
}
//§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ 111
if(row[7]!='' && row[11]!='' && row[15]!='')
{
if(row[9]!=''){
const [sw2a, sw2b] = row[11].split("#");
data.push({
"note": `${row[0]}\n\n${row[9]}`,
"switch": sw2a,
"port": sw2b
})
}else{
const [sw2a, sw2b] = row[11].split("#");
data.push({
"note": `${row[0]}\n\n${row[5]}`,
"switch": sw2a,
"port": sw2b
})
}
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
if(row[13]!=''){
const [sw3a, sw3b] = row[15].split("#");
data.push({
"note": `${row[0]}\n\n${row[13]}`,
"switch": sw3a,
"port": sw3b
})
}else{
const [sw3a, sw3b] = row[15].split("#");
data.push({
"note": `${row[0]}\n\n${row[5]}`,
"switch": sw3a,
"port": sw3b
})
}
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
const [sw1a, sw1b] = row[7].split("#");
data.push({
"note": `${row[0]}\n\n${row[5]}`,
"switch": sw1a,
"port": sw1b
})
}
return data;
});
console.log(data)
//console.log(sourceData);
const targetData = Sheet2.getDataRange().getValues();
const notes = targetData.map((row,i) => {
const sourceSwitch = data.find(sourceRow => sourceRow["switch"] === row[SWITCH_COL-1] || (i > 1 && sourceRow["switch"] === targetData[i-2][SWITCH_COL-1]));
if (sourceSwitch)
{
const currentSwitch = sourceSwitch["switch"];
const ports = row.slice(PORT_FIRST_COL-1, PORT_LAST_COL);
const rowNotes = ports.map(port => {
const sourceRow = data.find(row => row["switch"] === currentSwitch && Number(row["port"]) === Number(port));
if (sourceRow) return sourceRow["note"];
else return null;
});
return rowNotes;
} else {
return new Array(PORT_LAST_COL-PORT_FIRST_COL 1).fill(null);
}
});
Sheet2.getRange(1, PORT_FIRST_COL, Sheet2.getLastRow(), PORT_LAST_COL-PORT_FIRST_COL 1).setNotes(notes);
}
I am a begginer so i did instructions for each possible case.
