【GAS】스프레드시트의 맞춤 메뉴에서 항목별로 함수를 동적(?)에 할당
12993 단어 자바스크립트GoogleAppsScript
개요
이것에 대답했기 때문에.
커스텀 메뉴는 편리합니다만, 함수 지정이 캐릭터 라인만이거나, 함수에 인수를 건네줄 수 없는 느낌이므로, 그것을 타개하고 싶다!
결론부터 말하면!
커스텀 메뉴 아이템마다 별도의 함수를 정의하는 것으로, 인수가 없어도 어떻게든 되도록(듯이) 만들 수 있었다.
이번 샘플이라면 시트 수가 바뀌었을 때, 스프레드 시트를 리로드하지 않으면 정상적으로 움직이지 않기 때문에 동적으로 할당한다고 약간 어폐가 있을지도. . .
완성 된 것의 미리보기
메뉴에서 시트 이름을 선택하면 선택한 시트 이름을 활성화합니다.
출처와 해설
소스 전문
const APP_ACTIVE = SpreadsheetApp.getActive();
const SHEETS = APP_ACTIVE.getSheets();
const ITEM_FUNCTIONS = (function() {
let result = {};
for (let i = 0; i < SHEETS.length; i++) {
// 各メニューアイテムに紐づける関数
result['_moveTo' + i] = function() {
SHEETS[i].activate();
APP_ACTIVE.toast(SHEETS[i].getSheetName() + ' に切り替えた!', 'カスタムメニューさん');
};
}
return result;
})();
/**
* スプレッドシートを開いた時のハンドラ
*/
function onOpen() {
let userMenu = [];
// メニューと動的関数を生成する
for (let i = 0; i < SHEETS.length; i++) {
const customFunctionName = 'ITEM_FUNCTIONS._moveTo' + i;
// カスタムメニューを追加
userMenu.push({
name: SHEETS[i].getSheetName(),
functionName: customFunctionName,
});
}
SpreadsheetApp.getActiveSpreadsheet().addMenu('シート名一覧', userMenu);
}
해설이나 주의점
게재한 소스나 실장에 있어서의 주의점에 대해 쓴다.
커스텀 메뉴로 지정하는 함수명이 글로벌 스코프로부터 추적되는 일
추적하면 좋기 때문에 이런 느낌의 함수라면…
// 宣言
const hoge = {
fuga: function() { Browser.msgBox('hello'); };
};
이런 식으로 점으로 연결하여 메뉴 아이템을 넣으면 객체 아래에 넣은 함수도 호출할 수 있다.
// 呼び出しメニューアイテム
SpreadsheetApp.getActiveSpreadsheet().addMenu('シート名一覧', {[
name: 'fugaを呼べ',
functionName: 'hoge.fuga'
]});
일단, globalThis
를 사용할 수 있으므로 이런 쓰는 방법도 할 수 있었다. 글쎄, 좋아.
// 宣言
globalThis['piyo'] = function() { Browser.msgBox('piyoさんだよ!'); };
// 呼び出しメニューアイテム
SpreadsheetApp.getActiveSpreadsheet().addMenu('シート名一覧', {[
name: 'piyoを呼べ',
functionName: 'piyo'
]});
동적 추가 함수는 초기화 시점에 추가되어야 한다.
내가 검증한 범주에서 onOpen 이전.
onOpen 후에는 globalThis 등에 함수를 추가해도 메뉴에서 호출 할 수 없었습니다.
아래와 같은 코드로 함수가 정의되어 있는지 어떤지를 체크하고 있었습니다만,
추가 처리를 한 함수 내에서는 살아 있지만, 처리를 빠져 버리면 globalThis에서 사라져 버렸다.
let msg = '';
Object.keys(globalThis).filter(key => typeof(globalThis[key] === 'function').forEach(key => {
if (msg) {
msg += '\\n';
}
msg += 'key: ' + key + ', funcName: ' + globalThis[key]?.name;
});
Browser.msgBox(msg);
// こんな感じに書いても、「はーい、testさんだよ!」とは言ってくれずに眠ったまま。
const funcs = {
'test': function() {
Browser.msgBox('…zzZ');
}
};
function onOpen() {
funcs['test'] = function() {
Browser.msgBox('はーい、testさんだよ!');
};
let userMenu = [{
name: 'test関数を実行!',
functionName= 'funcs.test'
}];
SpreadsheetApp.getActiveSpreadsheet().addMenu('カスタムメニュー', userMenu);
}
참고
커스텀 메뉴 아이템마다 별도의 함수를 정의하는 것으로, 인수가 없어도 어떻게든 되도록(듯이) 만들 수 있었다.
이번 샘플이라면 시트 수가 바뀌었을 때, 스프레드 시트를 리로드하지 않으면 정상적으로 움직이지 않기 때문에 동적으로 할당한다고 약간 어폐가 있을지도. . .
완성 된 것의 미리보기
메뉴에서 시트 이름을 선택하면 선택한 시트 이름을 활성화합니다.
출처와 해설
소스 전문
const APP_ACTIVE = SpreadsheetApp.getActive();
const SHEETS = APP_ACTIVE.getSheets();
const ITEM_FUNCTIONS = (function() {
let result = {};
for (let i = 0; i < SHEETS.length; i++) {
// 各メニューアイテムに紐づける関数
result['_moveTo' + i] = function() {
SHEETS[i].activate();
APP_ACTIVE.toast(SHEETS[i].getSheetName() + ' に切り替えた!', 'カスタムメニューさん');
};
}
return result;
})();
/**
* スプレッドシートを開いた時のハンドラ
*/
function onOpen() {
let userMenu = [];
// メニューと動的関数を生成する
for (let i = 0; i < SHEETS.length; i++) {
const customFunctionName = 'ITEM_FUNCTIONS._moveTo' + i;
// カスタムメニューを追加
userMenu.push({
name: SHEETS[i].getSheetName(),
functionName: customFunctionName,
});
}
SpreadsheetApp.getActiveSpreadsheet().addMenu('シート名一覧', userMenu);
}
해설이나 주의점
게재한 소스나 실장에 있어서의 주의점에 대해 쓴다.
커스텀 메뉴로 지정하는 함수명이 글로벌 스코프로부터 추적되는 일
추적하면 좋기 때문에 이런 느낌의 함수라면…
// 宣言
const hoge = {
fuga: function() { Browser.msgBox('hello'); };
};
이런 식으로 점으로 연결하여 메뉴 아이템을 넣으면 객체 아래에 넣은 함수도 호출할 수 있다.
// 呼び出しメニューアイテム
SpreadsheetApp.getActiveSpreadsheet().addMenu('シート名一覧', {[
name: 'fugaを呼べ',
functionName: 'hoge.fuga'
]});
일단, globalThis
를 사용할 수 있으므로 이런 쓰는 방법도 할 수 있었다. 글쎄, 좋아.
// 宣言
globalThis['piyo'] = function() { Browser.msgBox('piyoさんだよ!'); };
// 呼び出しメニューアイテム
SpreadsheetApp.getActiveSpreadsheet().addMenu('シート名一覧', {[
name: 'piyoを呼べ',
functionName: 'piyo'
]});
동적 추가 함수는 초기화 시점에 추가되어야 한다.
내가 검증한 범주에서 onOpen 이전.
onOpen 후에는 globalThis 등에 함수를 추가해도 메뉴에서 호출 할 수 없었습니다.
아래와 같은 코드로 함수가 정의되어 있는지 어떤지를 체크하고 있었습니다만,
추가 처리를 한 함수 내에서는 살아 있지만, 처리를 빠져 버리면 globalThis에서 사라져 버렸다.
let msg = '';
Object.keys(globalThis).filter(key => typeof(globalThis[key] === 'function').forEach(key => {
if (msg) {
msg += '\\n';
}
msg += 'key: ' + key + ', funcName: ' + globalThis[key]?.name;
});
Browser.msgBox(msg);
// こんな感じに書いても、「はーい、testさんだよ!」とは言ってくれずに眠ったまま。
const funcs = {
'test': function() {
Browser.msgBox('…zzZ');
}
};
function onOpen() {
funcs['test'] = function() {
Browser.msgBox('はーい、testさんだよ!');
};
let userMenu = [{
name: 'test関数を実行!',
functionName= 'funcs.test'
}];
SpreadsheetApp.getActiveSpreadsheet().addMenu('カスタムメニュー', userMenu);
}
참고
소스 전문
const APP_ACTIVE = SpreadsheetApp.getActive();
const SHEETS = APP_ACTIVE.getSheets();
const ITEM_FUNCTIONS = (function() {
let result = {};
for (let i = 0; i < SHEETS.length; i++) {
// 各メニューアイテムに紐づける関数
result['_moveTo' + i] = function() {
SHEETS[i].activate();
APP_ACTIVE.toast(SHEETS[i].getSheetName() + ' に切り替えた!', 'カスタムメニューさん');
};
}
return result;
})();
/**
* スプレッドシートを開いた時のハンドラ
*/
function onOpen() {
let userMenu = [];
// メニューと動的関数を生成する
for (let i = 0; i < SHEETS.length; i++) {
const customFunctionName = 'ITEM_FUNCTIONS._moveTo' + i;
// カスタムメニューを追加
userMenu.push({
name: SHEETS[i].getSheetName(),
functionName: customFunctionName,
});
}
SpreadsheetApp.getActiveSpreadsheet().addMenu('シート名一覧', userMenu);
}
해설이나 주의점
게재한 소스나 실장에 있어서의 주의점에 대해 쓴다.
커스텀 메뉴로 지정하는 함수명이 글로벌 스코프로부터 추적되는 일
추적하면 좋기 때문에 이런 느낌의 함수라면…
// 宣言
const hoge = {
fuga: function() { Browser.msgBox('hello'); };
};
이런 식으로 점으로 연결하여 메뉴 아이템을 넣으면 객체 아래에 넣은 함수도 호출할 수 있다.
// 呼び出しメニューアイテム
SpreadsheetApp.getActiveSpreadsheet().addMenu('シート名一覧', {[
name: 'fugaを呼べ',
functionName: 'hoge.fuga'
]});
일단,
globalThis
를 사용할 수 있으므로 이런 쓰는 방법도 할 수 있었다. 글쎄, 좋아.// 宣言
globalThis['piyo'] = function() { Browser.msgBox('piyoさんだよ!'); };
// 呼び出しメニューアイテム
SpreadsheetApp.getActiveSpreadsheet().addMenu('シート名一覧', {[
name: 'piyoを呼べ',
functionName: 'piyo'
]});
동적 추가 함수는 초기화 시점에 추가되어야 한다.
내가 검증한 범주에서 onOpen 이전.
onOpen 후에는 globalThis 등에 함수를 추가해도 메뉴에서 호출 할 수 없었습니다.
아래와 같은 코드로 함수가 정의되어 있는지 어떤지를 체크하고 있었습니다만,
추가 처리를 한 함수 내에서는 살아 있지만, 처리를 빠져 버리면 globalThis에서 사라져 버렸다.
let msg = '';
Object.keys(globalThis).filter(key => typeof(globalThis[key] === 'function').forEach(key => {
if (msg) {
msg += '\\n';
}
msg += 'key: ' + key + ', funcName: ' + globalThis[key]?.name;
});
Browser.msgBox(msg);
// こんな感じに書いても、「はーい、testさんだよ!」とは言ってくれずに眠ったまま。
const funcs = {
'test': function() {
Browser.msgBox('…zzZ');
}
};
function onOpen() {
funcs['test'] = function() {
Browser.msgBox('はーい、testさんだよ!');
};
let userMenu = [{
name: 'test関数を実行!',
functionName= 'funcs.test'
}];
SpreadsheetApp.getActiveSpreadsheet().addMenu('カスタムメニュー', userMenu);
}
참고
Reference
이 문제에 관하여(【GAS】스프레드시트의 맞춤 메뉴에서 항목별로 함수를 동적(?)에 할당), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/neonemo/items/86f34ecb0db3cfc51c8d텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)