Memos About Salesforce

Salesforceにハマってたこと!

sfdc Visualforcepageで テーブル 横に列が動的

f:id:jude2016:20190920155743j:plain

こんにちは、管理人の@Salesforce.Zです。

SalesforceのVFを使い、帳票の画面開発をするときにさけれないニーズがあります。

縦に動的、行を追加する 横に動的、列を追加する

のようにしたい要望です。

今回、この動的実装について共有したいと思います。

目次

横に動的、クエリカラムを追加する

サンプルクラス

Public Class DynamicColumnCls{
    private static final String fieldStr = '項目:';
    public List<Account> accs {get;set;}
    public List<String> SelectedFields {get; set;} 
    public string FieldName {get;set;}
    string query;
    string fields = '';
    // コンストラクタ
    public DynamicColumnCls(){ 
        SelectedFields = New List<String>();
    }
    public void addFields(){
    try{
    
        If (FieldName == '' ){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO,'項目名を入力してください!'));
        }
    
        SelectedFields.Add(FieldName);
        //画面に入力したカラム名で文字列にする
        fields = String.Join(SelectedFields, ', ');
        fields = fields.RemoveEnd(',');
        query = 'Select ' + fields + ' From Account Limit 10';
        accs= Database.Query(query);
        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.CONFIRM, fieldStr + FieldName + ' 追加済み'));
    }
    catch( Exception e ){
    
        If ( e.getmessage().contains('カラムは存在しません') ){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Warning, fieldStr + FieldName + ' 無効の取引先'));
        }
    
        If ( e.getmessage().contains('duplicate') ){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO,'Field : ' + FieldName + ' 選択済み'));
        }
        SelectedFields.remove(SelectedFields.size()-1);
    }   
}
    
    

}

サンプルVF

<apex:page controller="DynamicColumnCls">
<apex:form >
    <apex:pageMessages id="msg"></apex:pageMessages>
    
    <apex:pageBlock >
        <apex:pageBlockSection >
            <apex:pageBlockSectionItem >
            
            <b>項目のAPI名:</b> <apex:inputText id="inputClo" value="{!FieldName}" />
            
            </apex:pageBlockSectionItem>
        </apex:pageBlockSection>
    
    <apex:pageBlockTable id="tbl" value="{!accs}" var="rec">
    
        <apex:repeat value="{!SelectedFields}" var="FieldLable"> 
            <apex:column value="{!rec[FieldLable]}"/> 
        </apex:repeat> 
    </apex:pageBlockTable>
    
    <apex:pageBlockButtons >
        <apex:commandButton reRender="tbl,msg" value="クエリカラム追加" action="{!addFields}"/>
    </apex:pageBlockButtons>
    </apex:pageBlock>
</apex:form>
</apex:page>

出力結果

Id追加 f:id:jude2016:20180807222727p:plain

Name追加 f:id:jude2016:20180807222809p:plain

横に動的、列を追加する

サンプルクラス

public with sharing class  EXCtrl {
    // VF側のPageBlockTableに使う設定オブジェクト変数
    public List<Account> accList{get;set;}
    // accListをクエリする先に抽出するカラムの開発名のリスト
    public List<String> accFieldList{get;set;}
    
   public EXCtrl(){
        // この文字列のリストはもっと自由度の高い方法実装できるcase by case
        accFieldList = new List<String>();
        accFieldList.add('Id');
        accFieldList.add('Name');
        accFieldList.add('SLASerialNumber__c');
        
        String fields = String.Join(accFieldList, ', ');
        String query  = 'select ';
        query += fields;
        query += ' From Account Limit 10';
        accList = Database.Query(query);
    }
}

サンプルVF

<apex:page controller="EXCtrl">
    <apex:form >
        <apex:pageBlock >
                <apex:pageBlockTable value="{!accList}" var="acc" width="100%">
                    <apex:repeat value="{!accFieldList}" var="fieldL">
                        <apex:column value="{!acc[fieldL]}"/>
                    </apex:repeat>
                </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>
</apex:page>

出力結果

f:id:jude2016:20180807221358p:plain

最後に

今回、ちょろっと共有だけです。

もっと拡張できます。時間があれば、遊んでみてください。

リファレンス

Add columns dynamically into PageBlockTable at run time