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
Daniel ProbertDaniel Probert 

Trigger to Loop a specific number of times

Hi Community,

 

I'm new to apex and trigger but have created a simple trigger against a custom object Loan__c that after insert will create the repayment schedule in the custom related object Loan_Repayment__c

 

trigger generateloanrepayments on Loan__c (after insert) {
List <Loan_Repayments__c> prefToInsert = new List <Loan_Repayments__c> ();


for (Loan__c c : Trigger.new) {
Loan_Repayments__c p = new Loan_Repayments__c ();

p.Loan__c = c.Id;
p.Expected_Repayment_Date__c = c.Hidden_First_Payment_Date__c + 30;
p.CurrencyISOCode = c.CurrencyISOCode;

prefToInsert.add(p);

}
try {
insert prefToInsert;
} catch (system.Dmlexception e) {
system.debug (e);
}
}

 

 

This works well however what I now need to do is have this loop and create the entire repayment schedule based on the value that is stored in Loan__c.Number_of_Repayments__c.

 

So when Loan__c.Number_Of_Repayments__c = 5 there are 5 records creates.

 

Hope this makes sense and someone can help me.

 

Cheers

Dan

SabrentSabrent
integer numOfRepayments = Loan__c.Number_of_Repayments__c;

for (integer i=0 i< numOfRepayments i++){

// create your records


}
Daniel ProbertDaniel Probert

thanks where do I put that though i changed my code to this an I get an error:

 

Error: Compile Error: expecting a semi-colon, found 'i' at line 8 column 21

 

trigger generateloanrepayments on Loan__c (after insert) {
    
    
    
    List <Loan_Repayments__c> prefToInsert = new List <Loan_Repayments__c> ();
        
    integer numOfRepayments = Loan__c.Number_of_Repayments__c;
    for (integer i=0 i< numOfRepayments i++){

        Loan_Repayments__c p = new Loan_Repayments__c ();


        p.Loan__c = c.Id;
        p.Expected_Repayment_Date__c = c.Hidden_First_Payment_Date__c + 30;
        p.CurrencyISOCode = c.CurrencyISOCode;


        prefToInsert.add(p);
       
    }
    try {
        insert prefToInsert;
        } catch (system.Dmlexception e) {
        system.debug (e);
        }
}

 appreciate your quick response..

 

 

MellowRenMellowRen

I am assuming the date needs to progress as well. How about:

 

for (Loan__c c : Trigger.new) {
Loan_Repayments__c p = new Loan_Repayments__c ();

p.Loan__c = c.Id;
p.CurrencyISOCode = c.CurrencyISOCode;

For (Integer i = 1, i <= Loan__c.Number_Of_Repayments__c,i++) {
p.Expected_Repayment_Date__c = c.Hidden_First_Payment_Date__c + (30 * i);
prefToInsert.add(p);
}

}

 If I am wrong about the date thing, just keep your original Repayment Date line as and where it was (outside the new 'for' loop) and delete mine.

 

Regards

MellowRen

MellowRenMellowRen

Man you guys were quick at posting!

 

In your current solution you're missing some commas in the 'for' loop declaration—look at the example I wrote and you'll see what I mean.

Daniel ProbertDaniel Probert

thanks for the idea hadn't got to that i was going to add that once I got the basic looping working.

 

i get this error with the code that you've given me and can't see the duplicate value:

 

Error: Compile Error: Duplicate variable: i (attempt to re-create the variable with type: Integer) at line 11 column 21

 

any ideas?

SabrentSabrent
For (Integer i = 1; i <= Loan__c.Number_Of_Repayments__c;i++)

replace , with ;
MellowRenMellowRen

Hey - You seem to have lost your outer for loop (the trigger.new one). You still need that.

MellowRenMellowRen

Arrgg, its late and I am confusing languages. You need semi-colons ( ; ) in the for loop, not commas. Sorry. That will fix your duplicate declaration problem.

 

 

EDIT: Man rov is fast! :-)

sushant sussushant sus
trigger generateloanrepayments on Loan__c (after insert) {



List <Loan_Repayments__c> prefToInsert = new List <Loan_Repayments__c> ();

integer numOfRepayments = Loan__c.Number_of_Repayments__c;
for (integer i=0; i< numOfRepayments; i++){

Loan_Repayments__c p = new Loan_Repayments__c ();


p.Loan__c = c.Id;
p.Expected_Repayment_Date__c = c.Hidden_First_Payment_Date__c + 30;
p.CurrencyISOCode = c.CurrencyISOCode;


prefToInsert.add(p);

}
try {
insert prefToInsert;
} catch (system.Dmlexception e) {
system.debug (e);
}
}
DanielBProbertDanielBProbert

hi guys thanks for the response, i've had a long weekend so just getting back to this now.

 

using this code i can now save the trigger without error:

 

trigger generateloanrepayments on Loan__c (after insert) {        
    List <Loan_Repayments__c> prefToInsert = new List <Loan_Repayments__c> ();
        for (Loan__c c : Trigger.new) {
            Loan_Repayments__c p = new Loan_Repayments__c ();
               p.Loan__c = c.Id;
               p.CurrencyISOCode = c.CurrencyISOCode;
        for (integer i = 1; i <= c.Number_Of_Repayments__c;i++) {
            p.Expected_Repayment_Date__c = c.Hidden_First_Payment_Date__c + (30 * i);
            prefToInsert.add(p);
            }
        }
    try {
        insert prefToInsert;
        } catch (system.Dmlexception e) {
        system.debug (e);
        }
}

 the problem i now have is when I save a new Loan record which should trigger this to create x number of repayment records I receive this error:

 

Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger generateloanrepayments caused an unexpected exception, contact your administrator: generateloanrepayments: execution of AfterInsert caused by: System.ListException: Before Insert or Upsert list must not have two identically equal elements: Trigger.generateloanrepayments: line 13, column 1

 

this seems to be an issue within:

 

try {
        insert prefToInsert;
        } catch (system.Dmlexception e) {
        system.debug (e);
        }

 but i can't for the life of me work out what might be causing it  :(

 

if i remove the statement then i get no error but also no records added.

 

any guidance?

 

thanks and kudos to all of you for helping me get this far.

 

dan

 

 

MellowRenMellowRen

Ooops. Fair enough. We're trying to insert the same record multiple times. Will write a modifed version in a tick.

DanielBProbertDanielBProbert

no worries all I've just worked it out with a mix of everything that was sent through this is my final code that works perfectly.

 

 

trigger generateloanrepayments on Loan__c (after insert) {        
    List <Loan_Repayments__c> prefToInsert = new List <Loan_Repayments__c> ();
        for (Loan__c c : Trigger.new) {  
            for (integer i = 1; i <= c.Number_Of_Repayments__c;i++) {
                Loan_Repayments__c p = new Loan_Repayments__c ();
                    p.Loan__c = c.Id;
                    p.CurrencyISOCode = c.CurrencyISOCode;
                    p.Expected_Repayment_Date__c = c.Hidden_First_Payment_Date__c + (30 * i);
            
                prefToInsert.add(p);
                }
            }

        try {
            insert prefToInsert;
            } catch (system.Dmlexception e) {
            system.debug (e);
            }
}

 the issue was the i had 2 seperate sections for the initial loop then a new loop for the date increment - this i got working but found only 1 record was created with the date incremented 5 times. 5 = number of repayments.

 

it was then that i realised what the issue must be so rebuilt like above and it works perfectly.

 

once again kudos to you all wouldn't have worked it out without you.

MellowRenMellowRen

Try this:

 

trigger generateloanrepayments on Loan__c (after insert) {
    private Loan_Repayments__c p;        
    List <Loan_Repayments__c> prefToInsert = new List <Loan_Repayments__c> ();
        for (Loan__c c : Trigger.new) {
            for (integer i = 1; i <= c.Number_Of_Repayments__c;i++) {
               p = new Loan_Repayments__c ();
               p.Loan__c = c.Id;
               p.CurrencyISOCode = c.CurrencyISOCode;
        
            p.Expected_Repayment_Date__c = c.Hidden_First_Payment_Date__c + (30 * i);
            prefToInsert.add(p);
            }
        }
    try {
        insert prefToInsert;
        } catch (system.Dmlexception e) {
        system.debug (e);
        }
}

 

I think that should work. Let us know if there are any further errors.

 

Regards

MellowRen

DanielBProbertDanielBProbert

hey mellow thanks for sending that through what's the benefit of using the method below? 

 

Mine looks almost identical apart from that so just want to understand why that would be beneficial to me?

 

private Loan_Repayments__c p; 
MellowRenMellowRen

Yes, you got it. Funny how our code is basically identical.

 

once again kudos to you all wouldn't have worked it out without you.

 

There is actually a kudos mechanism on this forum (the "star" button under peoples names) if you truly mean this :-)

MellowRenMellowRen

No difference. We simul-posted (I wrote my reply as you wrote down yours). Your version and mine are functionally the same.

 

I personally have a style choice of declaring variables near the top of code, I find it easier for debugging/modifying later. Since I hadn't looked at this for a few days (your long weekend), I just reverted to my style whilst typing a solution for you.