この記事は何
先日、項目をたくさん作って別の環境にリリースをする機会がありました。
普段はリリース環境で項目を手動で作成し、ぽちぽちと項目レベルセキュリティにチェックを入れていく方法で設定を行っていることが多いです。
ただし、項目数が多いときには項目自体を変更セットで送信し、
データローダーで項目レベルセキュリティを一括付与したほうが楽だと思います。
今後の自分のためになるはずなので、データローダーでの項目レベルセキュリティの設定方法を整理してみようと思います。
変更セットで項目をリリースする場合、カスタムレポートタイプも一緒に変更セットに含める必要があります。
作業手順
- 必要なデータをExport(権限セットオブジェクト)
- 項目権限設定用のCSVを作成
- データローダーで項目権限オブジェクトにInsert
1. 必要なデータをExport
- データローダーでExport
- オブジェクト:権限セット(PermissionSet)
- プロファイルではなく、権限セットオブジェクトを選択してください
- 「Show all Salesforce objects」にチェックを入れるとオブジェクトがでてきます
- 下記のSOQLを使ってExport
プロファイルの判別のため、Profile.Name(プロファイルの表示ラベル)も一緒に抽出しておきます。
SELECT Id, Name, Label, ProfileId, Profile.Name
FROM PermissionSet
2. 項目権限Insert用のCSVを作成
項目レベルセキュリティは、項目権限というオブジェクトで管理されています。このオブジェクトにInsertするためのCSVファイルを作成していきます。
1.で取得した権限セットオブジェクトのIDと新規作成する項目の情報を加工して、項目権限設定用のcsvを作成します。
プロファイルのリストを作成
1.の手順では組織の全プロファイル、権限セットのデータをExportしました。ここから項目レベルセキュリティを付与するプロファイルを抽出します。
権限付与が必要なプロファイルはProfile.Nameで判別します。
ちなみに、ProfileIdとProfile.Nameが空欄の場合は権限セットのデータになります。
リストに必要な項目は下表のとおりです。
| 項目 | 説明 | 例 |
|---|---|---|
| ParentId | PermissionSetのID | 0PSから始まるID |
| Profile.Name | プロファイルの表示ラベル(※) | システム管理者 |
PARENTIDに入れる値はProfileIdではなく権限セットオブジェクトのIDです。
運用TIPS
項目レベルセキュリティを付与するプロファイルについて、組織ごとにルールを定めていることが多いと思います。
ここで抽出したプロファイルのデータをマスタとして持っておくと次回以降使いまわせて便利だと思います。
(もちろんプロファイルの増減、ルールの変更ごとにマスタのメンテナンスは必要です)
項目のリストを作成
項目リストに必要なヘッダー(列名)は下表の通りです。
| 項目 | 説明 | 例 |
|---|---|---|
| オブジェクト名 | オブジェクトの表示ラベル | サンプルオブジェクト |
| SOBJECTTYPE | オブジェクトのAPI参照名(※) | Object__c |
| 項目名 | 項目の表示ラベル(※) | サンプル項目 |
| データ型 | 項目のデータ型(※) | テキスト(255) |
| FIELD | オブジェクト.項目のAPI参照名 | Object__c.Field__c |
| PERMISSIONSREAD | 参照権限 | TRUE |
| PERMISSIONSEDIT | 編集権限 | TRUE |
| ※必須ではないが、作業のために入れておいた方がいい列 |
- FIELDに入れるデータは、Object__c.Field__cの形式に整形する必要があります。
- データ型が数式、積み上げ集計の場合、PERMISSIONSEDITをTRUEにするとInsert時にエラーが出ます。忘れずにFALSEにしておきましょう。
(ほかに気づいたことがあれば随時追記していきます)
項目権限Insert用csvを作成
それぞれリストができたら、いよいよcsvの中身を準備していきます。
csvに必要なヘッダー(列名)は以下の通り。
後述のGASの処理で列名を設定しているので、何か作業をする必要はありません。
| 項目 | 説明 | 例 |
|---|---|---|
| PARENTID | PermissionSetのID | 0PSから始まるID |
| Profile.Name | プロファイルの表示ラベル(※) | システム管理者 |
| SOBJECTTYPE | オブジェクトのAPI参照名 | Object__c |
| FIELD | オブジェクト.項目のAPI参照名 | Object__c.Field__c |
| PERMISSIONSREAD | 参照権限 | TRUE |
| PERMISSIONSEDIT | 編集権限 | TRUE |
(※)必須ではないが、作業のために入れておいた方がいい列
具体的な例として、新規作成する項目が30個、権限付与したいプロファイルが10個あるとします。
この場合、30項目と10プロファイルの組み合わせで30×10=300行が必要です。
手動でリストをコピーペーストしてデータを作成するのは大変ですよね。
そこでGeminiに聞きながら、スプシの関数を使って項目とプロファイルの組み合わせリストを作成しました。
この記事を作成するにあたって、組み合わせリストを作成できるテンプレートを作ろうと思ったのですが、
項目数の変動に対応できるものを関数で作るのが難しく、結局GASで作成しました。
参考までに、Geminiに作ってもらったGASのコードを記載しておきます。
必要に応じて修正して使ってみてください。
function createCombinedList_largeData() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sourceSheet = ss.getSheetByName("元データ"); // 元のデータがあるシート名
const targetSheet = ss.getSheetByName("出力用"); // 結果を出力するシート名
// 1. 各リストからデータを取得(空白行は自動的に無視されます)
const list1Range = sourceSheet.getRange("A7:A").getValues();
const list2Range = sourceSheet.getRange("B7:B").getValues();
const list3Range = sourceSheet.getRange("E7:E").getValues();
const list4Range = sourceSheet.getRange("K7:K").getValues();
const list5Range = sourceSheet.getRange("I7:I").getValues();
const list6Range = sourceSheet.getRange("J7:J").getValues();
// 2. 各リストから空の値をフィルタリング
const ParentId = list1Range.filter(row => row[0] !== "").map(row => row[0]);
const ProfileName = list2Range.filter(row => row[0] !== "").map(row => row[0]);
const SOBJECTTYPE = list3Range.filter(row => row[0] !== "").map(row => row[0]);
const FIELD = list4Range.filter(row => row[0] !== "").map(row => row[0]);
const PERMISSIONSREAD = list5Range.filter(row => row[0] !== "").map(row => row[0]);
const PERMISSIONSEDIT = list6Range.filter(row => row[0] !== "").map(row => row[0]);
// 3. 組み合わせを生成
const output = [];
for (let i = 0; i < ParentId.length; i++) {
for (let j = 0; j < SOBJECTTYPE.length; j++) {
output.push([
ParentId[i],
ProfileName[i],
SOBJECTTYPE[j],
FIELD[j],
PERMISSIONSREAD[j],
PERMISSIONSEDIT[j]
]);
}
}
// 4. 出力シートに書き込み
targetSheet.clearContents(); // 既存のデータをクリア
// ヘッダー(列名)を設定
// 列名はご自身のデータに合わせて変更してください
const headers = ["ParentId", "Profile.Name", "SOBJECTTYPE", "FIELD", "PERMISSIONSREAD", "PERMISSIONSEDIT"];
targetSheet.getRange(1, 1, 1, headers.length).setValues([headers]);
if (output.length > 0) {
// データはヘッダーの下の行から書き込む
targetSheet.getRange(2, 1, output.length, output[0].length).setValues(output);
}}
「csv用データ出力」ボタンをクリックすると「出力用」シートに組み合わせリストが出力されます。

3. データローダーでInsert
「Show All Salesforce Object」にチェックをつけ「項目権限」オブジェクトを選択します。
Profile.Nameは自動マッピングの対象外となりますので、マッピングせずそのままinsertを行います。
エラーが出たら適宜対応します。
見慣れたブラウザの設定画面で項目レベルセキュリティがついているか確認してみましょう。
設定した通りについていればこれで完了です!
補足:権限セット(PermissionSet)オブジェクトについて
- 権限セットオブジェクトはプロファイルと権限セット両方を管理しているようです。
プロファイルか権限セットかで入る値は以下のように異なっています。
| 権限管理機能 | Name | Label | ProfileId | Profile.Name |
|---|---|---|---|---|
| プロファイル | Label列の値の前に「X」がついた値 | プロファイルID?(※) | プロファイルID | 表示ラベル |
| 権限セット | API参照名 | 表示ラベル | 値なし | 値なし |
(※)Labelは必ずプロファイルIDというわけでもなく、IDのあとに数字がついた値が入ってることもありました
さいごに
ほんとに楽になるかな…ポチポチの方が楽じゃないかなという気持ちもありますが、
せっかくテンプレートを作ったので今後機会があれば試してみます。
ページレイアウトの割り当てのようにオブジェクトごとにプロファイルと項目を一覧で選択できるようなUIがあれば
一番楽だと思うので、リリースを待っています。
参考
