4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SalesforceAdvent Calendar 2022

Day 8

Salesforceでカスタムメタデータを一括登録、一括更新、一括削除する方法

Posted at

Salesforce Advent Calendar 2022の8日目の記事です。

はじめに

この記事は@Aptenodytes9さんのSalesforceでカスタムメタデータ型を大量INSERTする方法
のオマージュです。
上記手順でハマったところ、改良したところを中心に書きます。

カスタムメタデータとは

カスタマイズ可能、リリース可能、パッケージ化可能、アップグレード可能なアプリケーションメタデータです。選択リストやリレーションが使えたり、レコードごとリリースできるのも良い。
詳しくこちら

Custom Metadata Loader

手法も同じく「Custom Metadata Loader」を使います。

Salesforce公式が提供しているのですが、
Salesforce CLIでカスタムメタデータが使えるようになったので、
もうメンテナンスは終了しています。

上記サイトにもCLIで利用できるようになったから、
サポートも終了したし、機能保証はしないよとあります。が、
運用担当者が非エンジニアでsfdxコマンドは厳しかったのでこの手法にしました。

インストール

インストールは元記事の通りでOKです(一応手順)

1.「Custom Meta Data Loader」のGithubにアクセス
2.「Deploy to Salesforce」ボタンをクリック
image.png
3.「Deploy to:」で環境を選択して「Login to Salesforce」をクリック(他の項目は変更不要です)
Login to Salesforce
4.アクセスを許可
アクセス許可
5.「Deploy」をクリック
アクセス許可
「Deployment Complete」が表示されたら完了です。
デプロイ完了

インストール後の設定

途中までは元記事の通りでOKです(一応手順)

1.利用ユーザのプロファイルの「カスタムアプリケーション設定」で「Custom Metadata Loader」の「参照可能」にチェック
カスタムアプリケーション設定
2.同じくプロファイルの「カスタムタブの設定」で「Custom Metadata Loader」を「デフォルトで表示」に変更
※ 「Custom Metadata Migrator」というカスタム設定、カスタムオブジェクトをカスタムメタデータに移行するツールもありますが今回は不要です。
カスタムタブの設定

3.「Visualforceページ」の「CustomMetadataRecordUploader」をクリック

4.「プレビュー」をクリック
5.URLのグレー部分を控える
https://d7f000005d9hsuas-dev-ed--c.vf.force.com/apex/CustomMetadataRecordUploader
URLドメイン
6.「リモートサイトの設定」で「新規リモートサイト」をクリックして以下設定して保存

項目 設定値
リモートサイト名 任意
リモートサイトのURL 手順5で控えたURL
プロトコルセキュリティの無効化 チェックなし
説明 任意
有効 チェックあり

7.アプリケーションの「Custom Metadata Loader」をクリックして画面が表示されたら準備完了
URLドメイン

CSVファイルの作成

以下フォーマットで作成

項目 設定値
文字コード UTF-8
改行コード CRLF
BOM なし
※ExcelでCSV保存した場合はBOMがつくので注意
データ構成 1行目はヘッダー
2行目以降がデータ
シングルクォーテーション
ダブルクォーテーション
なし
ヘッダー API参照名
必須の列 表示ラベル(Label)
カスタムメタデータレコード名(DeveloperName)
※「表示ラベル」のAPI参照名は「MasterLabel」だがインポート時に設定するのは「Label」
※Descriptionはなくても問題なし

インポート

テスト用カスタムメタデータ

上記のようなカスタムメタデータ型に対して以下のようなCSVを用意します。
(インストール時にテスト用の「CountryMapping」というカスタムメタデータが生成されます)
image.png

1.「ファイルを選択」でCSVを選択し、
右上の選択リストから対象のカスタムメタデータ型を選択して「Create/Update custom metadata」をクリック
image.png
※正常終了すると登録済みのカスタムメタデータが表示されます(なぜか今回登録した分は表示されません)。
※カスタムメタデータレコード名(DeveloperName)が存在する場合は更新します。

正常に登録されました。
登録完了カスタムメタデータ

ここから改良点になります。

改良1 空値を登録できるようにする

実は現状のままでは空値を登録することができません。
そこで以下のファイルを修正します。
split(regExp, limit)メソッドのlimitに負の数を設定することで空文字が破棄されなくなります。

CustomMetadataLoader/custom_md_loader/classes/CSVFileUtil.cls
- List<String> fields = line.split(',');
+ List<String> fields = line.split(',', -1);

改良2 カスタムメタデータを一括で削除できるようにする

現状のままだと1レコードずつ画面からしか削除できないので、
選択したカスタムメタデータ型のレコードをすべて削除するようにします。

CustomMetadataLoader/custom_md_loader/classes/CustomMetadataUploadController.cls
+ public PageReference deleteCustomMetaData() {
+     ApexPages.getMessages().clear();
+     showRecordsTable = false;
+     deleteCustomMetadtaRecords();
+     // TODO: Add Success Message / Display Errors
+     return null;
+ }
+
+ private void deleteCustomMetadtaRecords() {
+     if(selectedType == 'Select type') {
+         ApexPages.Message errorMessage = new ApexPages.Message(ApexPages.severity.ERROR, 'Please choose a valid custom metadata type.');
+         ApexPages.addMessage(errorMessage);
+         return;
+     }
+
+     String query = 'SELECT DeveloperName FROM ' + selectedType;
+
+     List<sObject> customRecords = Database.query(query);
+     List<String> recordsToDelete = new List<String>();
+
+     for (sObject record : customRecords) {
+         recordsToDelete.add(selectedType + '.' + record.get('DeveloperName'));
+     }
+
+     MetadataUtil.deleteMetadata('CustomMetadata', recordsToDelete);
+ }
CustomMetadataLoader/custom_md_loader/classes/MetadataUtil.cls
+ public static void deleteMetadata(String type_x,String[] fullNames) {
+     List<MetadataService.DeleteResult> results = getPort().deleteMetadata(type_x, fullNames);
+     if (results!=null) {
+         for (MetadataService.DeleteResult deleteResult : results) {
+             if (deleteResult==null || deleteResult.success) {
+                  continue;
+             }
+             // Construct error message and throw an exception
+             if (deleteResult.errors!=null) {
+                 List<String> messages = new List<String>();
+                 messages.add((deleteResult.errors.size()==1 ? 'Error ' : 'Errors ') + 'occured processing component ' + deleteResult.fullName + '.');
+                 for(MetadataService.Error error : deleteResult.errors){
+                     messages.add(error.message + ' (' + error.statusCode + ').' + ( error.fields!=null && error.fields.size()>0 ? ' Fields ' + String.join(error.fields, ',') + '.' : '' ) );
+                 }
+                 if(messages.size()>0){
+                     ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Error, String.join(messages, ' ')));
+                     System.debug(LoggingLevel.ERROR, String.join(messages, ''));
+                     return;
+                 }
+             }
+             if(!deleteResult.success){
+                 ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Error, 'Request failed with no specified error.'));
+                 return;
+             }
+         }
+     }
+ }
CustomMetadataLoader/custom_md_loader/pages/CustomMetadataRecordUploader.page
+ <div align="center" draggable="false" >
+    <apex:ActionRegion >
+     <apex:commandButton value="Delete Custom MetaData Type" action="{!deleteCustomMetaData}" rendered="true"/>
+     <apex:actionSupport event="onclick"  action="{!deleteCustomMetaData}" rendered="{!showRecordsTable}" oncomplete="window.opener.location.reload();"/>
+   </apex:ActionRegion>
+ </div>
+ <br/>
+ <br/>

image.png
これでカスタムメタデータ型を選択して「Delete Custom MetaData Type」をクリックするとレコードを全部消します。

まとめたものは以下

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?