添付ファイルの名称取得

添付ファイルの名称取得して、添付元の親オブジェクトのフィールドに表示したいとの質問がありました。
https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000BqlrzSAB

多分、Apexトリガーでしか無理じゃないかと思いますね。
そう、みんなに嫌われているApexなんだなぁ。私と一緒で日陰者だ。

回答で、Apexトリガーと答えると、海外でも日本でも100％拒絶されますね。何でだろう？こんなに便利で何でもできるのに。

しかし、これだけでは、ファイル名だけを変更された場合には対応できていません。（オブジェクトが違います）
まぁ、今回は質問者さんからのレスポンスはないので、ここまでにしておきますね。

オブジェクトのリファレンス
https://developer.salesforce.com/docs/atlas.en-us.232.0.object_reference.meta/object_reference/sforce_api_objects_contentdocumentlink.htm

```
trigger addFileName on ContentDocumentLink (after insert,after update,after delete) {
    

    //LinkedEntityId:リンクしたオブジェクトの ID
    //ContentDocumentId:ドキュメントの ID
    List<ContentDocumentLink> CDLList_Account = new List<ContentDocumentLink>();
    Set<String> AccountSet = new Set<String>();
    //新規作成の時,変更のあった時
    if (Trigger.IsInsert || Trigger.IsUpdate) {
        for(ContentDocumentLink CDL : Trigger.new) {
            String Lid = CDL.LinkedEntityId;
            System.debug('############ Lid ##################' + Lid);
            if (Lid.Left(3) == '001'){
                CDLList_Account.add(CDL);
                AccountSet.add(Lid);
            }
        }//end of for
    }//end of if
    //削除の時
    if (Trigger.IsDelete) {
        for(ContentDocumentLink CDL : Trigger.old) {
            String Lid = CDL.LinkedEntityId;
            System.debug('############ Lid ##################' + Lid);
            if (Lid.Left(3) == '001'){
                CDLList_Account.add(CDL);
                AccountSet.add(Lid);
            }
        }//end of for
    }//end of if

    if (AccountSet.size() >0) {
        System.debug('############ AccountSet ##################' + AccountSet);
        //ここからはすべて一緒に行う
        List<ContentDocumentLink> CDLList_AccountAll = [SELECT Id,ContentDocumentId,LinkedEntityId FROM ContentDocumentLink WHERE LinkedEntityId =: AccountSet ORDER BY ContentDocumentId];
        Set<String> CDset = new Set<String>();
        String AccountKey = '';
        List<String> AccountToDocList = new List<String>();
        Map<String,List<String>> AccountToDocMap = new Map<String,List<String>>();
        for (ContentDocumentLink CDL : CDLList_AccountAll){
            CDset.add(CDL.ContentDocumentId);
            System.debug('############ CDL.LinkedEntityId ##################' + CDL.LinkedEntityId);
            String myId = CDL.LinkedEntityId;
            if (AccountKey != myId) {
                if (AccountKey != '') AccountToDocMap.put(CDL.LinkedEntityId,AccountToDocList);
                AccountKey = CDL.LinkedEntityId;
                AccountToDocList = new List<String>();
                AccountToDocList.add(CDL.ContentDocumentId);
            } else {
                AccountToDocList.add(CDL.ContentDocumentId);
            }
        }
        AccountToDocMap.put(AccountKey,AccountToDocList);  
        System.debug('############ AccountToDocMap ##################' + AccountToDocMap);
        
        List<ContentDocument> CDList = [SELECT Id,Title FROM ContentDocument WHERE Id =:CDset];
        Map<String,ContentDocument> CDMap = new Map<String,ContentDocument>();
        for (ContentDocument CD : CDList){
            CDMap.put(CD.Id,CD);
        }
        
        List<Account> updateAccountList = new List<Account>();    
        //for (ContentDocumentLink CDL : CDLList_AccountAll){
        for (String CDL : AccountSet){
            //List<String> AccountToDocList = (List<String>)AccountToDocMap.get(CDL.LinkedEntityId);
            List<String> AccountToDocList2 = (List<String>)AccountToDocMap.get(CDL);
            if (AccountToDocList2 != null){
                String FileNameSt = '';
                for(String CDId : AccountToDocList2){
                    ContentDocument CD = CDMap.get(CDId);
                    if (CD != null){
                        FileNameSt = FileNameSt + CD.Title + ':';
                    }
                }//end of for
                Account ac = new Account();
                //ac.Id = CDL.LinkedEntityId;
                ac.Id = CDL;
                ac.FileName__c = FileNameSt;
                updateAccountList.add(ac);
            }//end of if
            
        }//end of for
        System.debug('############ updateAccountList ##################' + updateAccountList);
        if (updateAccountList.size() >0) update updateAccountList;
        }
}
```


テストクラス

```
@isTest
public class addFileName_test {
    
    private static testMethod void testInsert() {
        
        Test.startTest();
        Account acc= new Account(Name = 'TestAccount');
        insert acc;
        System.debug('############test acc.Id ##################' + acc.Id);
        
        ContentVersion cv = new ContentVersion(); // ファイル本体（バージョン管理）
        cv.Title  = 'TEST1';
        cv.PathOnClient = cv.Title + '.pdf';
        cv.versionData = EncodingUtil.base64Decode('StringToBlob');
        cv.ContentLocation = 'S';
        cv.ContentDocumentId = null; // 既にあるファイルはありません
        insert cv;
        System.debug('############test cv.Id ##################' + cv.Id);
        
        Id cdId = [SELECT Id, Title, ContentDocumentId FROM ContentVersion WHERE Id =: cv.Id].get(0).ContentDocumentId; // insertした直後はIdは取得できるが、新しく自動的に作成されたContentVersionのContentDocumentIdは取得できない。※
        ContentDocumentLink cdl = new ContentDocumentLink(); // ファイルとオブジェクトへのリンク
        cdl.LinkedEntityId = acc.Id;
        cdl.ShareType = 'V';
        cdl.ContentDocumentId = cdId;
        insert cdl;
        System.debug('############test Lid ##################' + cdl.LinkedEntityId);
        
        List<Account> chk_acc1 = [SELECT Id,FileName__c FROM Account WHERE Id =: acc.Id];
        System.assertEquals(chk_acc1[0].FileName__c,'TEST1:');  
        
        
        ContentVersion cv2 = new ContentVersion(); // ファイル本体（バージョン管理）
        cv2.Title  = 'TEST2';
        cv2.PathOnClient = cv.Title + '.pdf';
        cv2.versionData = EncodingUtil.base64Decode('StringToBlob');
        cv2.ContentLocation = 'S';
        cv2.ContentDocumentId = null; // 既にあるファイルはありません
        insert cv2;
        System.debug('############test cv2.Id ##################' + cv2.Id);
        
        Id cdId2 = [SELECT Id, Title, ContentDocumentId FROM ContentVersion WHERE Id =: cv2.Id].get(0).ContentDocumentId; // insertした直後はIdは取得できるが、新しく自動的に作成されたContentVersionのContentDocumentIdは取得できない。※
        ContentDocumentLink cdl2 = new ContentDocumentLink(); // ファイルとオブジェクトへのリンク
        cdl2.LinkedEntityId = acc.Id;
        cdl2.ShareType = 'V';
        cdl2.ContentDocumentId = cdId2;
        insert cdl2;
        System.debug('############test Lid ##################' + cdl2.LinkedEntityId);
        
        List<Account> chk_acc2 = [SELECT Id,FileName__c FROM Account WHERE Id =: acc.Id];
        System.assertEquals(chk_acc2[0].FileName__c,'TEST1:TEST2:');      
        
        ContentDocumentLink cdl2d = new ContentDocumentLink();
        cdl2d.Id = cdl2.Id;
        delete cdl2d;
        
        List<Account> chk_acc3 = [SELECT Id,FileName__c FROM Account WHERE Id =: acc.Id];
        System.assertEquals(chk_acc3[0].FileName__c,'TEST1:');  
        
        Test.stopTest();
        
    }
```

#　リンク先を単純に変えただけでは、変わらない
[アップロードした画像の共有先変更について](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000CgYUiSAN)