Ir al contenido



Foto

Una Lista de Record que contiene otra Lista (Lista de record anidados)


  • Por favor identifícate para responder
3 respuestas en este tema

#1 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.368 mensajes
  • LocationRepública Dominicana

Escrito 06 junio 2018 - 11:53

Estimados, tengo una situación que no sé cómo enfrentarlo, tengo los siguientes records:


delphi
  1. //Guardamos las salidas de cada insumo
  2. TTotalSalidas = record
  3. tsTitulo: String;
  4. tsTotal: Extended;
  5. tsSubMonto: Extended;
  6. tsItbis: Extended;
  7. tsMonto: Extended;
  8. end;
  9.  
  10. //Guardamos el inicial del mes anterior
  11. TTotalInicial = record
  12. tiTitulo: String;
  13. tiTotal: Extended;
  14. tiSubMonto: Extended;
  15. tiItbis: Extended;
  16. tiMonto: Extended;
  17. end;
  18.  
  19. //Guardamos todas las entradas
  20. TTotalEntradas = record
  21. teTitulo: String;
  22. teTotal: Extended;
  23. teSubMonto: Extended;
  24. teItbis: Extended;
  25. teMonto: Extended;
  26. end;
  27.  
  28. //Guardamos los insumos con sus datos
  29. TInsumoData = record
  30. ICodigo: Integer;
  31. INombre: String;
  32. ICategoria: String;
  33. ISalidas: TTotalSalidas;
  34. IEntradas: TTotalEntradas;
  35. IInicial: TTotalInicial;
  36. end;

Los datos de esos records debo guardarlos en este otro:


delphi
  1. //Guardamos los datos del corte
  2. TCorteInventario = record
  3. CCategoria: String;
  4. CInsumos: TList<TInsumoData>;
  5. end;

Aquí ya la cosa se complica, TCorteInventario tiene una Lista TList<TInsumoData> y debo hacer una iteración de datos y guardarlo en CInsumos, el detalle es que creo tendría problemas de crear y eliminar la lista, pero eso no es todo, yo necesito hacer una lista de TCorteInventario, algo así:


delphi
  1. Cortes: TList<TCorteInventario>;

De nuevo, aquí tengo el problema de nuevo de la creación y eliminación de las listas.

 

la lista debería de quedar como una especie de arreglo:

 

Cortes = [

   corte-1 -> [
                CCategoria = 'BATERIAS';
                CInsumos = [
                              insumo-1 = [
                                Nombre = BATERIA 15/12 CELDA HUMEDAS
                                ISalidas = [ titulo = 'DESPACHOS', cantidad = 65, Susbmonto = 1,000, itbis = 50, monto = 1050 ],
                                IEntradas = [ titulo = 'ENTRADAS', cantidad = 20, Susbmonto = 450, itbis = 50, monto = 500 ],
                                IInicial = [ titulo = 'CORTE INICIAL', cantidad = 120, Susbmonto = 4,000, itbis = 250, monto = 4,250 ]
                              ],
                              insumo-2 = [
                                Nombre = BATERIA 25/12 CELDA HUMEDA
                                ISalidas = [ titulo = 'DESPACHOS', cantidad = 65, Susbmonto = 1,000, itbis = 50, monto = 1050 ],
                                IEntradas = [ titulo = 'ENTRADAS', cantidad = 20, Susbmonto = 450, itbis = 50, monto = 500 ],
                                IInicial = [ titulo = 'CORTE INICIAL', cantidad = 120, Susbmonto = 4,000, itbis = 250, monto = 4,250 ]
                              ],
                              ...                              
                           ]
                    ],
   corte-2 -> [
                CCategoria = 'HERRAMIENTAS';
                CInsumos = [
                              insumo-1 = [
                                Nombre = DESTORNILLADOR PLANO 4"
                                ISalidas = [ titulo = 'DESPACHOS', cantidad = 65, Susbmonto = 1,000, itbis = 50, monto = 1050 ],
                                IEntradas = [ titulo = 'ENTRADAS', cantidad = 20, Susbmonto = 450, itbis = 50, monto = 500 ],
                                IInicial = [ titulo = 'CORTE INICIAL', cantidad = 120, Susbmonto = 4,000, itbis = 250, monto = 4,250 ]
                              ],
                              insumo-2 = [
                                Nombre = MARTILLO 8"
                                ISalidas = [ titulo = 'DESPACHOS', cantidad = 65, Susbmonto = 1,000, itbis = 50, monto = 1050 ],
                                IEntradas = [ titulo = 'ENTRADAS', cantidad = 20, Susbmonto = 450, itbis = 50, monto = 500 ],
                                IInicial = [ titulo = 'CORTE INICIAL', cantidad = 120, Susbmonto = 4,000, itbis = 250, monto = 4,250 ]
                              ],
                              ...                              
                           ]
                    ]                    
                    
   corte-3 -> [
                CCategoria = 'NEUMATICOS';
                CInsumos = [
                              insumo-1 = [
                                Nombre = GOMA 175/R15
                                ISalidas = [ titulo = 'DESPACHOS', cantidad = 65, Susbmonto = 1,000, itbis = 50, monto = 1050 ],
                                IEntradas = [ titulo = 'ENTRADAS', cantidad = 20, Susbmonto = 450, itbis = 50, monto = 500 ],
                                IInicial = [ titulo = 'CORTE INICIAL', cantidad = 120, Susbmonto = 4,000, itbis = 250, monto = 4,250 ]
                              ],
                              insumo-2 = [
                                Nombre = GOMA 245/R16
                                ISalidas = [ titulo = 'DESPACHOS', cantidad = 65, Susbmonto = 1,000, itbis = 50, monto = 1050 ],
                                IEntradas = [ titulo = 'ENTRADAS', cantidad = 20, Susbmonto = 450, itbis = 50, monto = 500 ],
                                IInicial = [ titulo = 'CORTE INICIAL', cantidad = 120, Susbmonto = 4,000, itbis = 250, monto = 4,250 ]
                              ],
                              ...                              
                           ]
                    ]                    

]

 

Se me ocurre utilizar un array of TInsumoData en el record TCorteInventario, la verdad no sé cómo atacar éste asunto..

 

¿Alguna idea?


  • 0

#2 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.368 mensajes
  • LocationRepública Dominicana

Escrito 06 junio 2018 - 01:46

Me respondo, sí, tuve que utilizar un array of TInsumoData para lograr mi cometido,al final hice el siguiente procedimiento:


delphi
  1. //Guardamos los insumos con sus datos
  2. TInsumoData = record
  3. ICodigo: Integer;
  4. INombre: String;
  5. ICategoria: String;
  6. ISalidas: TTotalSalidas;
  7. IEntradas: TTotalEntradas;
  8. IInicial: TTotalInicial;
  9. end;
  10.  
  11. //Guardamos los datos del corte
  12. TCorteInventario = record
  13. CCategoria: String;
  14. CInsumos: array of TInsumoData;
  15. end;
  16.  
  17. ....
  18.  
  19. ListaCortes: TList<TCorteInventario>;
  20.  
  21. ....
  22.  
  23. procedure TFProcesaCorte.ProcesaCorte(aMes: Integer; aYear: Integer);
  24. var aLastDate,aDesde,aHasta: TDateTime;
  25. aMonth: Integer;
  26. Categorias: TFDQuery;
  27. Insumos: TInsumoData;
  28. aCorte: TCorteInventario;
  29. begin
  30. case aMes of
  31. 1..11: aMonth := aMes;
  32. 0: aMonth := 12;
  33. end;
  34.  
  35. //obtenemos el último día del mes anterior
  36. aLastDate := EndOfAMonth(aYear, aMonth);
  37.  
  38. //obtenemosel primer día del mes seleccionado
  39. aDesde := StartOfAMonth(aYear, aMes + 1);
  40. aHasta := EndOfAMonth(aYear,aMes + 1);
  41.  
  42. picLoader.Visible := True;
  43. picLoader.Animate := True;
  44. picLoader.AsyncDrawing := True;
  45.  
  46. ListaCortes := TList<TCorteInventario>.Create;
  47. try
  48. //Primero obtenemos las categorías de los insumos
  49. Categorias := TFDQuery.Create(Self);
  50. try
  51. Categorias.Connection := Datos.dbDatos;
  52. Categorias.Transaction := Datos.trReadTransaction;
  53. Categorias.SQL.Add('select * from insumos_cat order by ins_cat_name asc');
  54. try
  55. Categorias.Open;
  56.  
  57. if not Categorias.IsEmpty then begin
  58.  
  59. //Recorremos las categorias y obtenemos los insumos que correspondan
  60. Categorias.First;
  61. while not Categorias.Eof do begin
  62.  
  63. lbProcess.Caption := 'Obteniendo los insumos...';
  64.  
  65. aCorte.CCategoria := Categorias.FieldByName('ins_cat_name').AsString;
  66.  
  67. QInsumo.Close;
  68. try
  69. QInsumo.Params[0].AsInteger := Categorias.FieldByName('ins_cat').AsInteger;
  70. QInsumo.Open;
  71.  
  72. if not QInsumo.IsEmpty then begin
  73. QInsumo.First;
  74. while not QInsumo.Eof do begin
  75.  
  76. Insumos.ICodigo := QInsumo.FieldByName('ins_id').AsInteger;
  77. Insumos.INombre := QInsumo.FieldByName('insumo').AsString;
  78. Insumos.ICategoria := Categorias.FieldByName('ins_cat_name').AsString;
  79. Insumos.ISalidas := getCorteSalidas(QInsumo.FieldByName('ins_id').AsInteger,aDesde,aHasta);
  80. Insumos.IEntradas := getCorteEntradas(QInsumo.FieldByName('ins_id').asInteger,aDesde,aHasta);
  81. Insumos.IInicial := getCorteInicial(QInsumo.FieldByName('ins_id').AsInteger,aLastDate);
  82.  
  83. Insert(Insumos,aCorte.CInsumos,High(aCorte.CInsumos));
  84.  
  85. QInsumo.Next;
  86.  
  87. end;
  88.  
  89. end;
  90.  
  91. finally
  92. QInsumo.Close;
  93. end;
  94.  
  95. ListaCortes.Add(aCorte);
  96.  
  97. Categorias.Next;
  98.  
  99. aCorte.CInsumos := nil;
  100.  
  101. end;
  102.  
  103. end;
  104. except
  105. Exit;
  106. end;
  107.  
  108. finally
  109. Categorias.Free;
  110. end;
  111.  
  112. finally
  113. ListaCortes.Free;
  114.  
  115. picLoader.Animate := False;
  116. picLoader.Visible := False;
  117. picLoader.AsyncDrawing := False;
  118. end;
  119.  
  120. end;

El tema del rendimiento ya será para otro momento, pero, aún así acepto sugerencias.

 

Saludos.


  • 0

#3 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.759 mensajes
  • LocationMadrid - España

Escrito 06 junio 2018 - 02:19

TTotalSalidas, TTotalInicial y TTotalEntradas son en realidad, la misma estructura con lo que ahorras complejidad. No he usado los Templates en delphi pero si es como en CPP y en el caso de TList, simplemente  se trataría de una lista de punteros de determinado tipo. Para destruirlos basta con recorrer la lista y destruirlos para vaciarla después.  El array dinámico también puede ser una solución, pero mas engorrosa que un TList si hay que añadir y borrar estructuras con frecuencia.

 

TCorteInventario  podría ser una clase que encapsule toda la funcionalidad que necesites con los TList

 

Quizás Agustin Ortu te oriente mejor en el tema de POO y nuevas características de delphi, pero por lo que veo, yo haría lo que te he comentado y usaría TList antes que arrays dinámicos.

 

 

Saludos.


  • 0

#4 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.368 mensajes
  • LocationRepública Dominicana

Escrito 06 junio 2018 - 04:07

...pero por lo que veo, yo haría lo que te he comentado y usaría TList antes que arrays dinámicos.

 

 

Saludos.

 

Esa era la intención en un principio, mi incertidumbre era ¿cómo creaba esas listas anidadas durante un ciclo while ó For?, ¿Al final no se pierde esa información al liberar la lista antes de pasar al siguiente registro?, por eso decidí por los arrays dinámicos para resolver un problema rápida.

 

Fíjate que ahora que lo comentas, tienes razón, no me había fijado que esos tres records tienen la misma estructura mie...a, gracias por la observación, ahora mismo lo corrijo.

 

Saludos.


  • 0