Salesforce CLIを使ったカスタムオブジェクトのインポート手順【トレイルヘッド環境での実践】


## はじめに

Salesforceの開発環境やトレイルヘッド環境でカスタムオブジェクトを手早く作成したいことはよくあります。UIからの手動設定も可能ですが、Salesforce CLIを使ったインポートなら設定を再利用でき、環境間の移行も容易になります。

この記事では、Salesforce CLIを使ってトレイルヘッド環境にカスタムオブジェクトをインポートする手順を解説します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/e19c642c-db4d-4086-a8fe-e482bef768a6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/e7769bea-34ad-49df-b16b-b1c20d96b0c8.png)

## 前提条件

| 項目 | 詳細 |
|------|------|
| Salesforce環境 | トレイルヘッド組織またはDeveloper Edition |
| 必要なツール | Visual Studio Code, Salesforce CLI, SFDX拡張機能 |
| 権限 | システム管理者権限 |

Salesforce CLI には、従来の sfdx コマンド体系と、現在推奨されている新しい sf コマンド体系の2種類があります。この記事ではsfコマンドを使用します。

## 1. 環境準備

### Salesforce CLIのインストール

まず、Salesforce CLIをインストールしましょう。

| ステップ | 内容 |
|---------|------|
| 1 | [Salesforce CLI公式サイト](https://developer.salesforce.com/tools/sfdxcli)からインストーラーをダウンロード |
| 2 | インストーラーを実行してSalesforce CLIをインストール |
| 3 | インストール確認のためターミナルで`sf --version`を実行 |

### Visual Studio Codeの設定

| ステップ | 内容 |
|---------|------|
| 1 | VS Codeをインストール (まだの場合) |
| 2 | Salesforce Extension Packをインストール |
| 3 | コマンドパレット(Ctrl+Shift+P)で「SF: Create Project」を選択 |
| 4 | 「Standard」を選択してプロジェクト名を入力 |

### Salesforce DXプロジェクトの作成

プロジェクトを作成せずにコマンドを実行すると「This directory does not contain a valid Salesforce DX project」エラーが発生します。必ずプロジェクトを作成しましょう。

| ステップ | コマンド | 説明 |
|---------|---------|------|
| 1 | `sf project generate -n MyProject` | 新しいSalesforce DXプロジェクトを作成 |
| 2 | `cd MyProject` | 作成したプロジェクトディレクトリに移動 |
| 3 | `dir` または `ls` | プロジェクト構造を確認（sfdx-project.jsonがあることを確認） |

これでプロジェクトのルートディレクトリに`sfdx-project.json`ファイルが作成され、Salesforce CLIがプロジェクトとして認識できるようになります。

## 2. トレイルヘッド組織への接続

| ステップ | 内容 | コマンド例 |
|---------|------|-----------|
| 1 | 認証フローを開始 | `sf org login web -a TrailheadOrg` |
| 2 | ブラウザが開くのでトレイルヘッドの認証情報でログイン | - |
| 3 | 接続確認 | `sf org display -o TrailheadOrg` |

## 3. カスタムオブジェクトのメタデータ作成

カスタムオブジェクトのメタデータファイルを作成します。

### メタデータファイルの構造

| ディレクトリ | ファイル | 説明 |
|------------|---------|------|
| force-app/main/default/objects/ | [オブジェクト名]__c/ | カスタムオブジェクトのルートディレクトリ |
| - | [オブジェクト名]__c.object-meta.xml | オブジェクト定義ファイル |
| force-app/main/default/objects/[オブジェクト名]__c/fields/ | [フィールド名]__c.field-meta.xml | カスタムフィールド定義ファイル |

### サンプルメタデータファイル

**Project__c.object-meta.xml**

```xml
<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
    <label>プロジェクト</label>
    <pluralLabel>プロジェクト</pluralLabel>
    <nameField>
        <type>Text</type>
        <label>プロジェクト名</label>
    </nameField>
    <deploymentStatus>Deployed</deploymentStatus>
    <sharingModel>ReadWrite</sharingModel>
    <enableReports>true</enableReports>
    <enableActivities>true</enableActivities>
    <description>顧客向けプロジェクト進捗管理用オブジェクト</description>
</CustomObject>
```

**Status__c.field-meta.xml**

```xml
<?xml version="1.0" encoding="UTF-8"?>
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
    <fullName>Status__c</fullName>
    <label>ステータス</label>
    <required>false</required>
    <type>Picklist</type>
    <valueSet>
        <restricted>true</restricted>
        <valueSetDefinition>
            <sorted>false</sorted>
            <value>
                <fullName>計画中</fullName>
                <default>true</default>
                <label>計画中</label>
            </value>
            <value>
                <fullName>進行中</fullName>
                <default>false</default>
                <label>進行中</label>
            </value>
            <value>
                <fullName>完了</fullName>
                <default>false</default>
                <label>完了</label>
            </value>
        </valueSetDefinition>
    </valueSet>
</CustomField>
```

### 他のフィールドタイプの例

#### 数値フィールド (Number__c.field-meta.xml)

```xml
<?xml version="1.0" encoding="UTF-8"?>
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
    <fullName>Number__c</fullName>
    <label>数値</label>
    <precision>18</precision>
    <required>false</required>
    <scale>2</scale>
    <type>Number</type>
    <unique>false</unique>
</CustomField>
```

#### 日付フィールド (Date__c.field-meta.xml)

```xml
<?xml version="1.0" encoding="UTF-8"?>
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
    <fullName>Date__c</fullName>
    <label>日付</label>
    <required>false</required>
    <type>Date</type>
</CustomField>
```

#### 標準オブジェクト参照フィールド (Account__c.field-meta.xml)

```xml
<?xml version="1.0" encoding="UTF-8"?>
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
    <fullName>Account__c</fullName>
    <label>取引先</label>
    <referenceTo>Account</referenceTo>
    <relationshipLabel>プロジェクト</relationshipLabel>
    <relationshipName>Projects</relationshipName>
    <required>false</required>
    <type>Lookup</type>
</CustomField>
```

#### 主従関係フィールド (Parent__c.field-meta.xml)

```xml
<?xml version="1.0" encoding="UTF-8"?>
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
    <fullName>Parent__c</fullName>
    <label>親プロジェクト</label>
    <referenceTo>Project__c</referenceTo>
    <relationshipLabel>サブプロジェクト</relationshipLabel>
    <relationshipName>SubProjects</relationshipName>
    <required>true</required>
    <type>MasterDetail</type>
    <writeRequiresMasterRead>false</writeRequiresMasterRead>
</CustomField>
```

### ファイル作成手順

| ステップ | 内容 |
|---------|------|
| 1 | プロジェクトディレクトリ内に `force-app/main/default/objects/Project__c` ディレクトリを作成 |
| 2 | 上記ディレクトリに `Project__c.object-meta.xml` ファイルを作成し、サンプルコードを貼り付け |
| 3 | `force-app/main/default/objects/Project__c/fields` ディレクトリを作成 |
| 4 | 上記ディレクトリに `Status__c.field-meta.xml` ファイルを作成し、サンプルコードを貼り付け |

> **重要**: ファイル名とファイル内の `<fullName>` 要素の値が一致していることを確認してください。例えば、`Status__c.field-meta.xml` ファイル内の `<fullName>Status__c</fullName>` のように一致させます。

## 4. メタデータのデプロイ

作成したメタデータファイルをトレイルヘッド環境にデプロイします。

| ステップ | コマンド | 説明 |
|---------|---------|------|
| 1 | `sf project deploy start -d force-app/main/default/objects/Project__c -o TrailheadOrg` | カスタムオブジェクトをデプロイ |
| 2 | `sf project deploy start -d force-app/main/default/objects/Project__c/fields -o TrailheadOrg` | カスタムフィールドをデプロイ |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/c691a51e-6bba-4eba-be7f-a5d6807d104b.png)

## 5. デプロイ結果の確認

| 確認方法 | 手順 |
|---------|------|
| Salesforce UI | 1. Setup > Object Manager を開く<br>2. 「プロジェクト」を検索して選択<br>3. オブジェクトとフィールドが作成されていることを確認 |
| SF CLI | `sf sobject describe -s Project__c -o TrailheadOrg` |


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/fe5e2127-b2cb-49ae-b004-2a69f9ad1b57.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/b269e7da-fe30-43e2-bd17-184804c26076.png)

## よくあるエラーと対処法

| エラー | 原因 | 対処法 |
|--------|------|--------|
| Invalid field: [フィールド名] | APIネーミング規則の違反 | フィールド名を修正（特殊文字の除去など） |
| Missing required field: [項目] | 必須メタデータが不足 | 該当するタグを追加 |
| Access denied | 権限不足 | システム管理者権限でログインし直す |
| Metadata file not found | ファイルパスの誤り | 正しいパスを指定してデプロイし直す |
| This directory does not contain a valid Salesforce DX project | プロジェクト未作成 | プロジェクトのルートディレクトリで実行する、またはプロジェクトを作成する |

## 応用：パッケージXMLを使った複数メタデータの一括デプロイ

複数のカスタムオブジェクト・フィールドを一度にデプロイする場合、package.xmlファイルを使用します。

**package.xml サンプル**

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Project__c</members>
        <name>CustomObject</name>
    </types>
    <types>
        <members>Project__c.Status__c</members>
        <members>Project__c.Account__c</members>
        <members>Project__c.Date__c</members>
        <members>Project__c.Number__c</members>
        <name>CustomField</name>
    </types>
    <version>58.0</version>
</Package>
```

| デプロイコマンド | 説明 |
|----------------|------|
| `sf project deploy start -x path/to/package.xml -o TrailheadOrg` | package.xmlに記載されたすべてのメタデータをデプロイ |

## 既存メタデータの取得と編集

既存の組織からメタデータを取得して編集することも可能です。

| ステップ | コマンド | 説明 |
|---------|---------|------|
| 1 | `sf project retrieve start -m CustomObject:Account -o TrailheadOrg` | 特定のメタデータを取得 |
| 2 | `sf project retrieve start -x manifest/package.xml -o TrailheadOrg` | package.xmlに指定されたメタデータを取得 |

## カスタムオブジェクトのテンプレート作成（CUIから）

Salesforce CLIを使って直接テンプレートを生成することもできます。

```bash
sf generate object -n Invoice__c --label "請求書" --plural "請求書" --dir force-app/main/default/objects
sf generate field -n Status__c --label "ステータス" --type Picklist -o Invoice__c --dir force-app/main/default/objects
```

## まとめ

メタデータAPIを活用することで、トレイルヘッド環境でも効率的にカスタムオブジェクトを作成・管理することができます。この手法を習得すれば、環境間の移行やバージョン管理も容易になり、より効率的なSalesforce開発が可能になります。

## 参考リンク

- [Salesforce メタデータAPI 開発者ガイド](https://developer.salesforce.com/docs/atlas.ja-jp.api_meta.meta/api_meta/meta_intro.htm)
- [Salesforce DX 開発者ガイド](https://developer.salesforce.com/docs/atlas.ja-jp.sfdx_dev.meta/sfdx_dev/sfdx_dev_intro.htm)
- [Trailhead: App Development with Salesforce DX](https://trailhead.salesforce.com/content/learn/modules/sfdx_app_dev)


## 免責事項
本記事の作成にあたり、文章や図解の生成にClaude Sonnetを、ファクトチェックにGensparkを活用しました。最終的な編集と確認は筆者が行っています。