Salesforce metadataで項目の一括作成

# XMLで複数のカスタム項目を作りたい
- 画面でやるのが面倒すぎる
- 超参考資料. この投稿がないと謎に包まれていたメタデータのデプロイでした

https://quanz.co.jp/blog/salesforce/951/

## (追記) そもそもXMLを作るのが面倒すぎる
- Google SheetのApps Scriptを使えば、それなりに楽に作れることがわかりました
- フィールドタイプごとに一旦はScriptを分けていますが、1 Scriptで処理を分けてやっちゃっても良いかと思います
- フィールド作成、プロファイルの権限付与、ページレイアウト配置までをカバーするコードを下記のGitHubにPushしました。参考にどうぞ。

https://github.com/mkzyk/SalesforceMetaDataXmlGeneratorGS/tree/main

## 1. 組織にVS Codeから接続
- その後、Org Browserから指定オブジェクトのメタデータをPullしておく

## 2. 取得したオブジェクトの`fileds`メタデータを確認
- 商談であれば、`force-app/main/default/objects/Opportunity/fields`にある

## 3. Terminalを開く
- 下記コマンドを実行

```
sfdx force:source:convert
```

- これで元々のソースファイルからメタデータの変換ができる

## 4. 作成されたメタデータコピーを確認
- `<fields></fields>`で囲まれている部分を探して、追加する
- これが、対象オブジェクトの存在する項目一覧となる
- 例は下記にあるが、わかりにくい

https://developer.salesforce.com/docs/atlas.ja-jp.api_meta.meta/api_meta/customfield.htm

## 5. 再度terminal
- 下記をコマンドを実行
```
sfdx force:mdapi:convert -r yourMetadataPackagePath
例: sfdx force:mdapi:convert -r metadataPackage_1700466413440
```
- メタデータからソースへの変換を行う

## 6. デプロイ
- 対象xmlをデプロイする

## 各項目タイプについての記述サンプル
### テキスト項目

```xml
<fields>
    <fullName>Property__c</fullName>
    <externalId>false</externalId>
    <label>物件名</label>
    <length>255</length>
    <required>false</required>
    <trackFeedHistory>false</trackFeedHistory>
    <type>Text</type>        
</fields>
```
### 数値、通貨、パーセント
- 基本 `type`を変えるだけで良い
    - 数値: `Number`
    - 通貨: `Currency`
    - パーセント: `Percent`
- `precision`: 桁数
- `scale`: 小数点の桁数

```xml
<fields>
    <fullName>PurchaseAmount__c</fullName>
    <label>仕入額</label>
    <type>Currency</type>
    <precision>18</precision>
    <scale>0</scale>
</fields>
```

### 日付
- `fullName`、`label`、`type`だけでDeployは成功する
```xml
<fields>
    <fullName>CheckDate__c</fullName>
    <externalId>false</externalId>
    <label>チェック日</label>
    <required>false</required>
    <trackHistory>false</trackHistory>
    <trackTrending>false</trackTrending>
    <type>Date</type>
</fields>
```

### 選択リスト(Picklist)の場合
- `valueSet`、`valueSetDefinition`を使用する
- 昔とやり方が今は違うらしい  

```xml
<fields>
    <fullName>Property__c</fullName>
    <description>My custom picklist field</description>
    <label>物件名</label>
    <type>Picklist</type>
    <valueSet>
        <valueSetDefinition>
            <sorted>false</sorted>
            <value>
                <fullName>Osaka</fullName>
                <default>false</default>
                <label>大阪</label>
            </value>
            <value>
                <fullName>Tokyo</fullName>
                <default>false</default>
                <label>東京</label>
            </value>
        </valueSetDefinition>
    </valueSet>
<fields>
```

### 選択リストで、選択リスト値セット（グローバル値セット）を使いたい場合
- こっちはより記述が簡単
- `valueSetName`に、グローバル値セットのAPI名を指定する

```xml
<fields>
    <fullName>IsExisted__c</fullName>
    <externalId>false</externalId>
    <label>存在有無</label>
    <required>false</required>
    <trackHistory>false</trackHistory>
    <trackTrending>false</trackTrending>
    <type>Picklist</type>
    <valueSet>
        <restricted>true</restricted>
        <valueSetName>IsPresence</valueSetName>
    </valueSet>
</fields>
```

### 参照関係
- `referenceTo`に対象オブジェクトを指定する
- `deleteConstraint`は削除された時に参照先のデータの扱いをどうするかの設定


```xml
<fields>
    <fullName>User__c</fullName>
    <deleteConstraint>SetNull</deleteConstraint>
    <description>My lookup field</description>
    <label>担当者</label>
    <relationshipName>MyLookupFieldsUser</relationshipName>
    <referenceTo>User</referenceTo>
    <required>false</required>
    <type>Lookup</type>
</fields>
```

## 項目を作ったあと、項目セキュリティの権限付与が面倒
- Org Browserでは、Profileメタデータは取得できない
- 取得するためのpackage.xmlをプロジェクト配下のディレクトリに作成する

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>*</members>
        <name>Profile</name>
    </types>
    <version>58.0</version>
</Package>
```
- 下記コマンドをTerminalで実行

```
sfdx force:source:retrieve -x package.xml
```
- `force-app/main/default/profiles`に取得できる
    - システム管理者のプロファイルは、 `admin`という名前のため注意
- 下記を該当プロファイルのメタデータに追加
    - `指定オブジェクト名.項目名`の入力

```xml
    <fieldPermissions>
        <editable>true</editable>
        <field>SalesRep__c.Opportunity__c</field>
        <readable>true</readable>
    </fieldPermissions>
```
- あとはメタデータをソースに変換して、デプロイ


## さらに、ページレイアウトに作成した項目を追加するのも面倒
### `layouts`のソースファイルを取得する
- これはOrg Browserから可能なので、対象オブジェクトの対象プロファイルに割り当てられているレイアウトを取得する
- 任意の位置に下記を追加

```xml
<layoutItems>
    <behavior>Edit</behavior>
    <field>Property__c</field>
</layoutItems>
```