C#からSpreadSheetの読み書きをする(2021年9月版)

# 【GCPでの手続き】

<details><summary>GCPでの手続き</summary><div>

## ①GCPプロジェクトを作成する
- [こちら](https://console.cloud.google.com/flows/enableapi?apiid=sheets.googleapis.com&hl=ja)にアクセス
  - 以下のどちらかの画面が出るので、進行して**プロジェクトを作成**する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/bd679f60-a5ea-f8f2-fb05-73775b8f300e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/1d54932c-8316-3093-493d-0d6d7c913a08.png)

## ②認証情報に進む
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/e2153be1-dd31-0e15-d18f-66b402e3ff5a.png)

## ③使用するAPIを指定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/9f34bc49-6ff6-6493-bf57-7124e4567d85.png)

#### ※上記画面への進み方が分からなくなった場合
- [GCP](https://console.cloud.google.com/)にアクセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/b42a4683-5ddf-b689-98ac-328db141e007.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/342f4828-c8da-1eef-80c5-91dd54115033.png)


## ④OAuth同意画面の設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/ead18da1-e4a0-d7da-91da-11f8956172fe.png)

## ⑤スコープを追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/732ee768-334a-843a-3f1e-aa078be5df99.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/b22192d0-7537-b4db-7d31-dea115ea408b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/199458d9-c341-5e33-3644-ea44f8de9100.png)


## ⑥OAuthクライアントID設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/07527840-15ae-094f-cf4e-2f15d36a2777.png)

## ⑦credentialsのダウンロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/43ee083e-2529-0c1b-19a4-27a6769bea5b.png)

## ⑧アプリを公開する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/ef47c8fc-9346-1ec4-2c6d-ceb117823452.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/42eb25c2-5d60-c845-6926-c7471e4cab49.png)

</div></details>

# 【スプレッドシートの準備】

<details><summary>スプレッドシートの準備</summary><div>

## ①スプレッドシートの用意
- [コチラ](https://docs.google.com/spreadsheets/u/0/create?usp=sheets_home&ths=true)からスプレッドシートを**新規作成**する
- シートに、値を適当に入れておく

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/88c5f391-9d63-4e15-de0c-6fd676388ebe.png)

## ②スプレッドシートの公開とID取得
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/127d2a19-dd30-9820-e5c2-dcaa7ca1908a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/3366ffb7-4e93-5ec0-58cc-985fe04208ea.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/b533a367-5d6a-da2e-e595-a9420a3a0fcd.png)


</div></details>

#【VisualStudioでのプロジェクト準備】

<details><summary>VisualStudioでのプロジェクト準備</summary><div>

## ①VisualStudioにて、Nugetパッケージマネージャーを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/9c345a37-0d83-66e6-40b9-9c4dd301ebc5.png)

## ②パッケージをインストール
- パッケージマネージャーにて下記を入力してEnter
    - `Install-Package Google.Apis.Sheets.v4`
- 「**Google.Apis.Sheets.v4 1.55.0.2371' が xxxxxxxx に正常にインストールされました**」と表示されたらOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/5b8839db-3ca9-e9b9-1ae7-e282e0f213f0.png)

# ③credentials.jsonの配置
- **GCP手続きの最後にダウンロードしたファイル**を`credentials.json`にリネームする
- VisualStudioにて、ソリューションエクスプローラーを開く
- `credentials.json`をD&Dで追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/972fec28-898b-7827-6475-a79cad23fd72.png)
    
- ↑D&Dでうまくいかない場合は、ファイルを選んで追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/a8aff4c3-0a0c-cc57-a952-2853cee26848.png)

# ④credentials.jsonのプロパティ設定
- プロパティを開き「`常にコピーする`」に変更

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/c16c67a8-3203-cd41-7cc1-c83dd1a39272.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/28d8982f-c4d7-f1ad-943f-08ea524bb37d.png)

</div></details>

#【C#ソースコード_SpreadSheetからの読み取り編】

<details><summary>C#ソースコード_SpreadSheetからの読み取り編</summary><div>

## ①VisualStudioにて、ソースコードをコピペ
- 以下をコピペする
    - ※ソースコードの冒頭の、`SpreadsheetId`に、**先ほど作成したSpreadSheet**のIDを入力する
        - **URL**の**「d/」**と**「/edit」**に挟まれた部分
        - `https://docs.google.com/spreadsheets/d/xxxxxxxxxxxxxxxxxxxxx_xxxxxxxxxxxxx/edit#gid=0`

```c#
using Google.Apis.Auth.OAuth2;
using Google.Apis.Sheets.v4;
using Google.Apis.Sheets.v4.Data;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;

class Program
{
    // https://docs.google.com/spreadsheets/d/xxxxxxxxxxxxxxxxxxxxx_xxxxxxxxxxxxx/edit#gid=0
    const string SpreadsheetId = "xxxxxxxxxxxxxxxxxxxxx_xxxxxxxxxxxxx";

    static void Main(string[] args)
    {
        // SheetsServiceを作成.
        SheetsService service = GetSheetsService();

        // 通信リクエストを作成.
        var request = service.Spreadsheets.Values.Get(SpreadsheetId,"シート1!1:1000");

        // 通信の同期実行. レスポンスを受け取る.
        ValueRange response = request.Execute();

        IList<IList<object>> values = response.Values;

        for (int i = 0;i < values.Count;i++)
        {
            for (int k = 0;k < values[i].Count;k++)
            {
                Console.WriteLine($"({i},{k}) = " + values[i][k]);
            }
        }
        Console.Read();
    }

    static SheetsService GetSheetsService()
    {
        var initializer = new BaseClientService.Initializer();
        initializer.HttpClientInitializer = GetUserCredential();
        initializer.ApplicationName = "test";
        var sheetsService = new SheetsService(initializer);

        return sheetsService;
    }

    static UserCredential GetUserCredential()
    {
        ClientSecrets clientSecrets;
        using (var stream = new FileStream("credentials.json",FileMode.Open,FileAccess.Read))
        {
            clientSecrets = GoogleClientSecrets.FromStream(stream).Secrets;
        }

        // Googleの認証通信開始.
        UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
            clientSecrets,
            new string[] { SheetsService.Scope.Spreadsheets },
            "user",
            CancellationToken.None,
            new FileDataStore("token.json",true)).Result;

        return credential;
    }
}
```



# ②実行する
- 実行すると、Googleアカウントのログインが求められるので、GCPで使用したアカウントでログインする
- その後、警告が表示されるが、左下の詳細をクリック
    - xxxに移動をクリック 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/8e39578d-cfc4-49d2-e271-ffd30107d69c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/a13a66fb-dd45-8319-c1c5-51032462493e.png)

# ③コンソールにて表示された事を確認！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/9e580176-70bc-f1e9-b023-60f9df37db17.png)

</div></details>

#【C#ソースコード_SpreadSheetへの書き出し編】

<details><summary>C#ソースコード_SpreadSheetへの書き出し編</summary><div>


## ①Main関数の置き換え
- Main関数を以下に置き換える

```C#
static void Main(string[] args)
{
    // 書き込む値.
    var values = new List<IList<object>>()
    {
        // 1行目に書き込む値.
        new List<object>
        {
            1,2,3,4,5,
        },

        // 2行目に書き込む値.
        new List<object>
        {
            "6","7","8","9","10",
        },

        // 3行目に書き込む値.
        new List<object>
        {
            DateTime.Now
        }
    };

    // リクエストボディを作成.
    var requestBody = new ValueRange() { Values = values };

    // SheetsServiceを作成.
    SheetsService service = GetSheetsService();

    // 通信リクエストを作成.
    var request = service.Spreadsheets.Values.Update(requestBody,SpreadsheetId,"シート1!1:1000");
    request.ValueInputOption = SpreadsheetsResource.ValuesResource.UpdateRequest.ValueInputOptionEnum.USERENTERED;

    // 通信実行.
    var result = request.Execute();
}
```

## ②SpreadSheetに値が反映された事を確認！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212240/9924870a-cad1-8b86-8784-783b5ef71f46.png)


</div></details>