function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Cobb AndersonCobb Anderson 

Trigger keeps giving me an error 'Expression cannot be assigned'

Dear Salesforce developers,

I am new to APEX. I've been Salesforce support and consultant only within the scope of admin and configuration.
I am learning how to write trigger these days and I've been successful with most of it, but just this;

============================================================
trigger HW_CountContactQuant on Contact (after delete, after update, after insert) {
    List<Account> accList = new list<Account>();
    integer i = [SELECT Count() FROM Contact];
    
 if(Trigger.isAfter){
     if(Trigger.isInsert || Trigger.isDelete || Trigger.isUpdate){
         for(Contact gh1 : Trigger.old || Trigger.new){
         Account.ContactQuantity__c = i;
         }
     }
 }


}
================================

I am trying to create a trigger whenever Contact is inserted, updated and deleted, it will count the number of records and update certain field in "Account". Like, rollup summary.
there seems to be no error in my syntax but I keep having "Expression cannot be assigned".

Someone please please help? T_T
Best Answer chosen by Cobb Anderson
Art SmorodinArt Smorodin
Hi Cobb, 

I myself if a beginned at APEX coding but I see some erorrs and will try to point them out for you.
As of right now you trigger is not updating any account because it does not point to any specific account in the system. 
Your line 8:
Account.ContactQuantity__c = i;
is looping inside Contact records, and trying to update an Account record. You have to use Update.

Line 3:
integer i = [SELECT Count() FROM Contact];

If you run it in the Developer Console you will see that it actually return ALL your contacts count. As far as I understand you want to update a specific Account record with the number of Contacts assigned to it. So you will heve to modify your query to reflect that. 

I took some liberties and updated your code. It might be for from perfect but it get the job done and updates the ContactQuantity field for you. 
 
trigger HW_CountContactQuant on Contact (after delete, after update, after insert) {

	Set<Id> AccIds = new Set<Id>();   // I would use Set of ID rather than List of Accounts.
    //integer i = [SELECT Count() FROM Contact];  this way you are selectinh ALL contacts you have in the system. You wont only the ones related to a particular account 


 if(Trigger.isAfter){
     if(Trigger.isInsert || Trigger.isDelete || Trigger.isUpdate){
         for(Contact gh1 : Trigger.new){ // got rig of Trigger.old 
			AccIds.add(gh1.AccountId);
		 }
         Account[] AccToUpdate = [SELECT Id, ContactQuantity__c FROM Account WHERE ID IN :AccIds];
		 Integer CountContacts = [SELECT Count() FROM Contact where AccountId =:AccIds];
         
         For (Account Accs: AccToUpdate){
             Accs.ContactQuantity__c = CountContacts;
         }
         update AccToUpdate;
     }
 }
}

Please give it a try and see if it works for you as well. 
-Art.

All Answers

Parvinder SinghParvinder Singh
Sorry to say but your code is not right, first thing its not batchable and it will work only from User interface, please take a look at this http://blog.jeffdouglas.com/2009/07/30/roll-up-summary-fields-with-lookup-relationships-part-1/ blog from Jeff Douglas and it will guide you with this trigger.
Art SmorodinArt Smorodin
Hi Cobb, 

I myself if a beginned at APEX coding but I see some erorrs and will try to point them out for you.
As of right now you trigger is not updating any account because it does not point to any specific account in the system. 
Your line 8:
Account.ContactQuantity__c = i;
is looping inside Contact records, and trying to update an Account record. You have to use Update.

Line 3:
integer i = [SELECT Count() FROM Contact];

If you run it in the Developer Console you will see that it actually return ALL your contacts count. As far as I understand you want to update a specific Account record with the number of Contacts assigned to it. So you will heve to modify your query to reflect that. 

I took some liberties and updated your code. It might be for from perfect but it get the job done and updates the ContactQuantity field for you. 
 
trigger HW_CountContactQuant on Contact (after delete, after update, after insert) {

	Set<Id> AccIds = new Set<Id>();   // I would use Set of ID rather than List of Accounts.
    //integer i = [SELECT Count() FROM Contact];  this way you are selectinh ALL contacts you have in the system. You wont only the ones related to a particular account 


 if(Trigger.isAfter){
     if(Trigger.isInsert || Trigger.isDelete || Trigger.isUpdate){
         for(Contact gh1 : Trigger.new){ // got rig of Trigger.old 
			AccIds.add(gh1.AccountId);
		 }
         Account[] AccToUpdate = [SELECT Id, ContactQuantity__c FROM Account WHERE ID IN :AccIds];
		 Integer CountContacts = [SELECT Count() FROM Contact where AccountId =:AccIds];
         
         For (Account Accs: AccToUpdate){
             Accs.ContactQuantity__c = CountContacts;
         }
         update AccToUpdate;
     }
 }
}

Please give it a try and see if it works for you as well. 
-Art.
This was selected as the best answer
Cobb AndersonCobb Anderson
@Parvinder Your link was very helpful too!!
@Art you began APEX too but it seems you are much more better than I am! I guess I need more study. Thanks a lot buddy!