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
sparktestsparktest 

expecting semi colon, found " problem

I am getting the below error on the myMethod line below.  for the life of me I cannot figure out why....obviously the semi-colon is there.

 

Any help from another pair of eyes would be great!

 

Thanks,


Save error: expecting a semi-colon, found '' SiteLeaseCumCostUpdate/src/classes SiteLeaseFncTblClass.cls line 182

 

 

if (j > 100)

{

myMethod(List<String> ListLeaseID, List<Date> ListDate, List<Decimal> ListCumDefRent, List<Decimal> ListRent, List<Integer> ListTerm);

}

else if (j <= 100)

{

insert followuprecords;

}

else

{

}

Best Answer chosen by Admin (Salesforce Developers) 
JustinCJustinC

#1) Are you still having issues with "Save error: Method does not exist or incorrect signature" or has that been resolved? You have to make sure that when you call myMethod you are sending it lists of the appropriate type of variables which you've defined as lists of String, Date, Decimal, Decimal, Integer (in that order)

 

#2) The first thing I would try is to change the way your insert works inside myMethod. In this context, you shouldn't put an insert inside the loop, because that causes the insert to be called once per loop. Governor limits only allow a limited amount of insert calls(the records are another thing - see below)

 

For the governnor limits see:

http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_gov_limits.htm?SearchType=Stem

 

Total number of DML statements issued (insert, update, upsert, merge, or delete)

 

The proper way to handle this is to create a List of objects to insert, and then call insert after the loop is done, on the list that has been built. So define a list of the objects you want to insert, and in each loop keep adding to this list. Then outside the loop call "insert objects;" where objects is whatever you named your list.. This will also make the code much faster, as you send multiple records to insert at once, rather than making a separate insert call once per loop.

 

In an @future method you can cause 10,000 records to be inserted, but you can only call insert 100 times. For 120 records, that should only require 1 of the available 100 insert statements.

 

All Answers

grigri9grigri9

You don't need to enter the parameter types when you call a function. So, assuming all these variables are already created you can do the following:

 

 

myMethod(ListLeaseID, ListDate, ListCumDefRent, ListRent, ListTerm);

 

 

 

sparktestsparktest

 

I replaced with your text, and this is what it now gives me...

 


Save error: Method does not exist or incorrect signature: myMethod(LIST:String, LIST:Date, LIST:Decimal, LIST:Decimal, LIST:Integer) SiteLeaseCumCostUpdate/src/classes SiteLeaseFncTblClass.cls line 182

 

Here is the method I am calling (and the class it is in)

 

global class SiteLeaseFncTblFClass {

@future

Global static void myMethod(List<String> ListLeaseID, List<Date> ListDate, List<Decimal> ListCumDefRent, List<Decimal> ListRent, List<Integer> ListTerm){

Integer ListCount = ListLeaseID.size() - 1;

for (Integer k = 0; k < ListCount; k++) {

SiteFnc__c a = new SiteFnc__c(Site_Lease__c=ListLeaseID.get(k), Date__c=ListDate.get(k), Cumulative_Def_Rent_Obl__c=ListCumDefRent.get(k), Rent__c=ListRent.get(k), Term__c=ListTerm.get(k));

insert a;

}

}

}

sparktestsparktest

It is strange.  I have battled through several different issues and I thought I had it, but this is catching me.  Basically, I am trying to create a maximum of 120 records.  With a limit of 100, I have to use an asynchronous call if it goes over that, however the @future method cannot accept SObjects as arguments, so I have to use a list primitive data type for each field.  So, I am doing the processing, creating the lists, and sending the lists to the @future method if the count is over 100......

 

Any help would be great.  With the DML limits being so low, this has got to be a common issue.

 

Thanks,

 

 

grigri9grigri9

If you are trying to create a maximum of 120 records you can do that in one DML statement by inserting a collection of Sobjects.

 

The governor limit you are hitting is that you can only have 100 separate DML statements. In your loop your are creating one Sobject and then inserting it. What you should be doing is adding those Sobjects to a list and then inserting that list all at once.

 

You may want to check this out for more in depth information. I think List insertion is on page 30 something.

 

http://www.salesforce.com/us/developer/docs/apexcode/salesforce_apex_language_reference.pdf



--Greg

Message Edited by grigri9 on 02-23-2009 08:29 PM
sparktestsparktest

I am, but if I do more than 120 it is still giving me a 'too many DML' statement error.  here is the pertinent code........I define the list, add fields/records to the 'SiteFnd__c' SObject, then add that SObject To the List, and then at the end insert the entire list.

 

public static void SiteLeaseFncTblTrigger(Site_Lease_Contract__c[] newSiteLeaseFncTbl)

List<SiteFnc__c> followuprecords = new List<SiteFnc__c>();

for (Integer i = 0; i < Trigger.new.size(); i++)

{

 SiteFnc__c SiteFnc = new SiteFnc__c(

Site_Lease__c = LeaseID,

Date__c = MonthBegin.addmonths(k),

Cumulative_Def_Rent_Obl__c = SLD * (k+1),

Rent__c = RentToPay,

Term__c = TermToCheck);

 

followuprecords.add(SiteFnc);

}

(after the looping is done)

 

insert followuprecords;

sparktestsparktest
correction....if i do more than 100....
sparktestsparktest
Presently I am just trying to create a conditional work-around  wih the @future method....which is not working correctly yet either.   I am getting 'cannot call @future method from @future method' errors......according to what I have found so far....I am not calling it that way.....but apparently I am missing something
HarmpieHarmpie

The message 'cannot call @future method from @future method' is because the update that you do asynchronous, is firing the same trigger again. You can work around this by surrouding your trigger code with a conditional statement to verify whether the trigger has executed already. E.g. if your trigger is updating the Account Billingaddress field:

 

 

if(Trigger.old[0].BillingAddress != Trigger.new[0].BillingAddress) { //Triggercode }

 

HarmpieHarmpie
Did you try calling it as : SiteLeaseFncTblFClass.myMethod(.....); ?
sparktestsparktest

SiteLeaseFncTblFClass.myMethod(ListLeaseID, ListDate, ListCumDefRent, ListRent, ListTerm);

 

 

I tried calling it this way, and I get this

 


Save error: Method does not exist or incorrect signature: SiteLeaseFncTblFClass.myMethod(LIST:String, LIST:Date, LIST:Decimal, LIST:Decimal, LIST:Integer) SiteLeaseCumCostUpdate/src/classes SiteLeaseFncTblClass.cls line 182 1235490754531 1234

 

HarmpieHarmpie
Could you paste the full class + calling trigger code?
sparktestsparktest

Here is the trigger

 

trigger SiteLeaseFncTblTrigger on Site_Lease_Contract__c (after update, after insert) { SiteLeaseFncTblClass.SiteLeaseFncTblTrigger( Trigger.new ); }

 

Here is the full code.....there is a lot to it......but basically, after a record is added to the parent object, I check a couple conditions, see how many months the cycle needs to go, and see how much the payment needs to go up each year (whether percentage or dollar amount).  Then I cycle through that, created an SObject for the insert, and a list for the @future method, if the count is > 100.  I know that I shouldn't have to do this, but that is what is going on for some reason.

 

 

public class SiteLeaseFncTblClass { public static void SiteLeaseFncTblTrigger(Site_Lease_Contract__c[] newSiteLeaseFncTbl) { List<SiteFnc__c> followuprecords = new List<SiteFnc__c>(); List<List<String>> sitefnclist = new List<List<String>>(); for (Integer i = 0; i < Trigger.new.size(); i++) { Boolean GT = newSiteLeaseFncTbl[i].Generate_Table__c; Boolean CT = newSiteLeaseFncTbl[i].Clear_Table__c; Double Months = newSiteLeaseFncTbl[i].Lease_Term_In_Months__c; Double RMonths = newSiteLeaseFncTbl[i].Renew_Term__c; Double RTerms = newSiteLeaseFncTbl[i].Renew_Addl_Terms__c; String LeaseID = newSiteLeaseFncTbl[i].id; Date MonthBegin = newSiteLeaseFncTbl[i].Start_Date__c; Double TermToGenD = newSiteLeaseFncTbl[i].Term_To_Generate__c; String LeaseSFID = newSiteLeaseFncTbl[i].Id; Integer countfnc = [select count() from SiteFnc__c where Term__c = :TermToGenD AND Site_Lease__c = :LeaseID]; //SiteFnc__c fncdelete=[select id from SiteFnc__c where Term__c = :TermToGenD AND Site_Lease__c = :LeaseID]; List<SiteFnc__c> fncdelete=[select id from SiteFnc__c where Term__c = :TermToGenD AND Site_Lease__c = :LeaseID]; //list declaration for @future annotated method // List<String> ListLeaseID = new List<String>(); List<Date> ListDate = new List<Date>();//Cumulative_Def_Rent_Obl List<Decimal> ListCumDefRent = new List<Decimal>(); List<Decimal> ListRent = new List<Decimal>(); List<Integer> ListTerm = new List<Integer>(); // // Integer NumRTerms = RTerms.intValue();//number of additional term cycles Integer Term1Len = Months.intValue();//lenth of initial term Integer TermRLen = RMonths.intValue();//length of additional term cycles Integer a = Term1Len; Integer CycleInsert = 0;//the month within the full cycle being calc'ed Integer TermToGenI = TermToGenD.intValue(); Map<Integer, Integer> TermMap = new Map<Integer, Integer> {}; Integer p = 0;//p = totals up the number of months for all terms for (Integer m = 1; m <= Term1Len; m++) { TermMap.put(m, 1); p = m+1; } for (Integer o = 0; o < NumRTerms; o++) { for (Integer n = 0; n < TermRLen; n++) { TermMap.put (p, o + 2); p = p + 1; } } Boolean resultpct = False; Boolean resultdlr = False; Double escpct = 0; Double escdlr = 0; String escamt = newSiteLeaseFncTbl[i].Escalation_Amount__c; resultpct = escamt.startsWith('%'); resultdlr = escamt.startsWith('$'); String escamtS = escamt.substring(1); Double escmth = newSiteLeaseFncTbl[i].Escalation_Month__c; Double RentToPay = newSiteLeaseFncTbl[i].Initial_Rent__c; Double SLD = newSiteLeaseFncTbl[i].Straight_Line_Depr__c; Double j = Months + (RMonths * RTerms);//Integer mths = mthsD.intValue(); if (GT == True && countfnc == 0) { if (resultpct == True && resultdlr == False) { escpct = 1 + (double.valueOf(escamtS))/100; Integer Count = 1; CycleInsert = 1; for (Integer k = 0; k < j; k++) { if (escmth == k+1) { RentToPay = RentToPay * escpct; } if (k+1 > escmth) { Count = Count + 1; } if (Count == 13 && k+1 > escmth -1 ) { Count = 1; RentToPay = RentToPay * escpct; } Integer TermToCheck = TermMap.get(CycleInsert); SiteFnc__c SiteFnc = new SiteFnc__c( Site_Lease__c = LeaseID, Date__c = MonthBegin.addmonths(k), Cumulative_Def_Rent_Obl__c = SLD * (k+1), Rent__c = RentToPay, Term__c = TermToCheck); ListLeaseID.add(LeaseID); ListDate.add(MonthBegin.addmonths(k)); ListCumDefRent.add(SLD * (k+1)); ListRent.add(RentToPay); ListTerm.add(TermToCheck); //remove to allow all months to be generated // //If (TermToCheck == TermToGenI){ followuprecords.add(SiteFnc); //} CycleInsert = CycleInsert + 1; }//for integer k loop } else if (resultpct == False && resultdlr == True) { escdlr = double.valueOf(escamtS); //Double j = Months + (RMonths * RTerms);//Integer mths = mthsD.intValue(); Integer Count = 1; CycleInsert = 1; for (Integer k = 0; k < j; k++) { if (escmth == k+1) { RentToPay = RentToPay + escdlr; } if (k+1 > escmth) { Count = Count + 1; } if (Count == 13 && k+1 > escmth -1 )//cycles amount of rent based on 12 month cycles { Count = 1; RentToPay = RentToPay + escdlr; } Integer TermToCheck = TermMap.get(CycleInsert); SiteFnc__c SiteFnc = new SiteFnc__c( Site_Lease__c = LeaseID, Date__c = MonthBegin.addmonths(k), Cumulative_Def_Rent_Obl__c = SLD * (k+1), Rent__c = RentToPay, Term__c = TermToCheck); ListLeaseID.add(LeaseID); ListDate.add(MonthBegin.addmonths(k)); ListCumDefRent.add(SLD * (k+1)); ListRent.add(RentToPay); ListTerm.add(TermToCheck); //remove to allow all months to be generated // //If (TermToCheck == TermToGenI){ followuprecords.add(SiteFnc); //} CycleInsert = CycleInsert + 1; }//for integer k loop } else { } //replaced this if (j > 100) { //@future myMethod(ListLeaseID, ListDate, ListCumDefRent, ListRent, ListTerm); //insert followuprecords; } else if (j <= 100) { insert followuprecords; } else { } //with this for testing purposes //SiteLeaseFncTblFClass.ProcessList(followuprecords); // } else if(CT == True && countfnc != 0) { delete fncdelete; } //Site_Lease_Contract__c ResetGenTable=[select id, Name, Generate_Table__c from Site_Lease_Contract__c where id = :LeaseSFID]; //ResetGenTable.Generate_Table__c=false; //update ResetGenTable; } //if GT = true end }//public static void end @future static void myMethod(List<String> ListLeaseID, List<Date> ListDate, List<Decimal> ListCumDefRent, List<Decimal> ListRent, List<Integer> ListTerm){ Integer ListCount = ListLeaseID.size() - 1; for (Integer k = 0; k < ListCount; k++) { SiteFnc__c a = new SiteFnc__c(Site_Lease__c=ListLeaseID.get(k), Date__c=ListDate.get(k), Cumulative_Def_Rent_Obl__c=ListCumDefRent.get(k), Rent__c=ListRent.get(k), Term__c=ListTerm.get(k)); insert a; } } }

 

HarmpieHarmpie

Did you try the same code, without the @future annotation at the myMethod declaration? Does not seem much wrong with the invocation itsself. Ofcourse you can try calling it as this.myMethod() etc., but I have a feeling that the @future is the problem..

 

sparktestsparktest

 

I can remove the @future and it will work, so long as it is less than 101 records (which means that it does not use the method at all).  I don't know, I have about had it......the code samples I have seen say I should be able to load 120 records without hitting the DML limits IF I use an array insert.....which I am.  I could not get that to work, so I am experimenting with the @future....and have not been able to get that to work either.   The method doesn't do anything......I do not get an error either......

 

I guess I am just going to start from scratch on this.  Crazy.....but I will get it.

JustinCJustinC

#1) Are you still having issues with "Save error: Method does not exist or incorrect signature" or has that been resolved? You have to make sure that when you call myMethod you are sending it lists of the appropriate type of variables which you've defined as lists of String, Date, Decimal, Decimal, Integer (in that order)

 

#2) The first thing I would try is to change the way your insert works inside myMethod. In this context, you shouldn't put an insert inside the loop, because that causes the insert to be called once per loop. Governor limits only allow a limited amount of insert calls(the records are another thing - see below)

 

For the governnor limits see:

http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_gov_limits.htm?SearchType=Stem

 

Total number of DML statements issued (insert, update, upsert, merge, or delete)

 

The proper way to handle this is to create a List of objects to insert, and then call insert after the loop is done, on the list that has been built. So define a list of the objects you want to insert, and in each loop keep adding to this list. Then outside the loop call "insert objects;" where objects is whatever you named your list.. This will also make the code much faster, as you send multiple records to insert at once, rather than making a separate insert call once per loop.

 

In an @future method you can cause 10,000 records to be inserted, but you can only call insert 100 times. For 120 records, that should only require 1 of the available 100 insert statements.

 

This was selected as the best answer
sparktestsparktest

Great, I will get to trying out what you suggest.  Yes, I did figure out the data type issue relative to the @future method, so I think that part is handled.

 

#1) Question:  I have the @future method noted in the same class as the main method....is that the right place for it, or should it have its own class?  it seems to recognize it better if I have it in the same class, but I wasn't sure if that was proper or not.

 

Thanks for shedding some light on the governor limit characteristics. 

 

#2) Just to double check, in the original scenario (non @future) I am calling the insert just once to insert 120 records....this will not work, correct?  I just want to make sure I am not using the @future if not necessary.

 

Thanks a ton!

JustinCJustinC

#1) You have the @future in the right spot, it goes above the method name, and it doesn't matter if it's in the same class, or some other class.

 

#2) You will need to use an @future method if you plan on updating more than 100 records, regardless of how you make use of the insert statement.

 

I hope this helps!

sparktestsparktest

Helped it sure did......I got it working even better than hoped for.......

 

Thanks....

 

code didn't change much, just a little tweaking in the method..........once seen it was 'duh'.....

 

 

nagalakshminagalakshmi

Hi,

 

I need to insert the records more than 10000. For this i have used @future method. But still getting Too Many dml rows 10001 error. Please help me.

 

My code is

 

global class MyFutureClass {
@future
/*public static void myMethod(set<id> stid, set<string> st )
{
Map<String,Id> stbr1=new Map<string,Id>();
list<storeproduct_category__C> stplist=new list<storeproduct_category__c>();
list<storeproduct_category__C> stplist1=new list<storeproduct_category__c>();
list<storeproduct_category__C> stplist2=new list<storeproduct_category__c>();
for(Product_category__C b : [Select Id,Name from Product_category__C limit 50000])
{
stbr1.put(b.name,b.Id);
}
for(id i:stid)
{
for(String s1:st)
{
storeproduct_category__C s=new storeproduct_Category__C();
StoreProduct_category__C stb=new StoreProduct_category__C ();
stb.Product_category__C =stbr1.get(s1);
stb.store__c=i;
stplist.add(stb);
}

}
system.debug('========' +stplist.size());

for(integer i=0;i<10000;i++)
{
stplist1.add(stplist.get(i));
}
/* if(stplist.size()>10000)
{
for(integer i=10000;i<stplist.size();i++)
{
system.debug('i========' +i+stplist.get(i));
stplist2.add(stplist.get(i));
}
}
if(stplist1.size()>0)
insert stplist1;

//if(stplist2.size()>0)
//insert stplist2;

}
}*/

//public static void myMethod(List<String> ListLeaseID, List<Date> ListDate, List<Decimal> ListCumDefRent, List<Decimal> ListRent, List<Integer> ListTerm)
public static void myMethod(set<id> stid, set<string> st)
{
Map<String,Id> stbr1=new Map<string,Id>();
for(Product_category__C b : [Select Id,Name from Product_category__C limit 50000])
{
stbr1.put(b.name,b.Id);
}
list<id> ilist=new list<id>();
for(id i:stid)
ilist.add(i);

Integer ListCount = ilist.size() - 1;
for (Integer k = 0; k < ListCount; k++)
{
for(string s:st)
{
StoreProduct_category__C stb=new StoreProduct_category__C ();
stb.Product_category__C =stbr1.get(s);
stb.store__c=ilist.get(k);
//stplist.add(stb);
insert stb;
}
}
}

}

 

I have called this class in to my normal apex class as

 

 MyFutureClass.myMethod(setsid,rightvalues1);

 

How can i solve this issue. Please help me out.

 

Thanks,

Lakshmi

JustinCJustinC

I'd like to help, but I'm confused by a few things.

 

#1) You don't have any comments in your code - it makes it very hard to understand what you're trying to do

 

#2) It looks like your @future method is commented out? Why is that?

 

#3) In your @future method, you have a line:

/* if(stplist.size()>10000)

But there is no end to that comment block */ indicating where that comment stops

 

#4) Which line is triggering the DML error? And what is the exact error message?

JustinCJustinC

Can you also paste your code with the indents intact? The indents make it easier to read.

 

nagalakshminagalakshmi

Hi

Actually i am inserting 100 vf page child values in to parent. If i am having 105 records from vf page and i am having 100 parents. I need to insert these 105 records in to every parent. i.e (my list having 105*100=10500 records)

global class MyFutureClass {
@future
public static void myMethod(set<id> stid, set<string> st )
{
//stid having set of storeid's
//st having set of strings
Map<String,Id> stbr1=new Map<string,Id>();
list<storeproduct_category__C> stplist=new list<storeproduct_category__c>();
list<storeproduct_category__C> stplist1=new list<storeproduct_category__c>();
list<storeproduct_category__C> stplist2=new list<storeproduct_category__c>();
for(Product_category__C b : [Select Id,Name from Product_category__C limit 50000])
{
stbr1.put(b.name,b.Id);
//stbr1 having strings with id's
}
for(id i:stid)
{
for(String s1:st)
{
storeproduct_category__C s=new storeproduct_Category__C();
StoreProduct_category__C stb=new StoreProduct_category__C ();
stb.Product_category__C =stbr1.get(s1);
stb.store__c=i;
stplist.add(stb);
}
}
system.debug('========' +stplist.size());
//stplist having morethan 10000 records
for(integer i=0;i<10000;i++)
{
stplist1.add(stplist.get(i));
//here i am splitting the list and stplist1 having first 10000 records
}
if(stplist.size()>10000)
{
for(integer i=10000;i<stplist.size();i++)
{
system.debug('i========' +i+stplist.get(i));
// stplist2 having remaining records that is with out having the first 10000 records.
stplist2.add(stplist.get(i));
}
}
if(stplist1.size()>0)
insert stplist1;
if(stplist2.size()>0)
insert stplist2;
}
}

When i execute this code i am getting 'Too Many dml rows 10001 error'

nagalakshminagalakshmi

And My log file is

 

14:24:48.796 (26796321000)|STATEMENT_EXECUTE|[48]
14:24:48.796 (26796371000)|DML_BEGIN|[48]|Op:Insert|Type:StoreProduct_Category__c|Rows:5704
14:24:48.797 (26797304000)|EXCEPTION_THROWN|[48]|System.LimitException: Too many DML rows: 10001
14:24:48.797 (26797423000)|HEAP_ALLOCATE|[48]|Bytes:28
14:24:48.797 (26797502000)|FATAL_ERROR|System.LimitException: Too many DML rows: 10001

Class.MyFutureClass.myMethod: line 48, column 1
14:24:48.797 (26797588000)|FATAL_ERROR|System.LimitException: Too many DML rows: 10001

Class.MyFutureClass.myMethod: line 48, column 1
14:24:49.408 (26797613000)|CUMULATIVE_LIMIT_USAGE
14:24:49.408|LIMIT_USAGE_FOR_NS|(default)|
Number of SOQL queries: 1 out of 200
Number of query rows: 126 out of 50000
Number of SOSL queries: 0 out of 20
Number of DML statements: 2 out of 150
Number of DML rows: 15704 out of 10000 ******* CLOSE TO LIMIT
Number of script statements: 100063 out of 1000000
Maximum heap size: 0 out of 12000000
Number of callouts: 0 out of 10
Number of Email Invocations: 0 out of 10
Number of fields describes: 0 out of 100
Number of record type describes: 0 out of 100
Number of child relationships describes: 0 out of 100
Number of picklist describes: 0 out of 100
Number of future calls: 0 out of 10

14:24:49.408|CUMULATIVE_LIMIT_USAGE_END

14:24:48.797 (26797652000)|CODE_UNIT_FINISHED|MyFutureClass.myMethod
14:24:48.797 (26797858000)|EXECUTION_FINISHED

 

 

Thanks