LoginSignup
2
1

More than 1 year has passed since last update.

Apexにつかわれているオブジェクト項目の調査2 (SFDX)

Last updated at Posted at 2022-11-20

要件

Apex,Trigger,Flowが使われているオブジェクト項目を洗い出したい

参照

Workbenchで調査
https://qiita.com/richard_hcq/items/6b627e6383b6115675f4
詳細資料
https://blog.bessereau.eu/assets/pdfs/api_tooling.pdf
 ※ワークルールについて
image.png

VsCodeでSfdxコマンドからToolingApiのSoqlから関連情報のCsvを出力する
関連オブジェクト
MetadataComponentDependencyから依存項目をみれますが、なんのオブジェクトの項目かを調べるため、CustomObjectとCustomFiledの内容をダウロードし、突き合わせる必要がある
image.png
上記の例で、バッチがRmBusinessSectionListの法人番号をつかっていることがわかる。

実施ポイント

① MetadataComponentDependencyの実施Soql

sfdx force:data:soql:query -q  
"select MetadataComponentId,MetadataComponentName,MetadataComponentType,
RefMetadataComponentId,RefMetadataComponentName,RefMetadataComponentType
from MetadataComponentDependency 
where MetadataComponentType in ('ApexClass') and 
RefMetadataComponentType in ('CustomField','CustomObject','ApexClass')  
Order by MetadataComponentName" -r csv -t >ApexAndField.csv

※ -t --toolingapi このオプションはSfdxで使える。Dataloaderはまた使えないようです。
    ちなみにDeveloperコンソールのQueryに使える(Optionにチェックする)
  該当関係オブジェクトは一Queryで2000行の制御がある。
※ TriggerまたFlowの場合、 MetadataComponentType in ('ApexTrigger','Flow')
※ 別のオブジェクトで下記設定で、2000行以上が取れるが、
MetadataComponentDependencyができない
   sfdx config:set maxQueryLimit=20000000
  取引先の200万レコードがとりますが、遅くて1時間以上がかかってしまった。
   (select id from account)
※ 漢字名がある場合、VsCodeのTerminalで文字ばけ、普通のCmdのPromptで実行する

結果:
image.png

Apexと使われている項目の一覧ができました。

② 上記①に項目は何のオブジェクトの項目は下記二つ情報が必要です。

カスタムオブジェクト一覧
select 
  Id,DeveloperName,NamespacePrefix 
from CustomObject 
where NamespacePrefix = null 
Order by DeveloperName

※「NamespacePrefix = null」は別Packageのものを除外している

  実行コマンド

sfdx force:data:soql:query -q  "select Id,DeveloperName,NamespacePrefix from CustomObject where NamespacePrefix = null Order by DeveloperName" -r csv -t >CustomObject.csv
カスタム項目一覧
select 
  Id,DeveloperName,NamespacePrefix,TableEnumOrId 
from CustomField 
where NamespacePrefix = null 

  実行コマンド

sfdx force:data:soql:query -q  "select Id,DeveloperName,NamespacePrefix,TableEnumOrId from CustomField where NamespacePrefix = null Order by TableEnumOrId" -r csv -t >CustomField.csv

※補足 Flow & ProcessBuilder
sfdx force:data:soql:query -q  "select Id ,DefinitionId,Status,ProcessType,VersionNumber from Flow where Status in ('Active') Order by MasterLabel" -r csv -t >Flow.csv

※補足 ApexTrigger
sfdx force:data:soql:query -q  "select Id,Name,NamespacePrefix from ApexTrigger Order by Name" -r csv -t >ApexTrigger.csv

※補足 WorkflowRule
 sfdx force:data:soql:query -q  "select Id,ManageableState,Name,TableEnumOrId from WorkflowRule" -r csv -t >workflowrule.csv
※補足 WorkflowFieldUpdate
sfdx force:data:soql:query -q  "select Id,Name,EntityDefinitionId,FieldDefinitionId,LiteralValue,LookupValueId,SourceTableEnumOrId from WorkflowFieldUpdate" -r csv -t >WorkflowFieldUpdate.csv

関係マットリックス

上記三つ情報はExcelシートに張り付け、マクロで突き合わせで、Apexが横並べ、縦はオブジェクト、項目を並べ、使われているところに「O」をつけ、関係マットリックスが作成できる
image.png

VBA Macro
Sub fillApexName()
  Set rfSht1 = Sheets("CustomObject")
  Set rfSht2 = Sheets("CustomField")
  Set srcSht = Sheets("ApexAndApexField")
  
  Set objDic = CreateObject("Scripting.Dictionary")
  Set fieldDic = CreateObject("Scripting.Dictionary")
  Set MatrixDicX = CreateObject("Scripting.Dictionary")
  Set MatrixDicY = CreateObject("Scripting.Dictionary")
  
  'obj
  ii = 3
  While rfSht1.Cells(ii, 2).Value <> ""
    objDic.Add rfSht1.Cells(ii, 2).Value, rfSht1.Cells(ii, 3).Value
    ii = ii + 1
  Wend
  
  'field
   ii = 3
  While rfSht2.Cells(ii, 2).Value <> ""
    vv = rfSht2.Cells(ii, 5).Value
    If Left(vv, 1) = "0" Then
      fieldDic.Add rfSht2.Cells(ii, 2).Value, objDic.Item(vv)
    Else
      fieldDic.Add rfSht2.Cells(ii, 2).Value, vv
    End If
    ii = ii + 1
  Wend
 
  'MatrixDicX
  'MatrixDicY
   ii = 3
   xcol = 6
   yrow = 4
  While srcSht.Cells(ii, 2).Value <> ""
    'x col
    vv = srcSht.Cells(ii, 3).Value
    If Not MatrixDicX.Exists(vv) Then
      MatrixDicX.Add vv, xcol
      xcol = xcol + 1
    End If
    
    'yrow
    tp = srcSht.Cells(ii, 7).Value
    fn = srcSht.Cells(ii, 6).Value
    fid = srcSht.Cells(ii, 5).Value
    If tp = "CustomField" Then
      key1 = tp & "#" & fieldDic.Item(fid) & "#" & fn
      
    Else
      If tp = "ApexClass" Then
        key1 = tp & "#" & fn & "#"
      End If
    End If
    If Not MatrixDicY.Exists(key1) Then
      MatrixDicY.Add key1, yrow
      yrow = yrow + 1
    End If

    
    ii = ii + 1
  Wend
  
  'xy
  Set ToSht = Sheets("MatrixApex")
  ToSht.Range("A4:AAX20000").ClearContents
  ToSht.Range("E3:AAX3").ClearContents
  'ii = 4
 
  For Each vKey In MatrixDicY
    
    item2 = MatrixDicY.Item(vKey)
    arr = Split(vKey, "#")
    ToSht.Cells(item2, 2) = arr(0)
    ToSht.Cells(item2, 3) = arr(1)
    ToSht.Cells(item2, 4) = arr(2)
 Next
 
 'x-ray
 For Each vKey In MatrixDicX
    item2 = MatrixDicX.Item(vKey)
    ToSht.Cells(3, item2) = vKey
 Next
 
 'mark the point
   ii = 3
   xcol = 6
   yrow = 4
  While srcSht.Cells(ii, 2).Value <> ""
    'x col
    apx = srcSht.Cells(ii, 3).Value
    
    'yrow
    tp = srcSht.Cells(ii, 7).Value
    fn = srcSht.Cells(ii, 6).Value
    fid = srcSht.Cells(ii, 5).Value
    If tp = "CustomField" Then
      key1 = tp & "#" & fieldDic.Item(fid) & "#" & fn
      
    Else
      If tp = "ApexClass" Then
        key1 = tp & "#" & fn & "#"
      End If
    End If
    
    ToSht.Cells(MatrixDicY.Item(key1), MatrixDicX.Item(apx)).Value = "O"

    
    ii = ii + 1
  Wend

    
  
 MsgBox ("Apex and field mapping OK")
  
  
End Sub
2
1
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
2
1