フィルタを使用してデータの可視性を管理する

このドキュメントでは、フィルタを使用してスプレッドシートに表示されるデータを並べ替えたり、フィルタしたりする方法について説明します。

フィルタを使用すると、スプレッドシートを表示する際に表示されるデータを並べ替えたり、フィルタしたりできます。フィルタは、スプレッドシートのデータ値を変更しません。フィルタを使用すると、情報を一時的に非表示にしたり、並べ替えたりできます。フィルタがオンになっている間は、指定したフィルタ条件に一致するデータは表示されません。フィルタ表示を使用すると、名前付きのフィルタを複数保存して、いつでも切り替えることができます。

Google Sheets API リクエストで返されるデータをフィルタするには、DataFilter オブジェクトを使用します。詳細については、メタデータの読み取り、書き込み、検索をご覧ください。

フィルタのユースケース

フィルタのユースケースの例を次に示します。

  • 特定の列でデータを並べ替えます。たとえば、ユーザー レコードを姓で並べ替えます。
  • 特定の条件を満たすデータを非表示にします。たとえば、2 年以上前のすべてのレコードを非表示にします。
  • 特定の値を満たすデータを非表示にします。たとえば、ステータスが「closed」の問題をすべて非表示にします。

基本フィルタ

スプレッドシートの BasicFilter オブジェクトは、スプレッドシートを表示するたびに適用されるデフォルトのフィルタです。スプレッドシートの シートごとに設定できる基本フィルタは 1 つのみです。基本フィルタをオフにするには、基本フィルタをクリアします。これにより、フィルタとそのすべての設定がスプレッドシートから削除されます。同じフィルタを再度有効にする場合は、条件を再度設定する必要があります。

基本フィルタを管理する

基本フィルタを設定またはクリアするには、適切なリクエスト タイプで spreadsheets.batchUpdate メソッドを使用します。

基本フィルタを一覧表示するには、spreadsheets.get メソッドを使用し、fields URL パラメータを sheets/basicFilter に設定します。次の spreadsheets.get コードサンプルは、フィールド マスクを含む Google スプレッドシートの URL を示しています。

GET https://sheets.googleapis.com/v4/spreadsheets/SPREADSHEET_ID?fields=sheets/basicFilter

フィルタ表示

FilterView は、いつでもオン / オフを切り替えられる名前付きフィルタです。シートには複数のフィルタ表示を保存できますが、一度に適用できるのは 1 つだけです。シートには基本フィルタと複数のフィルタ表示の両方を含めることもできますが、同じデータ範囲に両方を同時に適用することはできません。

フィルタ ビューのユースケース

フィルタ ビューのユースケースの例を次に示します。

  • データを表示するときに切り替えたいフィルタが複数ある。
  • スプレッドシートの編集権限がないが、フィルタを適用したい場合。このような場合は、自分だけが見える一時的なフィルタ表示を作成できます。
  • スプレッドシートを共有するユーザーごとにデータを異なる方法で表示したい場合。スプレッドシートの URL で spreadsheetIdfilterViewId を指定することで、適用するフィルタ ビューを指定できます。これを行うには、フィルタ表示の作成時にレスポンスで返された filterViewId を使用します。

    次のコードサンプルは、フィルタ ビューを含むスプレッドシートの URL を示しています。

    https://docs.google.com/spreadsheets/d/SPREADSHEET_ID/edit#gid=0&fvid=FILTER_VIEW_ID

フィルタビューを管理する

フィルタ ビューの作成、複製、変更、削除を行うには、適切なリクエスト タイプで spreadsheets.batchUpdate メソッドを使用します。

すべてのフィルタ ビューを一覧表示するには、spreadsheets.get メソッドを使用し、fields URL パラメータを sheets/filterViews に設定します。次の spreadsheets.get コードサンプルは、フィールド マスクを含むスプレッドシートの URL を示しています。

GET https://sheets.googleapis.com/v4/spreadsheets/SPREADSHEET_ID?fields=sheets/filterViews

フィルタの JSON 表現

次のコードサンプルは、FilterView オブジェクトの JSON 表現を示しています。BasicFilter オブジェクトは、filterViewId フィールドと title フィールドがなく、名前付き範囲を使用できない点を除いて同じです。

{
  "filterViewId": number,
  "title": string,
  "range": {
    object(GridRange)
  },
  "namedRangeId": string,
  "sortSpecs": [
    {
      object(SortSpec)
    }
  ],
  "criteria": {
    string: {
      object(FilterCriteria)
    },
    ...
  }
}

販売データのサンプル

このドキュメントの以降の部分では、次のサンプル販売データ テーブルを参照します。

表 1. 販売データのサンプル
A B C D E F G
1 アイテムのカテゴリ モデル番号 費用 数量 地域 営業担当者 発送日
2 ホイール W-24 $20.50 4 西 Beth 2016 年 3 月 1 日
3 ドア D-01X $15.00 2 Amir 2016 年 3 月 15 日
4 フレーム FR-0B1 $34.00 8 ハンナ 2016 年 3 月 12 日
5 パネル P-034 $6.00 4 Devyn 2016 年 3 月 15 日
6 パネル P-052 11.50 ドル 7 エリック 2016 年 5 月 16 日
7 ホイール W-24 $20.50 11 Sheldon 2016 年 4 月 30 日
8 エンジン ENG-0161 $330.00 2 Jessie 2016 年 7 月 2 日

並べ替えの仕様

フィルタには複数の並べ替え仕様を設定できます。これらの仕様は、データの並べ替え方法を決定し、指定された順序で適用されます。SortSpec.dimensionIndex 属性は、並べ替えを適用する列のインデックスを指定します。

次のコードサンプルは、並べ替えの仕様を示しています。

[
  {
    "dimensionIndex": 3,
    "sortOrder": "ASCENDING"
  },
  {
    "dimensionIndex": 6,
    "sortOrder": "ASCENDING"
  }
]

サンプル販売データに適用すると、この仕様ではまず「数量」列で並べ替えが行われ、2 つの行の数量が同じ場合は「出荷日」で並べ替えが行われます。

表 2. 2 つの列で並べ替えられた販売データ
A B C D E F G
1 アイテムのカテゴリ モデル番号 費用 数量 地域 営業担当者 発送日
2 ドア D-01X $15.00 2 Amir 2016 年 3 月 15 日
3 エンジン ENG-0161 $330.00 2 Jessie 2016 年 7 月 2 日
4 ホイール W-24 $20.50 4 西 Beth 2016 年 3 月 1 日
5 パネル P-034 $6.00 4 Devyn 2016 年 3 月 15 日
6 パネル P-052 11.50 ドル 7 エリック 2016 年 5 月 16 日
7 フレーム FR-0B1 $34.00 8 ハンナ 2016 年 3 月 12 日
8 ホイール W-24 $20.50 11 Sheldon 2016 年 4 月 30 日

フィルタ条件

FilterCriteria オブジェクトは、基本フィルタまたはフィルタビューでスプレッドシートのデータが表示されるか非表示になるかを決定します。各条件は、特定の列の値に依存します。フィルタ条件は、キーが列インデックスで値が条件であるマップとして指定します。

ブール値 condition を使用して指定された条件の場合、値が表示されるには条件が true である必要があります。条件は hiddenValues をオーバーライドしません。値が hiddenValues にリストされている場合、その値のすべての一致は引き続き非表示になります。

次のコードサンプルは、フィルタ条件マップを示しています。

{
  0: {
    'hiddenValues': ['Panel']
  },
  6: {
    'condition': {
      'type': 'DATE_BEFORE',
      'values': {
        'userEnteredValue': '4/30/2016'
      }
    }
  }
}

サンプル販売データに適用すると、この条件では、[商品カテゴリ] 列の値が [パネル] ではなく、[出荷日] 列の値が [2016 年 4 月 30 日] より前の行のみが表示されます。

表 3. フィルタ条件を使用した販売データ
A B C D E F G
1 アイテムのカテゴリ モデル番号 費用 数量 地域 営業担当者 発送日
2 ホイール W-24 $20.50 4 西 Beth 2016 年 3 月 1 日
3 ドア D-01X $15.00 2 Amir 2016 年 3 月 15 日
4 フレーム FR-0B1 $34.00 8 ハンナ 2016 年 3 月 12 日

フィルタビューのコードサンプル

次のコードサンプルは、フィルタ ビューを作成して複製し、サンプル販売データを使用して複製したバージョンを更新する方法を示しています。

Java

sheets/snippets/src/main/java/SheetsFilterViews.java
/*
 * Dependencies (Maven):
 * com.google.apis:google-api-services-sheets:v4-rev20220927-2.0.0
 * com.google.auth:google-auth-library-oauth2-http:1.19.0
 */

import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.sheets.v4.Sheets;
import com.google.api.services.sheets.v4.SheetsScopes;
import com.google.api.services.sheets.v4.model.*;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.*;

public class SheetsFilterViews {

    public static void main(String... args) {
        filterViews("1CM29gwKIzeXsAppeNwrc8lbYaVMmUclprLuLYuHog4k");
    }

    public static void filterViews(String spreadsheetId) {
        try {
            // Load pre-authorized user credentials from the environment.
            // TODO(developer) - See https://developers.google.com/identity for guides on implementing OAuth2.
            GoogleCredentials credentials = GoogleCredentials.getApplicationDefault()
                    .createScoped(Collections.singleton(SheetsScopes.SPREADSHEETS));

            Sheets service = new Sheets.Builder(
                    GoogleNetHttpTransport.newTrustedTransport(),
                    GsonFactory.getDefaultInstance(),
                    new HttpCredentialsAdapter(credentials))
                    .setApplicationName("Sheets Filter Views Sample")
                    .build();

            // --- Step 1: Add Filter View ---
            GridRange myRange = new GridRange()
                    .setSheetId(0)
                    .setStartRowIndex(0)
                    .setStartColumnIndex(0);

            // Construct Criteria for Column 0 (Hidden Values)
            FilterCriteria criteria0 = new FilterCriteria()
                    .setHiddenValues(Collections.singletonList("Panel"));

            // Construct Criteria for Column 6 (Date Condition)
            ConditionValue dateValue = new ConditionValue().setUserEnteredValue("4/30/2016");
            BooleanCondition dateCondition = new BooleanCondition()
                    .setType("DATE_BEFORE")
                    .setValues(Collections.singletonList(dateValue));
            FilterCriteria criteria6 = new FilterCriteria().setCondition(dateCondition);

            // Map criteria to column indices (Note: keys are Strings in Java map)
            Map<String, FilterCriteria> criteriaMap = new HashMap<>();
            criteriaMap.put("0", criteria0);
            criteriaMap.put("6", criteria6);

            FilterView filterView = new FilterView()
                    .setTitle("Sample Filter")
                    .setRange(myRange)
                    .setSortSpecs(Collections.singletonList(
                            new SortSpec().setDimensionIndex(3).setSortOrder("DESCENDING")
                    ))
                    .setCriteria(criteriaMap);

            // --- Step 1: Add Filter View ---
            // (Request construction remains the same)
            // ...
            AddFilterViewRequest addFilterViewRequest = new AddFilterViewRequest().setFilter(filterView);

            BatchUpdateSpreadsheetRequest batchRequest1 = new BatchUpdateSpreadsheetRequest()
                    .setRequests(Collections.singletonList(new Request().setAddFilterView(addFilterViewRequest)));

            BatchUpdateSpreadsheetResponse response1 = service.spreadsheets()
                    .batchUpdate(spreadsheetId, batchRequest1)
                    .execute();

            if (response1.getReplies() == null || response1.getReplies().isEmpty()) {
                System.err.println("Error: No replies returned from AddFilterView request.");
                return;
            }

            Response reply1 = response1.getReplies().get(0);
            if (reply1.getAddFilterView() == null || reply1.getAddFilterView().getFilter() == null) {
                 System.err.println("Error: Response did not contain AddFilterView data.");
                 return;
            }

            int filterId = reply1.getAddFilterView().getFilter().getFilterViewId();

            // --- Step 2: Duplicate Filter View ---
            DuplicateFilterViewRequest duplicateRequest = new DuplicateFilterViewRequest()
                    .setFilterId(filterId);

            BatchUpdateSpreadsheetRequest batchRequest2 = new BatchUpdateSpreadsheetRequest()
                    .setRequests(Collections.singletonList(new Request().setDuplicateFilterView(duplicateRequest)));

            BatchUpdateSpreadsheetResponse response2 = service.spreadsheets()
                    .batchUpdate(spreadsheetId, batchRequest2)
                    .execute();

            if (response2.getReplies() == null || response2.getReplies().isEmpty()) {
                 System.err.println("Error: No replies returned from DuplicateFilterView request.");
                 return;
            }

            Response reply2 = response2.getReplies().get(0);
            if (reply2.getDuplicateFilterView() == null || reply2.getDuplicateFilterView().getFilter() == null) {
                System.err.println("Error: Response did not contain DuplicateFilterView data.");
                return;
            }

            int newFilterId = reply2.getDuplicateFilterView().getFilter().getFilterViewId();

            // --- Step 3: Update Filter View ---
            // Extract the new ID from the duplicate response
            int newFilterId = response2.getReplies().get(0)
                    .getDuplicateFilterView().getFilter().getFilterViewId();

            // Create update criteria
            Map<String, FilterCriteria> updateCriteriaMap = new HashMap<>();
            updateCriteriaMap.put("0", new FilterCriteria()); // Empty criteria

            ConditionValue numValue = new ConditionValue().setUserEnteredValue("5");
            BooleanCondition numCondition = new BooleanCondition()
                    .setType("NUMBER_GREATER")
                    .setValues(Collections.singletonList(numValue));
            updateCriteriaMap.put("3", new FilterCriteria().setCondition(numCondition));

            FilterView updateFilterView = new FilterView()
                    .setFilterViewId(newFilterId)
                    .setTitle("Updated Filter")
                    .setCriteria(updateCriteriaMap);

            UpdateFilterViewRequest updateRequest = new UpdateFilterViewRequest()
                    .setFilter(updateFilterView)
                    .setFields("criteria,title");

            BatchUpdateSpreadsheetRequest batchRequest3 = new BatchUpdateSpreadsheetRequest()
                    .setRequests(Collections.singletonList(new Request().setUpdateFilterView(updateRequest)));

            BatchUpdateSpreadsheetResponse response3 = service.spreadsheets()
                    .batchUpdate(spreadsheetId, batchRequest3)
                    .execute();

            System.out.println(response3.toPrettyString());

        } catch (IOException | GeneralSecurityException e) {
            System.err.println("An error occurred: " + e);
        }
    }
}

Python

sheets/snippets/sheets_filter_views.py
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


def filter_views(spreadsheet_id):
  """
  Creates the batch_update the user has access to.
  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """
  creds, _ = google.auth.default()
  # pylint: disable=maybe-no-member
  try:
    service = build("sheets", "v4", credentials=creds)

    my_range = {
        "sheetId": 0,
        "startRowIndex": 0,
        "startColumnIndex": 0,
    }
    addfilterviewrequest = {
        "addFilterView": {
            "filter": {
                "title": "Sample Filter",
                "range": my_range,
                "sortSpecs": [{
                    "dimensionIndex": 3,
                    "sortOrder": "DESCENDING",
                }],
                "criteria": {
                    0: {"hiddenValues": ["Panel"]},
                    6: {
                        "condition": {
                            "type": "DATE_BEFORE",
                            "values": {"userEnteredValue": "4/30/2016"},
                        }
                    },
                },
            }
        }
    }

    body = {"requests": [addfilterviewrequest]}
    addfilterviewresponse = (
        service.spreadsheets()
        .batchUpdate(spreadsheetId=spreadsheet_id, body=body)
        .execute()
    )

    duplicatefilterviewrequest = {
        "duplicateFilterView": {
            "filterId": addfilterviewresponse["replies"][0]["addFilterView"][
                "filter"
            ]["filterViewId"]
        }
    }

    body = {"requests": [duplicatefilterviewrequest]}
    duplicatefilterviewresponse = (
        service.spreadsheets()
        .batchUpdate(spreadsheetId=spreadsheet_id, body=body)
        .execute()
    )

    updatefilterviewrequest = {
        "updateFilterView": {
            "filter": {
                "filterViewId": duplicatefilterviewresponse["replies"][0][
                    "duplicateFilterView"
                ]["filter"]["filterViewId"],
                "title": "Updated Filter",
                "criteria": {
                    0: {},
                    3: {
                        "condition": {
                            "type": "NUMBER_GREATER",
                            "values": {"userEnteredValue": "5"},
                        }
                    },
                },
            },
            "fields": {"paths": ["criteria", "title"]},
        }
    }

    body = {"requests": [updatefilterviewrequest]}
    updatefilterviewresponse = (
        service.spreadsheets()
        .batchUpdate(spreadsheetId=spreadsheet_id, body=body)
        .execute()
    )
    print(str(updatefilterviewresponse))
  except HttpError as error:
    print(f"An error occurred: {error}")


if __name__ == "__main__":
  # Pass: spreadsheet_id
  filter_views("1CM29gwKIzeXsAppeNwrc8lbYaVMmUclprLuLYuHog4k")