2

tengo mas de 4000 registros en cada uno de los objetos como puedo resolver el error que me aparece de apex cpu time limit exceeded

public class ConciliacionController { 

 //declaracion de variables 

  public List<Cartola__c> ListaCartola {get; set;}
  public List<Cartola__c> ListaCartolaREC {get; set;}
  public List<Pendiente_de_Recaudar__c> ListaPDR{get; set;}
  public List<Pendiente_de_Recaudar__c> ListaPDRREC{get; set;}
  public List<Pendiente_de_Recaudar__c> ListaPDRactualizar{get; set;}
  public List<Pendiente_de_Recaudar__c> ListaPDRactualizarREC{get; set;}
  public Integer contadorCartola {get; set;}
  public Integer contadorPDR {get; set;}
  public integer contadorbucleFORNA {get;set;}  
  public integer contadorbucleIF {get;set;}
  public integer contadorbucleFOR1 {get;set;}    
  public integer contadorbucleFOR2 {get;set;}   
  public integer conteolistaNA {get;set;}
  public integer conteolistaFinal {get;set;}
  public Boolean ConciliarRegistro{ get; set;}
  public Boolean MSG {get;set;}
  public Boolean MSG1 {get;set;}  
  public List<Pendiente_de_Recaudar__c> ListaPDRNA {get; set;}
  public List<Pendiente_de_Recaudar__c> ListaPDRNAActualiza {get; set;}  

  public ConciliacionController() //metodo constructor
  {
      ListaCartola = new List<Cartola__c>();
      ListaCartolaREC = new List<Cartola__c>();
      ListaPDR = new List<Pendiente_de_Recaudar__c>();
      ListaPDRREC = new List<Pendiente_de_Recaudar__c>();
      ListaPDRactualizar = new List<Pendiente_de_Recaudar__c>();
      ListaPDRactualizarREC = new List<Pendiente_de_Recaudar__c>();
      contadorCartola = 0;
      contadorPDR = 0;
      contadorbucleIF = 0;
      contadorbucleFOR1 = 0;
      contadorbucleFOR2 = 0;
      contadorbucleFORNA = 0;
      conteolistaNA = 0;
      conteolistaFinal = 0;
      ConciliarRegistro = false;
      MSG = true;
      ListaPDRNA = new List<Pendiente_de_Recaudar__c>();
      ListaPDRNAActualiza = new List<Pendiente_de_Recaudar__c>();
  }      

  public PageReference NA() {
              ListaPDRNA = [SELECT id, name,Recaudado__c,Codigo_PR__c, Razon_Social_Cartola__c, RUT__c,Encontrado__c
                            FROM Pendiente_de_Recaudar__c];

        FOR(Pendiente_de_Recaudar__c prNA : ListaPDRNA) 
            {
                prNA.RUT__c = 'N/A';
                prNA.Razon_Social_Cartola__c = 'N/A';
                //prNA.Encontrado__c = false;
                ListaPDRNAActualiza.add(prNA);
                contadorbucleFORNA = contadorbucleFORNA + 1;
            }

        update ListaPDRNAActualiza;
      conteolistaNA = ListaPDRNAActualiza.size();
        reset1();

        ApexPages.Message resultadoMSG1 = new ApexPages.Message(ApexPages.Severity.confirm, 'N/A listos');
        ApexPages.addmessage(resultadoMSG1);

    return null;
}

 public PageReference CuentaTotales() // metodo para desplegar los totales en la pagina vf
  {
            ConciliarRegistro = true;

    /*    ListaCartola = [SELECT id, name, Enviado_o_recaudado__c,Codigo_Cartola__c,Razon_Social_Cartola__c,RUT__c,Pendiente_disponible__c
                        FROM cartola__c 
                        WHERE Enviado_o_recaudado__c = False]; 


        ListaPDR = [SELECT id, name,Recaudado__c,Codigo_PR__c,Encontrado__c
                                FROM Pendiente_de_Recaudar__c 
                                WHERE Recaudado__c = False];

        contadorCartola =  ListaCartola.size(); //desde aqui saco el total de cartolas a recaudar
        contadorPDR = ListaPDR.size(); //desde aqui saco el total de pendientes a recaudar*/

      //id, name,Pendiente_disponible__c
      Map<id,Cartola__c> C = new Map<id,Cartola__c>([SELECT Enviado_o_recaudado__c ,Codigo_Cartola__c,RUT__c,Razon_Social_Cartola__c
                                                    FROM cartola__c 
                                                    WHERE Enviado_o_recaudado__c = False ]);                    

      //id, name,Recaudado__c,
      Map<id,Pendiente_de_Recaudar__c> P = new Map<id,Pendiente_de_Recaudar__c> ([SELECT Codigo_PR__c,Encontrado__c
                                                                                  FROM Pendiente_de_Recaudar__c 
                                                                                 WHERE Encontrado__c = False]);

      List<Cartola__c> Listcartola = C.values() ;
      List<Pendiente_de_Recaudar__c> ListPen = p.values();


        FOR(Cartola__c car : Listcartola)
        {
            contadorbucleFOR1 = contadorbucleFOR1 + 1;

            for(Pendiente_de_Recaudar__c pr :ListPen)
            {
                contadorbucleFOR2 = contadorbucleFOR2 + 1;

                 if(pr.Codigo_PR__c == car.Codigo_Cartola__c & pr.Encontrado__c == false ) 
                 {
                    pr.RUT__c = car.RUT__c;
                    pr.Razon_Social_Cartola__c = car.Razon_Social_Cartola__c;
                    pr.Encontrado__c = true;
                    ListaPDRactualizar.add(pr);
                    contadorbucleIF = contadorbucleIF + 1; 

                  //update ListaPDRactualizar; 
                  Break; 
                 }
            } 
        }
        update ListaPDRactualizar; 
      conteolistaFinal = ListaPDRactualizar.size(); 

        reset();

        ApexPages.Message resultadoMSG1 = new ApexPages.Message(ApexPages.Severity.confirm, 'Proceso finalizado con éxito');
        ApexPages.addmessage(resultadoMSG1);              


        return null; 
  }  

public void reset1()
{
  ListaPDRNAActualiza = new List<Pendiente_de_Recaudar__c>();
}

public PageReference Limpiar()
{
       contadorCartola = 0;
       contadorPDR = 0;

       ConciliarRegistro = true;
       MSG = true;

       return null;
 }     

 public void reset()
 {
     ListaCartola = new List<Cartola__c>();
     ListaPDR = new List<Pendiente_de_Recaudar__c>();
     ListaPDRactualizar = new List<Pendiente_de_Recaudar__c>(); 
     ConciliarRegistro = true;   
 }    
}

From Google translate:

I have over 4000 records in each of the objects as I can resolve the error appears me apex cpu time limit exceeded,

from what I've read it and I checked the error ocaciona within loops but not how to use the map if anyone can help

I think this is where the error rises help please

  • por lo que he leido el y he comprobado el error se ocaciona dentro de los bucles for pero no se como utilizar los map si alguien puede ayudarme – user7957 Apr 17 '14 at 17:47
0

Finding a match by looping over values in an inner loop when looping over values in an outer loop causes the execution time to grow exponentially and so can run you into the CPU limit more quickly than you might expect. Better to have the time grow linearly with the number of entries by using a map lookup instead.

(Encontrar a un partido por encima de los valores de bucle en un bucle interno cuando un bucle sobre los valores en un bucle exterior hace que el tiempo de ejecución para crecer de manera exponencial y por lo que puede funcionar en el límite de la CPU más rápido de lo que cabría esperar. Es mejor tener el tiempo crece linealmente con el número de entradas utilizando un mapa de búsqueda en su lugar.)

So instead of the exponentially expensive (así que en lugar de la cara de forma exponencial):

FOR(Cartola__c car : Listcartola)
{
    for(Pendiente_de_Recaudar__c pr :ListPen)
    {
        if(pr.Codigo_PR__c == car.Codigo_Cartola__c & pr.Encontrado__c == false )
        {
            ..
        }
    }
}
update ListaPDRactualizar;

use something like this that is linearly expensive (usar algo como esto que es linealmente caro);

Map<String, Cartola__c> m = new Map<String, Cartola__c>();
for (Cartola__c car : Listcartola) {
    m.put(Codigo_Cartola__c, car);
}
for(Pendiente_de_Recaudar__c pr : ListPen) {
    if (pr.Encontrado__c == false) {
         Cartola__c car = m.get(pr.Codigo_PR__c);
         if (car != null) {
             pr.RUT__c = car.RUT__c;
             pr.Razon_Social_Cartola__c = car.Razon_Social_Cartola__c;
             pr.Encontrado__c = true;
             ListaPDRactualizar.add(pr);
         }
    }
}
update ListaPDRactualizar;
  • la solucion fue excelente muchas gracias, ahora me surgio otro problema el cual es que solo debo marcar un registro de los pendientes, lo que el código hace en estos momentos es que toma el codigo de una cartola y busca las coincidencias en todos los pendientes si encuentra 20 a los 20 le asigna los valores, lo que necesito es que solo le asigne los valores de la cartola al primer pendiente encontrado y siga con la búsqueda de la siguiente cartola y su pendiente la relación de cartola y pendiente debe ser de 1 a 1 a pesar de que existan mas pendientes para 1 cartola – user7957 Apr 20 '14 at 19:22
1

A primera vista, el código parece ser muy exigente en su CPU así que con eso se dice ..

El tiempo máximo de la CPU en los servidores de Salesforce - 10000 milisegundos (límite sincrónico) 60.000 milisegundos (límite asíncrono).

Es posible que tenga que entrar y editar y perfeccionar algunos de su código, este puede ser un buen lugar para empezar.

http://wiki.developerforce.com/page/Apex_Code_Best_Practices

también

How to code more efficient to avoid "Apex CPU time limit exceeded"?

English

At first glance your code appears to be very taxing on your CPU so with that being said..

The Maximum CPU time on the salesforce servers - 10,000 milliseconds (Synchronous limit) 60,000 milliseconds(Asynchronous limit).

You may have to go in and edit and refine some of your code, This may be a good place to start.

http://wiki.developerforce.com/page/Apex_Code_Best_Practices

also

How to code more efficient to avoid "Apex CPU time limit exceeded"?

Edit..

No sé si va a arreglar el problema, pero debe ser la creación de un conjunto de identificadores de Cartola__c y Pendiente_de_Recaudar__c. Luego usando los conjuntos de identificadores que debe buscar en el objeto contrario.

  • he intentado utilizar el metodo map<> pero no he tenido suerte en su utilización podrías ayudarme a desarrollarlo? – user7957 Apr 17 '14 at 19:01
  • ¿Usted está consiguiendo los errores que no sean de tiempo de espera de la CPU? ¿Qué estás tratando de hacer? – EricSSH Apr 17 '14 at 19:04
  • lo que quiero hacer en que busque dentro de todas las cartola__c y de todos los registro Pendiente_de_Recaudar__c que encuentre si los codigos son iguales que pase los valores al objeto contrario, pero son tantos registros que me da un error de CPU " apex cpu time limit exceeded ", al parecer el error que me da es donde tengo los for anidados y por ultimo un IF – user7957 Apr 17 '14 at 19:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.