質問するログイン新規登録

回答編集履歴

10

追加

2021/10/10 14:14

投稿

退会済みユーザー
answer CHANGED
@@ -168,11 +168,11 @@
168
168
  たとえば、シート1 の F12セル をアクティブにした状態で、実行ボタンをクリックすると、
169
169
  ・アクティブセルのC列は「`AAA12`」
170
170
  ・アクティブセルの1つ前の列の1行目は「`2021.7`」
171
+ ![イメージ説明](b28f36165578fa1067e0967ad2ae97cb.png)
171
172
  なので、
172
173
  **シート9**の中から、
173
174
  「D列またはL列が`AAA12`である行のうち、A列の年月が `2021年7月` である行]
174
175
  を探します。
175
- ![イメージ説明](b28f36165578fa1067e0967ad2ae97cb.png)
176
176
 
177
177
  そうすると、該当するのは13行目なので、シート9の13行目のデータが シート9の150行目に展開されます。
178
178
  ![イメージ説明](6c12a069cf8cd84a22be87789a34c33a.png)
@@ -223,4 +223,96 @@
223
223
  }
224
224
  return output;
225
225
  }
226
+ ```
227
+
228
+ -----
229
+ # コメントでの追加質問に対する回答
230
+ > 、上記のシート1に相当するピボットテーブルのシートが複数あり、その際switch case break構文を使えば良いと教えていただいたのですが、上記コードにこれを組み込むにはどうすればよろしいでしょうか?(仮にシート2として表の位置は1行目D列に枠があると仮定していただけますと幸いです、これで私の思うものが完成する次第です)
231
+
232
+
233
+ シートごとに処理を変える場合の例です
234
+ (共通処理として出せる部分は多々あるかと思いますが、「各シートの処理で具体的にどのような差異があるのか」について全く明記されていない以上、こちらでは回答できかねます。
235
+ 下記は共通処理も重複して書くことで、最低限動くであろうという例となります)
236
+ ```
237
+ // メニュー追加処理
238
+ function onOpen() {
239
+ var ui = SpreadsheetApp.getUi();
240
+ var menu = ui.createMenu('script');
241
+ menu.addItem('仕訳呼出', 'onClickMenu');
242
+ menu.addToUi();
243
+ }
244
+
245
+ // メニューをクリックしたときに実行
246
+ function onClickMenu() {
247
+ var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
248
+ switch (sheet.getName()){
249
+ case "シート1":
250
+ myFunctionSheet1(sheet)
251
+ break;
252
+
253
+ case "シート2":
254
+ myFunctionSheet2(sheet)
255
+ break;
256
+
257
+ case "シート3":
258
+ myFunctionSheet3(sheet)
259
+ break;
260
+
261
+ default: //上記以外の場合は何もしない
262
+ return;
263
+ }
264
+ // 以下に各シート共通処理を書く。
265
+ // ....
266
+ }
267
+
268
+
269
+ // シート1の処理コード
270
+ function myFunctionSheet1(sheet) {
271
+ var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート9');
272
+
273
+ // 展開先の行番号(例:150目以降に展開したい場合「150」を指定)
274
+ var OUTPUT_START = 150;
275
+ ....
276
+ ~~以下略~~(シート1専用の処理)(中身は上記のコード中のmyFunctionXYを参考に書けばよい)
277
+ ....
278
+ }
279
+
280
+ // シート2のコード
281
+ function myFunctionSheet2(sheet) {
282
+ var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート9');
283
+
284
+ // 展開先の行番号(例:150目以降に展開したい場合「150」を指定)
285
+ var OUTPUT_START = 150;
286
+ ....
287
+ ~~略~~(シート2専用の処理)
288
+ //「1行目D列に枠がある」->where節の読み取り列を3から4に変えればよい(?)
289
+ sheet2.getRange(lastRow, 1).setValue(
290
+ `=query('シート9'!A2:U${OUTPUT_START - 1},`
291
+ + `"where (D='"&${getAddress(sheet, rangeList[i].getRow() - 1 + 1, 4)}&"'`
292
+ + ` or L='"&${getAddress(sheet, rangeList[i].getRow() - 1 + 1, 4)}&"')`
293
+ + ` and year(A)="&text(substitute(substitute(${getAddress(sheet, 1, rangeList[i].getColumn() - 1)},"-",""),",","-"),"YYYY")&"`
294
+ + ` and month(A)+1="&text(substitute(substitute(${getAddress(sheet, 1, rangeList[i].getColumn() - 1)},"-",""),",","-"),"MM")&"")`);
295
+ ~~以下略~~
296
+ }
297
+ }
298
+
299
+ // シート3のコード
300
+ function myFunctionSheet3(sheet) {
301
+ var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート9');
302
+
303
+ // 展開先の行番号(例:150目以降に展開したい場合「150」を指定)
304
+ var OUTPUT_START = 150;
305
+ ....
306
+ ~~略~~(シート3専用の処理)
307
+ }
308
+ }
309
+
310
+
311
+ function getAddress(sheetObj, row, col) {
312
+
313
+ }
314
+
315
+ function getSprittedRange(rangelist) {
316
+
317
+ }
226
318
  ```

9

修正

2021/10/10 14:14

投稿

退会済みユーザー
answer CHANGED
@@ -108,7 +108,7 @@
108
108
  * getActiveRangeList()で取得した、アクティブセルのRangeList
109
109
  *
110
110
  * 戻り値:
111
- * Range : 分割後の個別セル範囲
111
+ * Range[] : 分割後の個別セル範囲(Range)を格納した配列
112
112
  *****************************************************/
113
113
  function getSprittedRange(rangelist) {
114
114
  // 戻り値(個別セル範囲)を格納するための配列

8

修正

2021/10/10 04:52

投稿

退会済みユーザー
answer CHANGED
@@ -172,7 +172,7 @@
172
172
  **シート9**の中から、
173
173
  「D列またはL列が`AAA12`である行のうち、A列の年月が `2021年7月` である行]
174
174
  を探します。
175
- ![イメージ説明](ff6a62463130d3d623b264b61941bdda.png)
175
+ ![イメージ説明](b28f36165578fa1067e0967ad2ae97cb.png)
176
176
 
177
177
  そうすると、該当するのは13行目なので、シート9の13行目のデータが シート9の150行目に展開されます。
178
178
  ![イメージ説明](6c12a069cf8cd84a22be87789a34c33a.png)

7

修正

2021/10/10 04:41

投稿

退会済みユーザー
answer CHANGED
@@ -83,7 +83,7 @@
83
83
  *  (シート名の両側にはシングルクォーテーションが入ります)
84
84
  *****************************************************/
85
85
  function getAddress(sheetObj, row, col) {
86
- if (sheetObj < 1) {
86
+ if (sheetObj == null) {
87
87
  throw Error("引数 sheetObjが指定されていません。");
88
88
  }
89
89
 

6

2021/10/10 04:35

投稿

退会済みユーザー
answer CHANGED
@@ -6,7 +6,6 @@
6
6
  QUERY関数そのものはスプレッドシート上の数式でしか利用できません。
7
7
   
8
8
  現状のQUERYを使った数式と同じ動作をGASで実装することも可能ですが、この場合は、まず「どのような動作にしたいのか」をしっかり固める必要があると思います。
9
- (組んだ後で「実は本当はこういう動作がしたい」「うまく動かない」等言われても、また一からやり直しになってしまいます)
10
9
 
11
10
  QUERYを使った「数式」を汎用的に「GASのコード」に変える手段はおそらく存在せず、結局「やりたい動作」を行うために個別にカスタマイズせざるを得ません。
12
11
 

5

2021/10/10 04:34

投稿

退会済みユーザー
answer CHANGED
@@ -5,12 +5,13 @@
5
5
   
6
6
  QUERY関数そのものはスプレッドシート上の数式でしか利用できません。
7
7
   
8
- 現状のQUERYを使った数式と同じ動作をGASで実装することも可能ですが、まず「どのような動作にしたいのか」を固めた上でない、同等の動作を組むことはできせん
8
+ 現状のQUERYを使った数式と同じ動作をGASで実装することも可能ですが、この場合は、まず「どのような動作にしたいのか」をしっかり固める必要がある思い
9
-  
10
- QUERYを使った数式を汎用的にGASのコードに変える手段はなく、結局やりたい動作」を行うための個別のカスタマイズとせざるを得せん。
9
+ (組んだ後で実は本当はこう動作がしたいまく動かない」等言われても、ま一からやり直しになってしいます)
11
10
 
12
-  数式を使っていれば、質問者さん方でカスタマイズも容易であと考えした
11
+ QUERYを使った「数式」を汎用的に「GASコード」に変える手段はおそらく存在せず、結局「やりたい動作」を行うために個別にカスタマイズせざを得せん
13
12
 
13
+ 数式を使っていれば、質問者さんの方でカスタマイズも容易であると考えました。
14
+
14
15
  ・mapやfilter等を駆使すればもっと短く・速くできるところはたくさんあるかもしれませんが、上記と同様の理由で、あえて冗長であったり、速度を犠牲にした書き方をしている部分があります。
15
16
  (元のmyFunctionXY()の中では、constやletを使った書き方も使用していません)
16
17
 

4

2021/10/10 04:31

投稿

退会済みユーザー
answer CHANGED
@@ -149,18 +149,21 @@
149
149
 
150
150
  # 動作について
151
151
 
152
- シート1のデータ範囲のセルをクリックし、実行ボタンをクリックすると、下記の動作を行います。
152
+ シート1のデータ範囲のセルを1個以上クリックした状態で、実行ボタンをクリックすると、下記の動作を行います。
153
153
 
154
154
  (1)シート1 のアクティブなセルの行の **C列** にあるID(「`A***`」)を読み取ります。
155
155
  (2)シート1 のアクティブなセルの**1つ前の列の1行目**にある年月値(「`2021,***`」)を読み取ります。
156
- (3)シート9 の A1~A149 の範囲から、**下記の条件**にあてはまる行を抽出、シート9の150行目以降に展開します。
156
+ (3)シート9 の A1~L149 の範囲から、**下記の条件**にあてはまる行を抽出する数式を、シート9の150行目以降に入力します。
157
157
  ```text
158
158
  抽出条件
159
159
    ・シート9の D列 または L列が (1) で取得したIDと一致する
160
160
      かつ
161
161
    ・シート9の A列 の日付の年・月が、(2) で取得した年月値と一致する
162
162
  ```
163
-
163
+ (4)クリックしたセルが複数ある場合は、残りのセルに対して同じ動作を順次繰り返します。
164
+ それぞれのセルについて検索結果が見つかった場合は、シート9の既存の結果行から1行空けて数式を追記します。
165
+  
166
+  
164
167
  # 例
165
168
  たとえば、シート1 の F12セル をアクティブにした状態で、実行ボタンをクリックすると、
166
169
  ・アクティブセルのC列は「`AAA12`」

3

2021/10/10 04:26

投稿

退会済みユーザー
answer CHANGED
@@ -194,7 +194,10 @@
194
194
  Logger.log(range.getA1Notation());
195
195
  // "E2"
196
196
  ```
197
+ 上記コード内のgetAddress()関数は、これを拡張し、
198
+ シートオブジェクト・行番号・列番号を与えると、対応する「シート名!A1」形式の文字列を返す関数としています。
197
199
 
200
+
198
201
  ・**隣接するセルを選択したときのセル分割**
199
202
  Googleスプレッドシートの仕様として、隣接するセルをControlクリックで複数選択すると、1つのセルとして扱われてしまうことがあります。(少なくとも Windows10上のChromium Edgeではそうなっています)
200
203
 

2

2021/10/10 04:10

投稿

退会済みユーザー
answer CHANGED
@@ -16,6 +16,9 @@
16
16
 
17
17
  ・具体的な動作が読解し切れていないので、期待する動作と異なる部分があるかもしれませんが、御了承ください。
18
18
  (動作検証環境:Windows 10 /Chromium Edge/GAS:V8エンジン有効)
19
+
20
+ シート9の展開先開始行を変えたい場合は、コード中の`OUTPUT_START`の数字を変えて保存・実行してください。
21
+  
19
22
  ```js
20
23
  function myFunctionXY() {
21
24
 

1

追加

2021/10/10 04:05

投稿

退会済みユーザー
answer CHANGED
@@ -15,7 +15,7 @@
15
15
  (元のmyFunctionXY()の中では、constやletを使った書き方も使用していません)
16
16
 
17
17
  ・具体的な動作が読解し切れていないので、期待する動作と異なる部分があるかもしれませんが、御了承ください。
18
-
18
+ (動作検証環境:Windows 10 /Chromium Edge/GAS:V8エンジン有効)
19
19
  ```js
20
20
  function myFunctionXY() {
21
21
 
@@ -172,4 +172,46 @@
172
172
  ![イメージ説明](6c12a069cf8cd84a22be87789a34c33a.png)
173
173
 
174
174
  複数の結果がある場合は1行ずつ空けて表示します。(下記はサンプルです)
175
- ![イメージ説明](e74dcaa5cc67f09d835aeaa1f7f7059b.png)
175
+ ![イメージ説明](e74dcaa5cc67f09d835aeaa1f7f7059b.png)
176
+
177
+ ---
178
+ # 補足
179
+ ・**別シートのセル値取得**
180
+ スプレッドシート上の数式で、同じスプレッドシート上の**別シート**のセル値を読み取る場合、indirect関数を使用する必要はありません。
181
+ 単純に`'シート名'!セル番地` とすれば指定したシートの指定した番地の値を取得できます。
182
+  
183
+  
184
+ ・**GAS内で、指定した行・列から、A1セル形式に変更する手段**
185
+ [getA1Notation() という関数](https://developers.google.com/apps-script/reference/spreadsheet/range#geta1notation)を使うことで、A1セル形式の文字列に変換できます。
186
+ ```
187
+ var ss = SpreadsheetApp.getActiveSpreadsheet();
188
+ var sheet = ss.getSheets()[0];
189
+ var range = sheet.getRange(2, 5);
190
+
191
+ Logger.log(range.getA1Notation());
192
+ // "E2"
193
+ ```
194
+
195
+ ・**隣接するセルを選択したときのセル分割**
196
+ Googleスプレッドシートの仕様として、隣接するセルをControlクリックで複数選択すると、1つのセルとして扱われてしまうことがあります。(少なくとも Windows10上のChromium Edgeではそうなっています)
197
+
198
+ 上記コードのgetSprittedRange()関数は、これを個別のセルに分割する関数です。
199
+ ```
200
+ function getSprittedRange(rangelist) {
201
+ // 戻り値(個別セル範囲)を格納するための配列
202
+ const output = [];
203
+ for (const range of rangelist.getRanges()) {
204
+ // RangeList が連続したセルの場合は、個別セル範囲に分割してoutput配列に追加
205
+ if (range.getHeight() != 1 || range.getWidth() != 1) {
206
+ for (let i = 1; i <= range.getHeight(); i++) {
207
+ for (let j = 1; j <= range.getWidth(); j++) {
208
+ output.push(range.getCell(i, j));
209
+ }
210
+ }
211
+ } else {
212
+ output.push(range);
213
+ }
214
+ }
215
+ return output;
216
+ }
217
+ ```