Airtableの使い方:基本と、業務で使ってつまずく3つのこと

Airtableでは、データをまとめて置く場所を「ベース」と呼びます。ベース(base)は database の略で、1つの仕事や業務の流れに必要な情報をまとめて入れておく場所です。この記事では、Airtableの基本の使い方を説明したうえで、弊社が業務の仕組みからAirtableを使ってきて実際につまずいた3つのことと、その直し方を書きます。
基本の説明はAirtableの公式ヘルプとAPIのドキュメントに、つまずきは弊社の本番で確かめた記録にもとづいています。
この記事の結論
- ベースの中に表(テーブル)を作り、表どうしをリンクでつなぐのが基本の形です。
- 同じ表に、並べ方や絞り方の違う「ビュー」をいくつも作れます。
- 弊社がAPIや自動化から使っていてつまずいたのは、リンク項目の絞り込み、
TODAY()の日付、単一選択の値の3つです。 - APIは、1つのベースにつき毎秒5リクエストまでです。
Airtableの基本
ベース・表・レコード・フィールド
ベースは、1つの仕事や業務に必要な情報をまとめて入れておく、データのまとまりです。ベースの中には表(テーブル)をいくつも作れます。表の1行がレコードで、レコードの中身はフィールド(列)ごとに入ります。
ビュー
ビューは、表のデータの見方・並べ方の1つです。同じ表に対して、目的ごとに別のビューを作れます。公式ヘルプでは、グリッド、フォーム、カレンダー、ギャラリー、カンバン、タイムライン、リスト、ガントの種類が挙げられています。
リンクで表どうしをつなぐ
案件と作業、イベントと参加者のように、関係のある情報は別々の表に分けて、リンクでつなぎます。リンクは、2つの別の表のレコードの間にも、同じ表の中のレコードどうしにも作れます。
基本の使い方
- 業務ごとにベースを1つ作ります。
- 1つの表には1種類のものだけを入れます。たとえば顧客、予約、担当者は別々の表にします。
- 予約の表から顧客の表へ、のようにリンクでつなぎます。同じ情報を2か所に書かずに済みます。
- 「今日の予約」「担当者ごと」のように、見る目的ごとにビューを作ります。
ここまでは画面の操作だけでできます。弊社がつまずいたのは、APIや自動化ツールからAirtableを読み書きするようになってからでした。
業務の仕組みから使って分かった、つまずく3つのこと
1. リンク項目は、レコードIDでは絞り込めない
APIでレコードを取ると、リンク項目の値はレコードID(rec で始まる文字列)の配列で返ってきます。ところが、filterByFormula の数式の中では、リンク項目は相手の表のプライマリフィールド(一番左の列)の値、つまり表示名として扱われます。そのため、次のようにレコードIDで探すと、相手が実在していても0件になります。
FIND('recXXXXXXXXXXXXXX', ARRAYJOIN({物件}))
表示名で探すと当たります。ただし FIND は部分一致なので、FIND('物件A', ARRAYJOIN({物件})) と書くと「物件AB」にも当たります。名前がまるごと一致したときだけ当てるには、区切り記号で前後を挟みます。
FIND(',物件A,', ',' & ARRAYJOIN({物件}, ',') & ',')
弊社では、この書き方のせいで、つながっているはずの相手が「見つからない」と判定されていました。直し方は2つです。
- 確実なのは、相手のレコードをIDで1件取得して、そこにある逆向きのリンク項目を読む方法です。自分を指しているレコードのIDが並んでいます。
- 絞り込みたい表の件数が多くなければ、条件を付けずに取ってから、手元のプログラムでレコードIDを照らし合わせる方法もあります。
- 数式で絞るなら、上のように表示名を区切り記号で挟んで探します。ただし、同じ表示名のレコードがあると、どちらにも当たります。
0件が返ったときは、「無い」と決めつける前に、当たるはずの組み合わせで件数を確かめてください。詳しい経緯はAirtable filterByFormulaでリンク先のレコードIDが0件になる原因と回避策に書いています。
2. filterByFormula の TODAY() は、日本時間の日付ではない
APIに渡す filterByFormula の TODAY() は、国際標準時の日付で評価されました。TODAY() の日付が変わるのは日本時間の9時です。そのため、日本時間の0時から9時になるまでは、前日の日付が返ります。弊社の予約の同期は深夜0時台に動くため、この時間に判定を誤りました。昼に試すと再現しないので、気づきにくいずれです。
弊社では、日付の区切りを数式の TODAY() に任せず、プログラムの側で日本時間から計算して、国際標準時の日時として数式に渡すように決めています。たとえば日本時間の9月13日0時は、国際標準時では9月12日15時です。
IS_AFTER({start_at}, '2026-09-12T15:00:00.000Z')
3. 単一選択に、決めていない値を書き込むと弾かれる
単一選択のフィールドに、選択肢として決めていない値をAPIで書き込むと、422 で INVALID_MULTIPLE_CHOICE_OPTIONS が返り、書き込みは失敗します。弊社では、AIのモデルを入れ替えたら、選択肢に無い言葉を出すようになり、この失敗が起きていました。自動化の処理の側は「成功」と表示されたままで、書き込みだけが落ちていました。
単一選択を空にしたいときも注意が必要です。空文字 "" を送ると422になりました。空にするときは null を送ります(弊社では typecast: true と一緒に送って空にできました)。
APIには typecast という指定があります。公式ドキュメントでは、文字列の値から自動で型の変換を試みるもので、データを守るために既定では無効、と説明されています。弊社では、typecast を付けて書き込むことで、まだ無い選択肢を作ったことがあります。打ち間違いの値でも選択肢が増えてしまう点には注意が要ります。ただし、書き込みに使う鍵(トークン)に選択肢を作る権限が無いと、typecast を付けても422のままでした。AIの出力の件は、決めた選択肢を先にAIへ渡して、その中から選ばせて直しました。
もう1つ:APIの上限
公式ドキュメントでは、APIは1つのベースにつき毎秒5リクエストまでです。トークンごとにも毎秒50リクエストの上限があります。超えると 429 が返り、次のリクエストが通るまで30秒待つ必要があります。まとめて書き込むときは、間を空けて送ります。
まとめ
- ベースの中に表を作り、1つの表には1種類のものだけを入れて、表どうしをリンクでつなぎます。
- 見る目的ごとにビューを作ります。
- リンク項目は数式の中ではレコードIDで探せません。相手のレコードから逆向きのリンク項目を読むか、表示名を区切り記号で挟んで探します。
TODAY()は国際標準時の日付です。日本時間の区切りはプログラムの側で作ります。- 単一選択には、決めた選択肢の値だけを書き込みます。空にするときは
nullを送ります。
参考にした公式ドキュメント






