[Google Sheets API] 「シートと範囲を保護」を追加・更新・削除する

Google Sheets API v4（Java）を使用して、
スプレットシートのシート単位の保護と、セル範囲の保護の追加・更新・削除
についてご紹介します。

:::note info
APIを利用する環境の準備から始める場合や、コードを実行する際は、
[⧉[Google Sheets API] Google Sheets API v4をJavaで操作する](https://qiita.com/doran/items/3d43f776188b2281044c)
を参照ください。
```
例：requests.add(moveDimension(sheetId)); //実行したいリクエストのMethodを指定
```
:::

:::note info
その他のGoogle Sheets APIは、下記の記事を参照ください。
[⧉[Google Sheets API] JavaでスプレットシートのメニューとAPIを関連づけてみた](https://qiita.com/doran/items/2f6f8932b994fbd1a170)
:::

|No||目次|
|---|---|---|
|1||[「シートと範囲を保護」を追加](#1-シートと範囲を保護を追加)|
||1|[ シートを保護](#11-シートを保護)|
||2|[ 範囲を保護](#12-範囲を保護)|
||3|[ 設定された保護IDを取得](#13-設定された保護idを取得)|
|2||[「シートと範囲を保護」を更新](#2-シートと範囲を保護を更新)|
|3||[「シートと範囲を保護」を削除](#3-シートと範囲を保護を削除)|


## 1. 　「シートと範囲を保護」を追加
シートとセル範囲を指定して保護することができます。

**編集の際の動作**
保護されたシートまたは範囲を編集した際の動作を指定できます。

・この範囲を編集するときに警告を表示する
　　保護されたシートまたは範囲を編集した際に下記のメッセージが表示されます。
　　編集自体は可能です。
　　<img width="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/56df6006-950e-7682-5eaa-28a5cf185a96.png">
　　ProtectedRangeクラスのsetWarningOnlyメソッドでtrueを指定します。
  
・この範囲を編集できるユーザーを制限する
　　保護されたシートまたは範囲は、指定されたユーザーのみ編集できます。
　　ユーザーの指定がなくとも、オーナーは編集できます。
　　ProtectedRangeクラスのsetWarningOnlyメソッドでfalseを指定します。(デフォルト)
  
### 1.1. シートを保護
シートに対して保護を設定することができます。
保護したシート内の一部のセルのみ保護から外すこともできます。

**サンプル コード**
シートの保護をしたい場合は、範囲を指定するProtectedRangeクラスのsetRangeメソッドで
シートIDのみを指定します。
```java
public Request addProtectedRange(Integer sheetId) {
    Request request = new Request();

    AddProtectedRangeRequest r = new AddProtectedRangeRequest();
    ProtectedRange protectedRange = new ProtectedRange();

    //この保護範囲の説明。
    protectedRange.setDescription("範囲保護の説明だよ");

    //編集可能なユーザーの指定
    //編集アクセス権を持つユーザーのメールアドレスのみ設定できます。
    Editors editor = new Editors();
    List<String> users = new ArrayList<>();
    users.add("******@*****.iam.gserviceaccount.com");
    editor.setUsers(users);
    protectedRange.setEditors(editor);

    //保護する範囲（この場合はシート）
    GridRange sheet = new GridRange(); //枠線の範囲
    sheet.setSheetId(sheetId);         //シートID
    protectedRange.setRange(sheet);    //保護する範囲（シートIDだけ指定）

    //保護するシート内の指定したセル範囲のみ保護が解除されます。
    List<GridRange> unprotectedRanges = new ArrayList<>();
    GridRange grid = new GridRange(); //枠線の範囲
    grid.setSheetId(sheetId);
    grid.setStartRowIndex(1);         //開始行(0スタート)
    grid.setEndRowIndex(4);           //終了行(1スタート)
    grid.setStartColumnIndex(1);      //開始列(0スタート)
    grid.setEndColumnIndex(3);        //終了列(1スタート)
    unprotectedRanges.add(grid);
    protectedRange.setUnprotectedRanges(unprotectedRanges);

    //この範囲を編集するときに警告を表示する 
    protectedRange.setWarningOnly(true);
    
    r.setProtectedRange(protectedRange);	//追加する保護範囲

    request.setAddProtectedRange(r);
    return request;
}
```
**実行結果**
シートが保護されました。
　　<img width="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/e6e7fdb9-34b2-f0cf-5228-2efd1a0e3900.png">
　　<img width="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/0d3bc596-d392-064b-9bc0-dc0bb43d0a86.png">

### 1.2. 範囲を保護
指定したシートの指定範囲を保護することができます。

ProtectedRangeクラスのsetRangeメソッドにセルの範囲を「範囲を保護」になります。
その他は「シートを保護」と変わりません。
ただし、保護シート内のセル範囲を保護から除外する範囲を指定する
ProtectedRangeクラスのsetUnprotectedRangesは使用できません。

**サンプル コード**
```java
public Request addProtectedRange(Integer sheetId) {
    Request request = new Request();

    AddProtectedRangeRequest r = new AddProtectedRangeRequest();
    ProtectedRange protectedRange = new ProtectedRange();

    //編集可能なユーザーの指定
    //編集アクセス権を持つユーザーのメールアドレスのみ設定できます。
    Editors editor = new Editors();
    List<String> users = new ArrayList<>();
    users.add("******@*****.iam.gserviceaccount.com");
    editor.setUsers(users);
    protectedRange.setEditors(editor);

    //保護する範囲
    GridRange grid = new GridRange(); //枠線の範囲
    grid.setSheetId(sheetId);
    grid.setStartRowIndex(1);         //開始行(0スタート)
    grid.setEndRowIndex(4);           //終了行(1スタート)
    grid.setStartColumnIndex(1);      //開始列(0スタート)
    grid.setEndColumnIndex(3);        //終了列(1スタート)
    protectedRange.setRange(grid);    //保護する範囲（シートIDだけ指定）
    
    r.setProtectedRange(protectedRange);	//追加する保護範囲

    request.setAddProtectedRange(r);
    return request;
}
```

### 1.3. 設定された保護IDを取得
保護を設定や更新した後、保護IDが取得できます。
この保護IDを使って、保護の更新と削除を行います。

**サンプル コード**
```java
//batchUpdateを実行
BatchUpdateSpreadsheetResponse update = sheets.batchUpdate(fileId, body).execute();

//実行後にレスポンスを取得する
for(Response response : update.getReplies()) {

    //AddProtectedRangeRequestに対するレスポンスを取得
    AddProtectedRangeResponse res = response.getAddProtectedRange();
    if(res==null)  continue;

    //保護IDを取得
    return res.getProtectedRange().getProtectedRangeId();
}
```

## 2. 「シートと範囲を保護」を更新
設定されている「シートと範囲を保護」を更新します。

更新したい保護IDを指定して更新します。
保護IDの取得は、前述の[設定された保護IDを取得](#13-設定された保護idを取得)を参照してください。

更新したい保護IDの指定と、更新するフィールドの指定以外は
[「シートと範囲を保護」を追加](#1-シートと範囲を保護を追加)と同じです。

**更新するフィールドの指定**
更新したいフィールドを文字列で設定します。設定がない場合は更新されません。
複数のフィールドを指定したい場合は、「,」で繋げます。
<font color="red">編集可能なユーザーは、追加ではなく更新なので設定済みのリストは
上書きされます。</font>
|フィールド|内容|
|---|---|
|description|保護の説明|
|editors|編集可能なユーザー|
|range|保護する範囲|
|unprotectedRanges|シート保護から除外する範囲|
|warningOnly|編集の際の動作|

**サンプル コード**
保護範囲の説明を更新します。
更新する保護IDの指定は必須です。
```java
public static Request updateProtectedRange() {
    Request request = new Request();

    ProtectedRange protectedRange = new ProtectedRange();
    protectedRange.setDescription("説明の更新");      //この保護範囲の説明。
    protectedRange.setProtectedRangeId(539077030);  //更新する保護IDを指定
    
    UpdateProtectedRangeRequest r = new UpdateProtectedRangeRequest();
    r.setProtectedRange(protectedRange);
    r.setFields("description");
    
    request.setUpdateProtectedRange(r);
    return request;
}
```

## 3. 　「シートと範囲を保護」を削除
設定されている「シートと範囲を保護」を削除します。

削除したい保護IDを指定して削除します。
保護IDの取得は、前述の[設定された保護IDを取得](#13-設定された保護idを取得)を参照してください。

**サンプル コード**
```java
public Request deleteProtectedRange() {
    Request request = new Request();

    DeleteProtectedRangeRequest r = new DeleteProtectedRangeRequest();
    r.setProtectedRangeId(1683825936);	//保護IDを指定
    
    request.setDeleteProtectedRange(r);
    return request;
}
```
<br>
おしまい。。