95636


全てのファイルに入力するのは面倒ではないかと思い、数字をA1セルに１を、A2セルに２を入力する関数を作成してみたのですが、

[![マクロの結果](https://i.stack.imgur.com/SYOeJ.png)](https://i.stack.imgur.com/SYOeJ.png)

[code]

    function number() {
      var spreadsheet = SpreadsheetApp.getActive();
      spreadsheet.getRange('A1').activate();
      spreadsheet.getCurrentCell().setValue('1');
      spreadsheet.getRange('A2').activate();
      spreadsheet.getCurrentCell().setValue('2');
      spreadsheet.getRange('A3').activate();
    }
    
[/code]

上記は普通に実行されましたが、下記で関数に`var spreadsheet =
SpreadsheetApp.getActive();`を入れて、関数を書き込んでも実行されません。

[code]

    function number() {
      spreadsheet
      spreadsheet.getRange('A1').activate();
      spreadsheet.getCurrentCell().setValue('1');
      spreadsheet.getRange('A2').activate();
      spreadsheet.getCurrentCell().setValue('2');
      spreadsheet.getRange('A3').activate();
    }
    
[/code]

これは省略できない決まりがあるのか、それとも関数を書き込む際に何か書かなければならないのか、教えていただけませんか？

[code]

    function number() {
      var spreadsheet = SpreadsheetApp.getActive();
      spreadsheet.getRange('A1').activate();
      spreadsheet.getCurrentCell().setValue('1');
      spreadsheet.getRange('A2').activate();
      spreadsheet.getCurrentCell().setValue('2');
      spreadsheet.getRange('A3').activate();
    }
    
[/code]

[code]

    function number() {
    　spreadsheet
      spreadsheet.getRange('A1').activate();
      spreadsheet.getCurrentCell().setValue('1');
      spreadsheet.getRange('A2').activate();
      spreadsheet.getCurrentCell().setValue('2');
      spreadsheet.getRange('A3').activate();
    }
    
[/code]

スプレッドシートを使うために書いた関数です。

[code]

    function spreadsheet(spreadsheet) {
      var spreadsheet = SpreadsheetApp.getActive();
    }
    
[/code]


CC BY-SA 4.0
2023-07-14T02:46:31.167
95603
2023-07-15T10:25:40.663
2023-07-15T07:11:49.853
3054
58928
question
javascript google-apps-script google-spreadsheet
スプレッドシートを使う宣言は、関数化して省略できないものでしょうか？


関数のなかの型を宣言しているところを別の関数として定義できないかということだと思うんですけど、自分でもfunction
spreadsheetの宣言を先行して書いてみてやってみましたができませんでした。

関数の中のvar spreadsheetのところの型宣言があいまいになってしまうからじゃないですかね。


CC BY-SA 4.0
2023-07-14T07:31:22.210
95610
2023-07-14T07:31:22.210
50767
95603
answer


できます。元が短いので「省略」になるかはともかく、関数にして共通化できます。質問のコードにはいくつか誤りがあるので、これらを直せばよいです。

（追記: なお、変数のスコープに関する誤解があると思いますので、それは「共通の変数を読み書きしたい場合」の項で少し触れました）

### 関数定義の修正

関数の定義に間違いがあります。

オリジナル:

[code]

    function spreadsheet(spreadsheet) {
      var spreadsheet = SpreadsheetApp.getActive();
    }
    
[/code]

関数名、引数名、及び関数内の変数名に同じ名前（`spreadsheet`）が使われています。これが混乱を招いていると思いますので、まずこれを止めましょう。

改善1:

[code]

    function getSpreadsheet(arg) {
      var spreadsheet = SpreadsheetApp.getActive();
    }
    
[/code]

これで分かると思いますが、引数（`arg`）は使われていません。削除しましょう。

改善2:

[code]

    function getSpreadsheet() {
      var spreadsheet = SpreadsheetApp.getActive();
    }
    
[/code]

さらに、関数内で宣言されている変数 `spreadsheet`
が、どこにも利用されずに放置されていることが分かります。これを関数の戻り値として返すようにしましょう。

改善3（これで動作します）:

[code]

    function getSpreadsheet() {
      var spreadsheet = SpreadsheetApp.getActive();
      return spreadsheet;
    }
    
[/code]

### 関数の呼び出し方の修正

関数の呼び出し方にも間違いが有ります。

オリジナル:

[code]

    function number() {
      spreadsheet
    
[/code]

まず、関数定義の修正で関数名を `getSpreadsheet` に修正したので、これに合わせます。

改善1:

[code]

    function number() {
      getSpreadsheet
    
[/code]

次に、[関数の呼び出し](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Functions#%E9%96%A2%E6%95%B0%E3%81%AE%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%97)には関数名の後に括弧、つまり「`(`」と「`)`」が必要です。括弧内には引数を書きますが、引数が無くとも括弧は省略できませんので空の括弧、つまり「`()`」を書きます。

改善2:

[code]

    function number() {
      getSpreadsheet();
    
[/code]

これで関数が実行されるようになりました。しかし、関数の戻り値を利用するコードが有りません。変数に保存するようにしましょう。

改善3（これで動作します）:

[code]

    function number() {
      var spreadsheet = getSpreadsheet();
    
[/code]

* * *

### 共通の変数を読み書きしたい場合

上の修正を全て行なうと、コードは下のようになります。

修正後のコード:

[code]

    function getSpreadsheet() {
      var spreadsheet = SpreadsheetApp.getActive();
      return spreadsheet;
    }
    
    function number() {
      var spreadsheet = getSpreadsheet();
    
[/code]

しかし、質問者さんの当初の意図としては、呼び出す側の関数 `number` からも、`getSpreadsheet` 関数内の変数である
`spreadsheet` を参照できるものとし、例えば下のように書きたかったものと思います。

当初の意図に近いが動かないコード:

[code]

    function getSpreadsheet() {
      var spreadsheet = SpreadsheetApp.getActive();
    }
    
    function number() {
      getSpreadsheet();
      // 以降で変数 spreadsheet を参照するコードを書く
    
[/code]

しかし、これは動作しません。なぜなら、関数内で宣言した変数は、その関数の中のコードからしか参照できないからです。この参照できる範囲を「[スコープ](https://developer.mozilla.org/ja/docs/Glossary/Scope)」と言います。

このルールが無ければ、関数を呼び出す側は、呼び出した関数が内部で扱う変数名を全て把握しておかなければならず、それらと同じ変数名を使わないように気を付けるなど、沢山のことを考慮しなければならなくなります。

ですから、関数 `getSpreadsheet` と 関数 `number`
とで同じ変数を参照したい場合は、その変数の宣言を両方の関数が含まれるスコープ内で行なう必要があります。例えば下のようになります。

関数の外に宣言を出す（これで動作します）:

[code]

    var spreadsheet;
    
    function getSpreadsheet() {
      spreadsheet = SpreadsheetApp.getActive();
    }
    
    function number() {
      getSpreadsheet();
      // 以降で変数 spreadsheet を参照するコードを書く
    
[/code]

これで変数 `spreadsheet` はどちらの関数からも参照できますので、質問者さんの意図にもっとも近い動作可能なコードであろうと思います。

ただし、一般にはこういったコードは良くないとされます。関数を呼び出す側は、その関数が結果を書き込む変数を把握しておかなければならず、これはコードが増えるにつれ、段々と対処不能な複雑さを生み出すようになります。あえて使用すべき状況を判断できるようになるまでは、避けたほうが無難です。


CC BY-SA 4.0
2023-07-15T07:11:07.633
95636
2023-07-15T10:25:40.663
2023-07-15T10:25:40.663
3054
3054
95603
answer