Although we can create or update fieldsets using salesforce UI but Is there any way to insert or update FieldSets using apex code (using metadata or API calls) ?
2 Answers
This is indeed possible via the Salesforce Metadata API. While this is a Web Service it is available through Apex like any other Web Service. There is a prebuilt Apex wrapper with samples here. The FieldSet metadata type can be used with the 'create' and 'update' operations on this API.
As if by magic it appears someone has just commited a FieldSet example to the library. Note that the Metadata API is an aysnc API, you can poll its results via Batch Apex or apex:actionPoller. Examples of doing both are included in the Github repo and Readme.
Creating a FieldSet via Apex...
// FieldSet
MetadataService.FieldSet fieldSet = new MetadataService.FieldSet();
fieldSet.fullName = 'Test__c.MyFieldSet';
fieldSet.label = 'My FieldSet';
fieldSet.description = 'Used by my VF page';
MetadataService.FieldSetItem myAvailableField = new MetadataService.FieldSetItem();
myAvailableField.field = 'TestField__c';
myAvailableField.isFieldManaged = true;
myAvailableField.isRequired = true;
fieldSet.availableFields = new List<MetadataService.FieldSetItem>();
fieldSet.availableFields.add(myAvailableField);
// Create
MetadataService.AsyncResult[] results = service.create(new List<MetadataService.Metadata> { fieldSet });
Updating a FieldSet via Apex...
// FieldSet
MetadataService.FieldSet fieldSet = new MetadataService.FieldSet();
fieldSet.fullName = 'Test__c.MyFieldSet';
fieldSet.label = 'My FieldSet';
fieldSet.description = 'Used by my VF page';
MetadataService.FieldSetItem myAvailableField = new MetadataService.FieldSetItem();
myAvailableField.field = 'TestField__c';
myAvailableField.isFieldManaged = true;
myAvailableField.isRequired = true;
MetadataService.FieldSetItem myAvailableFieldNew = new MetadataService.FieldSetItem();
myAvailableFieldNew.field = 'ExternalField__c';
myAvailableFieldNew.isFieldManaged = true;
myAvailableFieldNew.isRequired = true;
fieldSet.availableFields = new List<MetadataService.FieldSetItem>();
fieldSet.availableFields.add(myAvailableField);
fieldSet.availableFields.add(myAvailableFieldNew);
// Update
List<MetadataService.UpdateMetadata> updateMetadataList = new List<MetadataService.UpdateMetadata>();
updateMetadataList.add(new MetadataService.UpdateMetadata());
updateMetadataList[0].currentName = 'Test__c.MyFieldSet';
updateMetadataList[0].metadata = fieldSet;
MetadataService.AsyncResult[] results = service.updateMetadata(updateMetadataList);
-
It's awesome Andrew. I will definitely give it a try. Thanks a lot.– S.SharmaCommented Sep 18, 2013 at 0:49
-
@andrew can I add and remove fields from page layout by fieldSet ???– AnzarCommented Sep 12, 2016 at 20:42
-
@Anzar, no fieldsets do not apply to layouts, sorry. Commented Sep 13, 2016 at 8:40
-
@AndrewFawcett thanks for the reply, actually I want to remove field from layout via metadata. I will be thankful to you if you just take a look here is the link of the question salesforce.stackexchange.com/questions/140283/…– AnzarCommented Sep 13, 2016 at 15:55
Did you try adding fields in FieldSet as displayedFields rather than availableFields? Please see simple code below. Developer console throws an error for fieldSet.displayedFields.add(myAvailableField);
Error Message: Metadata API Exception Attempt to de-reference a null object
// FieldSet
MetadataService.FieldSet fieldSet = new MetadataService.FieldSet();
fieldSet.fullName = 'PricebookEntry.MyFieldSet1';
fieldSet.label = 'My FieldSet1';
fieldSet.description = 'Used by my VF page';
//FieldSet Field
fieldSet.availableFields = new List<MetadataService.FieldSetItem>();
MetadataService.FieldSetItem myAvailableField = new MetadataService.FieldSetItem();
//Field 1
myAvailableField.field = 'UnitPrice';
fieldSet.availableFields.add(myAvailableField);
//Field 2
myAvailableField = new MetadataService.FieldSetItem();
myAvailableField.field = 'Product2.LastModifiedDate';
fieldSet.displayedFields.add(myAvailableField);
// Create
List<MetadataService.UpsertResult> results = service.upsertMetadata(new MetadataService.Metadata[] { fieldSet });
-
Sonebody down voted and now that I look I can probably see why. But above post is related and valid if someone is looking for FieldSet + Apex. Not asking to change your opinion, but at same time wanted to voice mine as well :) Commented May 22, 2018 at 4:14