Révision 3 UnitDeclaration.pas

Voir les différences:

UnitDeclaration.pas
42 42
    ClientDataSetInraAfz: TClientDataSet;
43 43
    ClientDataSetInraAfzId: TAutoIncField;
44 44
    ClientDataSetInraAfzName: TStringField;
45
    ClientDataSetInraAfzComment: TStringField;
45 46
    ClientDataSetInraAfzSource: TStringField;
46 47
    ClientDataSetInraAfzClass: TIntegerField;
47 48
    ClientDataSetInraAfzMS: TFloatField;
......
112 113
    ClientDataSetInraAfzP: TFloatField;
113 114
    ClientDataSetInraAfzdP: TFloatField;
114 115
    ClientDataSetInraAfzdPphy: TFloatField;
116
    ClientDataSetInraAfzNa: TFloatField;
117
    ClientDataSetInraAfzK: TFloatField;
118
    ClientDataSetInraAfzCl: TFloatField;
115 119
    DataSourceInraAfz: TDataSource;
116 120
    ClientDataSetIngredients: TClientDataSet;
117 121
    ClientDataSetIngredientsId: TIntegerField;
......
238 242
    ClientDataSetIngredientsP: TFloatField;
239 243
    ClientDataSetIngredientsdP: TFloatField;
240 244
    ClientDataSetIngredientsdPphy: TFloatField;
245
    ClientDataSetIngredientsNa: TFloatField;
246
    ClientDataSetIngredientsK: TFloatField;
247
    ClientDataSetIngredientsCl: TFloatField;
248
    ClientDataSetIngredientsBE: TFloatField;
241 249
    DataSourceIngredients: TDataSource;
242 250
    ClientDataSetComposition: TClientDataSet;
243 251
    ClientDataSetCompositionFeed: TIntegerField;
......
364 372
    ClientDataSetFeedsLevelSum: TFloatField;
365 373
    ClientDataSetFeedsTotal: TFloatField;
366 374
    ClientDataSetFeedsRemain: TFloatField;
375
    ClientDataSetFeedsNa: TFloatField;
376
    ClientDataSetFeedsK: TFloatField;
377
    ClientDataSetFeedsCl: TFloatField;
378
    ClientDataSetFeedsBE: TFloatField;
367 379
    DataSourceFeeds: TDataSource;
368
    ClientDataSetInraAfzComment: TStringField;
369 380
    procedure DataModuleCreate(Sender: TObject);
370 381
    procedure DataModuleDestroy(Sender: TObject);
371 382
    procedure ClientDataSetIngredientsFilterRecord(DataSet: TDataSet; var Accept: Boolean);
......
388 399
    procedure CalcOriginal;
389 400
    procedure CalcCopy;
390 401
    procedure CalcFeed;
402
    function CalcBilanElectrolytique(Na, K, Cl: Double): Double;
391 403
    function InputProximal(Value, MS: Double; ExpressionMode, ProximalUnit: Integer): Double;
392 404
    function InputEnergy(Value, MS: Double; ExpressionMode, EnergyUnit: Integer): Double;
393 405
    function InputAA(Value, MAT, MS: Double; ExpressionMode, AAUnit: Integer): Double;
......
412 424
uses
413 425
  SHFolder, StrUtils, UnitOptions;
414 426

  
427
procedure TDataModuleDeclaration.AggregateLevelSumUpdate(Agg: TAggregate);
428
begin
429
  if not ClientDataSetFeeds.Eof
430
  then
431
  begin
432
    ClientDataSetFeeds.Edit;
433
    if VarIsEmpty(Agg.Value) or VarIsNull(Agg.Value)
434
    then
435
      ClientDataSetFeedsLevelSum.Clear
436
    else
437
      ClientDataSetFeedsLevelSum.AsFloat := Agg.Value;
438
    ClientDataSetFeeds.Post;
439
  end;
440
end;
441

  
442
procedure TDataModuleDeclaration.ClientDataSetFeedsCalcFields(DataSet: TDataSet);
443
begin
444
  if ClientDataSetFeedsPhytaseIncorporation.IsNull or ClientDataSetFeedsPhytaseConcentration.IsNull
445
  or (ClientDataSetFeedsPhytaseConcentration.Value = 0)
446
  then
447
    ClientDataSetFeedsPhytaseLevel.Clear
448
  else
449
    ClientDataSetFeedsPhytaseLevel.Value := OutputIncorporation(ClientDataSetFeedsPhytaseIncorporation.Value / ClientDataSetFeedsPhytaseConcentration.Value / 1000, FormOptions.Incorporation);
450
  ClientDataSetFeedsTotal.Value := ClientDataSetFeedsLevelSum.Value + ClientDataSetFeedsPhytaseLevel.Value;
451
  ClientDataSetFeedsRemain.Value := OutputIncorporation(1, FormOptions.Incorporation) - ClientDataSetFeedsTotal.Value;
452
end;
453

  
454
procedure TDataModuleDeclaration.ClientDataSetIngredientsFilterRecord(DataSet: TDataSet; var Accept: Boolean);
455
begin
456
  Accept := True;
457
  if FilterOnClass and (FilteredClass > 0)
458
  then
459
    Accept := Accept and (DataSet.FieldByName('Class').AsInteger = FilteredClass);
460
  if FilterOnDatabase
461
  then
462
    case FilteredDatabase of
463
      1: // User database
464
        Accept := Accept and DataSet.FieldByName('User').AsBoolean;
465
      2: // Reference tables
466
        Accept := Accept and not DataSet.FieldByName('User').AsBoolean;
467
    end;
468
  if FilterOnName and (FilteredName <> '')
469
  then
470
    Accept := Accept and (Pos(FilteredName, DataSet.FieldByName('Name').AsWideString) > 0);
471
end;
472

  
473
procedure TDataModuleDeclaration.DataModuleCreate(Sender: TObject);
474
var
475
  i: Integer;
476
  ExeDir, DataDir, DataFile: String;
477
  Cryptage: TLbBlowfish;
478
  FluxClair, FluxCrypte: TMemoryStream;
479
  DocumentsPath: array[0..MAX_PATH] of Char;
480
begin
481
  // Classes
482
  ClassList := TStringList.Create;
483
  ClassList.Add('Cereals');
484
  ClassList.Add('Wheat by-products');
485
  ClassList.Add('Maize by-products');
486
  ClassList.Add('Other cereal by-products');
487
  ClassList.Add('Rice by-products');
488
  ClassList.Add('Legume and oil seeds');
489
  ClassList.Add('Oil seed meals');
490
  ClassList.Add('Starch, roots and tubers');
491
  ClassList.Add('Fruits and vegetables by-products');
492
  ClassList.Add('Molasses and vinasses');
493
  ClassList.Add('Other plant products');
494
  ClassList.Add('Dehydrated forages');
495
  ClassList.Add('Dairy products');
496
  ClassList.Add('Fish meals and solubles');
497
  ClassList.Add('Other animal by-products');
498
  ClassList.Add('Fats and oils');
499
  ClassList.Add('Amino acids');
500
  ClassList.Add('Mineral sources');
501
  ClassList.Add('Not referenced');
502
  ClientDataSetClasses.CreateDataSet;
503
  for i := 0 to ClassList.Count - 1 do
504
    ClientDataSetClasses.AppendRecord([i + 1, dgettext('InraAfz', ClassList[i])]);
505
  // Phytase
506
  ClientDataSetPhytase.CreateDataSet;
507
  ClientDataSetPhytase.AppendRecord([1, 0.60, 0.67]);
508
  ClientDataSetPhytase.AppendRecord([2, 0.65, 0.76]);
509
  ClientDataSetPhytase.AppendRecord([3, 0.70, 0.87]);
510
  ClientDataSetPhytase.AppendRecord([4, 0.75, 1.00]);
511
  ClientDataSetPhytase.AppendRecord([5, 0.80, 1.15]);
512
  ClientDataSetPhytase.AppendRecord([6, 0.85, 1.34]);
513
  ClientDataSetPhytase.AppendRecord([7, 0.90, 1.60]);
514
  ClientDataSetPhytase.AppendRecord([8, 0.95, 1.98]);
515
  // Tables de r?f?rence
516
  ExeDir := ExtractFilePath(Application.ExeName);
517
  DataFile := ExeDir + 'EvaPig2020.dat';
518
  if not FileExists(DataFile)
519
  then // Erreur
520
  begin
521
    MessageDlg(_('Reference tables of composition and nutritional values of feed materials for pigs') + sLineBreak
522
      + Format(_('%s: file not found'), [DataFile]), mtError, [mbOK], 0);
523
    Application.Terminate;
524
    Exit;
525
  end;
526
  ClientDataSetInraAfz.CreateDataSet;
527
  Cryptage := TlbBlowfish.Create(nil);
528
  Cryptage.GenerateKey('Tables of Composition and Nutritional Value of Feed Materials');
529
  FluxCrypte := TMemoryStream.Create;
530
  FluxClair := TMemoryStream.Create;
531
  try
532
    FluxCrypte.LoadFromFile(DataFile);
533
    FluxCrypte.Position := 0;
534
    Cryptage.DecryptStream(FluxCrypte, FluxClair);
535
    FluxClair.Position := 0;
536
    try
537
      ClientDataSetInraAfz.LoadFromStream(FluxClair);
538
    except
539
      MessageDlg(_('Reference tables of composition and nutritional values of feed materials for pigs') + sLineBreak
540
        + _('Invalid data format'), mtError, [mbOK], 0);
541
      Application.Terminate;
542
      Exit;
543
    end;
544
  finally
545
    FluxCrypte.Free;
546
    FluxClair.Free;
547
    Cryptage.Free;
548
  end;
549
  // Base User.sqb
550
  SHGetFolderPath(0, CSIDL_PERSONAL, 0, SHGFP_TYPE_CURRENT, DocumentsPath);
551
  DataDir := IncludeTrailingPathDelimiter(IncludeTrailingPathDelimiter(DocumentsPath) + Application.Title);
552
  ForceDirectories(DataDir);
553
  if not FileExists(ExeDir + 'sqlite3.dll')
554
  then // Erreur
555
  begin
556
    MessageDlg(_('SQLite') + sLineBreak
557
      + Format(_('%s: driver missing'), [ExeDir + 'sqlite3.dll']), mtError, [mbOK], 0);
558
    Application.Terminate;
559
    Exit;
560
  end;
561
  DBUser := TSQLiteDatabase.Create(DataDir + 'User.sqb');
562
  if not DBUser.TableExists('Ingredients')
563
  then // Cr?ation de la table Ingredients
564
  begin
565
    DBUser.ExecSQL('CREATE TABLE Ingredients ('
566
      + 'Id INTEGER PRIMARY KEY, '
567
      + 'Name TEXT, '
568
      + 'Definition TEXT, '
569
      + 'Class INTEGER, '
570
      + 'Model INTEGER, '
571
      + 'MS REAL, '
572
      + 'MM REAL, '
573
      + 'MAT REAL, '
574
      + 'MG REAL, '
575
      + 'CB REAL, '
576
      + 'NDF REAL, '
577
      + 'ADF REAL, '
578
      + 'ADL REAL, '
579
      + 'Amidon REAL, '
580
      + 'Sucres REAL, '
581
      + 'EB REAL, '
582
      + 'Bonus REAL, '
583
      + 'Lys REAL, '
584
      + 'Thr REAL, '
585
      + 'Met REAL, '
586
      + 'Cys REAL, '
587
      + 'MetCys REAL, '
588
      + 'Trp REAL, '
589
      + 'Ile REAL, '
590
      + 'Val REAL, '
591
      + 'Leu REAL, '
592
      + 'Phe REAL, '
593
      + 'Tyr REAL, '
594
      + 'PheTyr REAL, '
595
      + 'His REAL, '
596
      + 'Arg REAL, '
597
      + 'Ala REAL, '
598
      + 'Asp REAL, '
599
      + 'Glu REAL, '
600
      + 'Gly REAL, '
601
      + 'Ser REAL, '
602
      + 'Pro REAL, '
603
      + 'dLys REAL, '
604
      + 'dThr REAL, '
605
      + 'dMet REAL, '
606
      + 'dCys REAL, '
607
      + 'dMetCys REAL, '
608
      + 'dTrp REAL, '
609
      + 'dIle REAL, '
610
      + 'dVal REAL, '
611
      + 'dLeu REAL, '
612
      + 'dPhe REAL, '
613
      + 'dTyr REAL, '
614
      + 'dPheTyr REAL, '
615
      + 'dHis REAL, '
616
      + 'dArg REAL, '
617
      + 'dAla REAL, '
618
      + 'dAsp REAL, '
619
      + 'dGlu REAL, '
620
      + 'dGly REAL, '
621
      + 'dSer REAL, '
622
      + 'dPro REAL, '
623
      + 'Ca REAL, '
624
      + 'P REAL, '
625
      + 'dP REAL, '
626
      + 'dPphy REAL)');
627
    DBUser.ExecSQL('CREATE INDEX IdxClasses ON Ingredients (Class)');
628
    DBUser.ExecSQL('CREATE INDEX IdxModels ON Ingredients (Model)');
629
  end;
630
  if not DBUser.TableExists('Feeds')
631
  then // Cr?ation de la table Feeds
632
    DBUser.ExecSQL('CREATE TABLE Feeds ('
633
      + 'Id INTEGER PRIMARY KEY, '
634
      + 'Name TEXT, '
635
      + 'Description TEXT, '
636
      + 'Presentation INTEGER, '
637
      + 'BonusC REAL, '
638
      + 'BonusT REAL, '
639
      + 'Phytase INTEGER, '
640
      + 'Concentration REAL, '
641
      + 'Incorporation REAL)');
642
  if not DBUser.TableExists('Composition')
643
  then // Cr?ation de la table Composition
644
  begin
645
    DBUser.ExecSQL('CREATE TABLE Composition ('
646
      + 'Feed INTEGER, '
647
      + 'Ingredient INTEGER, '
648
      + 'User BOOLEAN, '
649
      + 'Rank INTEGER, '
650
      + 'MS REAL, '
651
      + 'Level REAL)');
652
    DBUser.ExecSQL('CREATE INDEX IdxFeeds ON Composition (Feed)');
653
    DBUser.ExecSQL('CREATE INDEX IdxIngredients ON Composition (Ingredient)');
654
  end;
655
  Application.ProcessMessages;
656
  // Liste des mati?res premi?res utilisateur
657
  UserList := TStringList.Create;
658
  TableIngredients := DBUser.GetTable('SELECT Name FROM Ingredients');
659
  with TableIngredients do
660
    try
661
      while not Eof do
662
      begin
663
        UserList.Add(FieldAsString(FieldIndex['Name']));
664
        Next;
665
      end;
666
    finally
667
      Free;
668
    end;
669
  // Liste des r?gimes
670
  FeedList := TStringList.Create;
671
  TableFeeds := DBUser.GetTable('SELECT Name FROM Feeds');
672
  with TableFeeds do
673
    try
674
      while not Eof do
675
      begin
676
        FeedList.Add(FieldAsString(FieldIndex['Name']));
677
        Next;
678
      end;
679
    finally
680
      Free;
681
    end;
682
end;
683

  
684
procedure TDataModuleDeclaration.DataModuleDestroy(Sender: TObject);
685
begin
686
  ClientDataSetClasses.Close;
687
  ClientDataSetPhytase.Close;
688
  ClientDataSetInraAfz.Close;
689
  ClassList.Free;
690
  UserList.Free;
691
  FeedList.Free;
692
  Application.ProcessMessages;
693
  DBUser.ExecSQL('VACUUM'); // Compacter la base User.sqb
694
  DBUser.Free;
695
  Application.ProcessMessages;
696
end;
697

  
415 698
procedure TDataModuleDeclaration.CalcInraAfz;
416 699
// Renseigner l'enregistrement courant de ClientDataSetIngredients
417 700
// ? partir de l'enregistrement courant de ClientDataSetInraAfz
......
1013 1296
    ClientDataSetIngredientsP.Clear
1014 1297
  else
1015 1298
    ClientDataSetIngredientsP.Value := OutputMinerals(ClientDataSetInraAfzP.Value, RapMS, FormOptions.Expression, FormOptions.Minerals);
1299
  if ClientDataSetInraAfzNa.IsNull
1300
  then
1301
    ClientDataSetIngredientsNa.Clear
1302
  else
1303
    ClientDataSetIngredientsNa.Value := OutputMinerals(ClientDataSetInraAfzNa.Value, RapMS, FormOptions.Expression, FormOptions.Minerals);
1304
  if ClientDataSetInraAfzK.IsNull
1305
  then
1306
    ClientDataSetIngredientsK.Clear
1307
  else
1308
    ClientDataSetIngredientsK.Value := OutputMinerals(ClientDataSetInraAfzK.Value, RapMS, FormOptions.Expression, FormOptions.Minerals);
1309
  if ClientDataSetInraAfzCl.IsNull
1310
  then
1311
    ClientDataSetIngredientsCl.Clear
1312
  else
1313
    ClientDataSetIngredientsCl.Value := OutputMinerals(ClientDataSetInraAfzCl.Value, RapMS, FormOptions.Expression, FormOptions.Minerals);
1314
  if ClientDataSetIngredientsNa.IsNull or ClientDataSetIngredientsK.IsNull or ClientDataSetIngredientsCl.IsNull
1315
  then
1316
    ClientDataSetIngredientsBE.Clear
1317
  else
1318
    ClientDataSetIngredientsBE.Value := CalcBilanElectrolytique(InputMinerals(ClientDataSetIngredientsNa.Value, RapMS, FormOptions.Expression, FormOptions.Minerals), InputMinerals(ClientDataSetIngredientsK.Value, RapMS, FormOptions.Expression, FormOptions.Minerals), InputMinerals(ClientDataSetIngredientsCl.Value, RapMS, FormOptions.Expression, FormOptions.Minerals));
1016 1319
  if ClientDataSetIngredientsP.Value = 0
1017 1320
  then // En l'absence de P, il n'y a pas de dP
1018 1321
  begin
......
1997 2300
    ClientDataSetIngredientsP.Clear
1998 2301
  else
1999 2302
    ClientDataSetIngredientsP.Value := OutputMinerals(TableIngredients.FieldAsDouble(TableIngredients.FieldIndex['P']), RapMS, FormOptions.Expression, FormOptions.Minerals);
2303
  if TableIngredients.FieldIsNull(TableIngredients.FieldIndex['Na'])
2304
  then
2305
    ClientDataSetIngredientsNa.Clear
2306
  else
2307
    ClientDataSetIngredientsNa.Value := OutputMinerals(TableIngredients.FieldAsDouble(TableIngredients.FieldIndex['Na']), RapMS, FormOptions.Expression, FormOptions.Minerals);
2308
  if TableIngredients.FieldIsNull(TableIngredients.FieldIndex['K'])
2309
  then
2310
    ClientDataSetIngredientsK.Clear
2311
  else
2312
    ClientDataSetIngredientsK.Value := OutputMinerals(TableIngredients.FieldAsDouble(TableIngredients.FieldIndex['K']), RapMS, FormOptions.Expression, FormOptions.Minerals);
2313
  if TableIngredients.FieldIsNull(TableIngredients.FieldIndex['Cl'])
2314
  then
2315
    ClientDataSetIngredientsCl.Clear
2316
  else
2317
    ClientDataSetIngredientsCl.Value := OutputMinerals(TableIngredients.FieldAsDouble(TableIngredients.FieldIndex['Cl']), RapMS, FormOptions.Expression, FormOptions.Minerals);
2318
  if ClientDataSetIngredientsNa.IsNull or ClientDataSetIngredientsK.IsNull or ClientDataSetIngredientsCl.IsNull
2319
  then
2320
    ClientDataSetIngredientsBE.Clear
2321
  else
2322
    ClientDataSetIngredientsBE.Value := CalcBilanElectrolytique(InputMinerals(ClientDataSetIngredientsNa.Value, RapMS, FormOptions.Expression, FormOptions.Minerals), InputMinerals(ClientDataSetIngredientsK.Value, RapMS, FormOptions.Expression, FormOptions.Minerals), InputMinerals(ClientDataSetIngredientsCl.Value, RapMS, FormOptions.Expression, FormOptions.Minerals));
2000 2323
  if ClientDataSetIngredientsP.Value = 0
2001 2324
  then // En l'absence de P, il n'y a pas de dP
2002 2325
  begin
......
3013 3336
      ClientDataSetIngredientsP.Value := OutputMinerals(ClientDataSetInraAfzP.Value, RapMS, FormOptions.Expression, FormOptions.Minerals)
3014 3337
  else
3015 3338
    ClientDataSetIngredientsP.Value := OutputMinerals(TableIngredients.FieldAsDouble(TableIngredients.FieldIndex['P']), RapMS, FormOptions.Expression, FormOptions.Minerals);
3339
  if TableIngredients.FieldIsNull(TableIngredients.FieldIndex['Na'])
3340
  then
3341
    if ClientDataSetInraAfzNa.IsNull
3342
    then
3343
      ClientDataSetIngredientsNa.Clear
3344
    else
3345
      ClientDataSetIngredientsNa.Value := OutputMinerals(ClientDataSetInraAfzNa.Value, RapMS, FormOptions.Expression, FormOptions.Minerals)
3346
  else
3347
    ClientDataSetIngredientsNa.Value := OutputMinerals(TableIngredients.FieldAsDouble(TableIngredients.FieldIndex['Na']), RapMS, FormOptions.Expression, FormOptions.Minerals);
3348
  if TableIngredients.FieldIsNull(TableIngredients.FieldIndex['K'])
3349
  then
3350
    if ClientDataSetInraAfzK.IsNull
3351
    then
3352
      ClientDataSetIngredientsK.Clear
3353
    else
3354
      ClientDataSetIngredientsK.Value := OutputMinerals(ClientDataSetInraAfzK.Value, RapMS, FormOptions.Expression, FormOptions.Minerals)
3355
  else
3356
    ClientDataSetIngredientsK.Value := OutputMinerals(TableIngredients.FieldAsDouble(TableIngredients.FieldIndex['K']), RapMS, FormOptions.Expression, FormOptions.Minerals);
3357
  if TableIngredients.FieldIsNull(TableIngredients.FieldIndex['Cl'])
3358
  then
3359
    if ClientDataSetInraAfzCl.IsNull
3360
    then
3361
      ClientDataSetIngredientsCl.Clear
3362
    else
3363
      ClientDataSetIngredientsCl.Value := OutputMinerals(ClientDataSetInraAfzCl.Value, RapMS, FormOptions.Expression, FormOptions.Minerals)
3364
  else
3365
    ClientDataSetIngredientsCl.Value := OutputMinerals(TableIngredients.FieldAsDouble(TableIngredients.FieldIndex['Cl']), RapMS, FormOptions.Expression, FormOptions.Minerals);
3366
  if ClientDataSetIngredientsNa.IsNull or ClientDataSetIngredientsK.IsNull or ClientDataSetIngredientsCl.IsNull
3367
  then
3368
    ClientDataSetIngredientsBE.Clear
3369
  else
3370
    ClientDataSetIngredientsBE.Value := CalcBilanElectrolytique(InputMinerals(ClientDataSetIngredientsNa.Value, RapMS, FormOptions.Expression, FormOptions.Minerals), InputMinerals(ClientDataSetIngredientsK.Value, RapMS, FormOptions.Expression, FormOptions.Minerals), InputMinerals(ClientDataSetIngredientsCl.Value, RapMS, FormOptions.Expression, FormOptions.Minerals));
3016 3371
  if ClientDataSetIngredientsP.Value = 0
3017 3372
  then // En l'absence de P, il n'y a pas de dP
3018 3373
  begin
......
3157 3512
    // Min?raux
3158 3513
    ClientDataSetFeedsCa.Clear;
3159 3514
    ClientDataSetFeedsP.Clear;
3515
    ClientDataSetFeedsNa.Clear;
3516
    ClientDataSetFeedsK.Clear;
3517
    ClientDataSetFeedsCl.Clear;
3160 3518
    ClientDataSetFeedsPd.Clear;
3161 3519
  end
3162 3520
  else
......
3228 3586
    // Min?raux
3229 3587
    ClientDataSetFeedsCa.Value := 0;
3230 3588
    ClientDataSetFeedsP.Value := 0;
3589
    ClientDataSetFeedsNa.Value := 0;
3590
    ClientDataSetFeedsK.Value := 0;
3591
    ClientDataSetFeedsCl.Value := 0;
3231 3592
    ClientDataSetFeedsPd.Value := 0;
3232 3593
    PdEndo := 0;
3233 3594
    ClientDataSetComposition.First;
......
3641 4002
          ClientDataSetFeedsP.Clear
3642 4003
        else
3643 4004
          ClientDataSetFeedsP.Value := ClientDataSetFeedsP.Value + ClientDataSetIngredientsP.Value * Ratio;
4005
      if not ClientDataSetFeedsNa.IsNull
4006
      then
4007
        if ClientDataSetIngredientsNa.IsNull and (ClientDataSetIngredientsMM.Value <> 0)
4008
        then
4009
          ClientDataSetFeedsNa.Clear
4010
        else
4011
          ClientDataSetFeedsNa.Value := ClientDataSetFeedsNa.Value + ClientDataSetIngredientsNa.Value * Ratio;
4012
      if not ClientDataSetFeedsK.IsNull
4013
      then
4014
        if ClientDataSetIngredientsK.IsNull and (ClientDataSetIngredientsMM.Value <> 0)
4015
        then
4016
          ClientDataSetFeedsK.Clear
4017
        else
4018
          ClientDataSetFeedsK.Value := ClientDataSetFeedsK.Value + ClientDataSetIngredientsK.Value * Ratio;
4019
      if not ClientDataSetFeedsCl.IsNull
4020
      then
4021
        if ClientDataSetIngredientsCl.IsNull and (ClientDataSetIngredientsMM.Value <> 0)
4022
        then
4023
          ClientDataSetFeedsCl.Clear
4024
        else
4025
          ClientDataSetFeedsCl.Value := ClientDataSetFeedsCl.Value + ClientDataSetIngredientsCl.Value * Ratio;
3644 4026
      if not ClientDataSetFeedsPd.IsNull
3645 4027
      then
3646 4028
        if ClientDataSetFeedsPresentation.Value = 0
......
3873 4255
      if not ClientDataSetFeedsP.IsNull
3874 4256
      then
3875 4257
        ClientDataSetFeedsP.Value := ClientDataSetFeedsP.Value / RapMS;
4258
      if not ClientDataSetFeedsNa.IsNull
4259
      then
4260
        ClientDataSetFeedsNa.Value := ClientDataSetFeedsNa.Value / RapMS;
4261
      if not ClientDataSetFeedsK.IsNull
4262
      then
4263
        ClientDataSetFeedsK.Value := ClientDataSetFeedsK.Value / RapMS;
4264
      if not ClientDataSetFeedsCl.IsNull
4265
      then
4266
        ClientDataSetFeedsCl.Value := ClientDataSetFeedsCl.Value / RapMS;
3876 4267
      if not ClientDataSetFeedsPd.IsNull
3877 4268
      then
3878 4269
        ClientDataSetFeedsPd.Value := ClientDataSetFeedsPd.Value / RapMS;
3879 4270
    end;
3880 4271
  end;
4272
  if ClientDataSetFeedsNa.IsNull or ClientDataSetFeedsK.IsNull or ClientDataSetFeedsCl.IsNull
4273
  then
4274
    ClientDataSetFeedsBE.Clear
4275
  else
4276
    ClientDataSetFeedsBE.Value := CalcBilanElectrolytique(InputMinerals(ClientDataSetFeedsNa.Value, RapMS, FormOptions.Expression, FormOptions.Minerals), InputMinerals(ClientDataSetFeedsK.Value, RapMS, FormOptions.Expression, FormOptions.Minerals), InputMinerals(ClientDataSetFeedsCl.Value, RapMS, FormOptions.Expression, FormOptions.Minerals));
3881 4277
  // Rapports
3882 4278
  if ClientDataSetFeedsEDc.IsNull or ClientDataSetFeedsEB.IsNull or (ClientDataSetFeedsEB.Value = 0)
3883 4279
  then
......
4140 4536
    ClientDataSetFeedsProd_Lysd.Value := ClientDataSetFeedsProd.Value / ClientDataSetFeedsLysd.Value * 100;
4141 4537
end;
4142 4538

  
4143
procedure TDataModuleDeclaration.AggregateLevelSumUpdate(Agg: TAggregate);
4539
function TDataModuleDeclaration.CalcBilanElectrolytique(Na, K, Cl: Double): Double;
4144 4540
begin
4145
  if not ClientDataSetFeeds.Eof
4146
  then
4147
  begin
4148
    ClientDataSetFeeds.Edit;
4149
    if VarIsEmpty(Agg.Value) or VarIsNull(Agg.Value)
4150
    then
4151
      ClientDataSetFeedsLevelSum.Clear
4152
    else
4153
      ClientDataSetFeedsLevelSum.AsFloat := Agg.Value;
4154
    ClientDataSetFeeds.Post;
4155
  end;
4541
  Result := (Na / 23 + K / 39 - Cl / 35.5) * 1000000;
4542
  if FormOptions.Expression = 0
4543
  then // sur frais
4544
    Result := Result * RapMS;
4156 4545
end;
4157 4546

  
4158
procedure TDataModuleDeclaration.ClientDataSetFeedsCalcFields(DataSet: TDataSet);
4159
begin
4160
  if ClientDataSetFeedsPhytaseIncorporation.IsNull or ClientDataSetFeedsPhytaseConcentration.IsNull
4161
  or (ClientDataSetFeedsPhytaseConcentration.Value = 0)
4162
  then
4163
    ClientDataSetFeedsPhytaseLevel.Clear
4164
  else
4165
    ClientDataSetFeedsPhytaseLevel.Value := OutputIncorporation(ClientDataSetFeedsPhytaseIncorporation.Value / ClientDataSetFeedsPhytaseConcentration.Value / 1000, FormOptions.Incorporation);
4166
  ClientDataSetFeedsTotal.Value := ClientDataSetFeedsLevelSum.Value + ClientDataSetFeedsPhytaseLevel.Value;
4167
  ClientDataSetFeedsRemain.Value := OutputIncorporation(1, FormOptions.Incorporation) - ClientDataSetFeedsTotal.Value;
4168
end;
4169

  
4170
procedure TDataModuleDeclaration.ClientDataSetIngredientsFilterRecord(DataSet: TDataSet; var Accept: Boolean);
4171
begin
4172
  Accept := True;
4173
  if FilterOnClass and (FilteredClass > 0)
4174
  then
4175
    Accept := Accept and (DataSet.FieldByName('Class').AsInteger = FilteredClass);
4176
  if FilterOnDatabase
4177
  then
4178
    case FilteredDatabase of
4179
      1: // User database
4180
        Accept := Accept and DataSet.FieldByName('User').AsBoolean;
4181
      2: // Reference tables
4182
        Accept := Accept and not DataSet.FieldByName('User').AsBoolean;
4183
    end;
4184
  if FilterOnName and (FilteredName <> '')
4185
  then
4186
    Accept := Accept and (Pos(FilteredName, DataSet.FieldByName('Name').AsWideString) > 0);
4187
end;
4188

  
4189
procedure TDataModuleDeclaration.DataModuleCreate(Sender: TObject);
4190
var
4191
  i: Integer;
4192
  ExeDir, DataDir, DataFile: String;
4193
  Cryptage: TLbBlowfish;
4194
  FluxClair, FluxCrypte: TMemoryStream;
4195
  DocumentsPath: array[0..MAX_PATH] of Char;
4196
begin
4197
  // Classes
4198
  ClassList := TStringList.Create;
4199
  ClassList.Add('Cereals');
4200
  ClassList.Add('Wheat by-products');
4201
  ClassList.Add('Maize by-products');
4202
  ClassList.Add('Other cereal by-products');
4203
  ClassList.Add('Rice by-products');
4204
  ClassList.Add('Legume and oil seeds');
4205
  ClassList.Add('Oil seed meals');
4206
  ClassList.Add('Starch, roots and tubers');
4207
  ClassList.Add('Fruits and vegetables by-products');
4208
  ClassList.Add('Molasses and vinasses');
4209
  ClassList.Add('Other plant products');
4210
  ClassList.Add('Dehydrated forages');
4211
  ClassList.Add('Dairy products');
4212
  ClassList.Add('Fish meals and solubles');
4213
  ClassList.Add('Other animal by-products');
4214
  ClassList.Add('Fats and oils');
4215
  ClassList.Add('Amino acids');
4216
  ClassList.Add('Mineral sources');
4217
  ClassList.Add('Not referenced');
4218
  ClientDataSetClasses.CreateDataSet;
4219
  for i := 0 to ClassList.Count - 1 do
4220
    ClientDataSetClasses.AppendRecord([i + 1, dgettext('InraAfz', ClassList[i])]);
4221
  // Phytase
4222
  ClientDataSetPhytase.CreateDataSet;
4223
  ClientDataSetPhytase.AppendRecord([1, 0.60, 0.67]);
4224
  ClientDataSetPhytase.AppendRecord([2, 0.65, 0.76]);
4225
  ClientDataSetPhytase.AppendRecord([3, 0.70, 0.87]);
4226
  ClientDataSetPhytase.AppendRecord([4, 0.75, 1.00]);
4227
  ClientDataSetPhytase.AppendRecord([5, 0.80, 1.15]);
4228
  ClientDataSetPhytase.AppendRecord([6, 0.85, 1.34]);
4229
  ClientDataSetPhytase.AppendRecord([7, 0.90, 1.60]);
4230
  ClientDataSetPhytase.AppendRecord([8, 0.95, 1.98]);
4231
  // Tables de r?f?rence
4232
  ExeDir := ExtractFilePath(Application.ExeName);
4233
  DataFile := ExeDir + 'EvaPig2020.dat';
4234
  if not FileExists(DataFile)
4235
  then // Erreur
4236
  begin
4237
    MessageDlg(_('Reference tables of composition and nutritional values of feed materials for pigs') + sLineBreak
4238
      + Format(_('%s: file not found'), [DataFile]), mtError, [mbOK], 0);
4239
    Application.Terminate;
4240
    Exit;
4241
  end;
4242
  ClientDataSetInraAfz.CreateDataSet;
4243
  Cryptage := TlbBlowfish.Create(nil);
4244
  Cryptage.GenerateKey('Tables of Composition and Nutritional Value of Feed Materials');
4245
  FluxCrypte := TMemoryStream.Create;
4246
  FluxClair := TMemoryStream.Create;
4247
  try
4248
    FluxCrypte.LoadFromFile(DataFile);
4249
    FluxCrypte.Position := 0;
4250
    Cryptage.DecryptStream(FluxCrypte, FluxClair);
4251
    FluxClair.Position := 0;
4252
    try
4253
      ClientDataSetInraAfz.LoadFromStream(FluxClair);
4254
    except
4255
      MessageDlg(_('Reference tables of composition and nutritional values of feed materials for pigs') + sLineBreak
4256
        + _('Invalid data format'), mtError, [mbOK], 0);
4257
      Application.Terminate;
4258
      Exit;
4259
    end;
4260
  finally
4261
    FluxCrypte.Free;
4262
    FluxClair.Free;
4263
    Cryptage.Free;
4264
  end;
4265
  // Base User.sqb
4266
  SHGetFolderPath(0, CSIDL_PERSONAL, 0, SHGFP_TYPE_CURRENT, DocumentsPath);
4267
  DataDir := IncludeTrailingPathDelimiter(IncludeTrailingPathDelimiter(DocumentsPath) + Application.Title);
4268
  ForceDirectories(DataDir);
4269
  if not FileExists(ExeDir + 'sqlite3.dll')
4270
  then // Erreur
4271
  begin
4272
    MessageDlg(_('SQLite') + sLineBreak
4273
      + Format(_('%s: driver missing'), [ExeDir + 'sqlite3.dll']), mtError, [mbOK], 0);
4274
    Application.Terminate;
4275
    Exit;
4276
  end;
4277
  DBUser := TSQLiteDatabase.Create(DataDir + 'User.sqb');
4278
  if not DBUser.TableExists('Ingredients')
4279
  then // Cr?ation de la table Ingredients
4280
  begin
4281
    DBUser.ExecSQL('CREATE TABLE Ingredients ('
4282
      + 'Id INTEGER PRIMARY KEY, '
4283
      + 'Name TEXT, '
4284
      + 'Definition TEXT, '
4285
      + 'Class INTEGER, '
4286
      + 'Model INTEGER, '
4287
      + 'MS REAL, '
4288
      + 'MM REAL, '
4289
      + 'MAT REAL, '
4290
      + 'MG REAL, '
4291
      + 'CB REAL, '
4292
      + 'NDF REAL, '
4293
      + 'ADF REAL, '
4294
      + 'ADL REAL, '
4295
      + 'Amidon REAL, '
4296
      + 'Sucres REAL, '
4297
      + 'EB REAL, '
4298
      + 'Bonus REAL, '
4299
      + 'Lys REAL, '
4300
      + 'Thr REAL, '
4301
      + 'Met REAL, '
4302
      + 'Cys REAL, '
4303
      + 'MetCys REAL, '
4304
      + 'Trp REAL, '
4305
      + 'Ile REAL, '
4306
      + 'Val REAL, '
4307
      + 'Leu REAL, '
4308
      + 'Phe REAL, '
4309
      + 'Tyr REAL, '
4310
      + 'PheTyr REAL, '
4311
      + 'His REAL, '
4312
      + 'Arg REAL, '
4313
      + 'Ala REAL, '
4314
      + 'Asp REAL, '
4315
      + 'Glu REAL, '
4316
      + 'Gly REAL, '
4317
      + 'Ser REAL, '
4318
      + 'Pro REAL, '
4319
      + 'dLys REAL, '
4320
      + 'dThr REAL, '
4321
      + 'dMet REAL, '
4322
      + 'dCys REAL, '
4323
      + 'dMetCys REAL, '
4324
      + 'dTrp REAL, '
4325
      + 'dIle REAL, '
4326
      + 'dVal REAL, '
4327
      + 'dLeu REAL, '
4328
      + 'dPhe REAL, '
4329
      + 'dTyr REAL, '
4330
      + 'dPheTyr REAL, '
4331
      + 'dHis REAL, '
4332
      + 'dArg REAL, '
4333
      + 'dAla REAL, '
4334
      + 'dAsp REAL, '
4335
      + 'dGlu REAL, '
4336
      + 'dGly REAL, '
4337
      + 'dSer REAL, '
4338
      + 'dPro REAL, '
4339
      + 'Ca REAL, '
4340
      + 'P REAL, '
4341
      + 'dP REAL, '
4342
      + 'dPphy REAL)');
4343
    DBUser.ExecSQL('CREATE INDEX IdxClasses ON Ingredients (Class)');
4344
    DBUser.ExecSQL('CREATE INDEX IdxModels ON Ingredients (Model)');
4345
  end;
4346
  if not DBUser.TableExists('Feeds')
4347
  then // Cr?ation de la table Feeds
4348
    DBUser.ExecSQL('CREATE TABLE Feeds ('
4349
      + 'Id INTEGER PRIMARY KEY, '
4350
      + 'Name TEXT, '
4351
      + 'Description TEXT, '
4352
      + 'Presentation INTEGER, '
4353
      + 'BonusC REAL, '
4354
      + 'BonusT REAL, '
4355
      + 'Phytase INTEGER, '
4356
      + 'Concentration REAL, '
4357
      + 'Incorporation REAL)');
4358
  if not DBUser.TableExists('Composition')
4359
  then // Cr?ation de la table Composition
4360
  begin
4361
    DBUser.ExecSQL('CREATE TABLE Composition ('
4362
      + 'Feed INTEGER, '
4363
      + 'Ingredient INTEGER, '
4364
      + 'User BOOLEAN, '
4365
      + 'Rank INTEGER, '
4366
      + 'MS REAL, '
4367
      + 'Level REAL)');
4368
    DBUser.ExecSQL('CREATE INDEX IdxFeeds ON Composition (Feed)');
4369
    DBUser.ExecSQL('CREATE INDEX IdxIngredients ON Composition (Ingredient)');
4370
  end;
4371
  Application.ProcessMessages;
4372
  // Liste des mati?res premi?res utilisateur
4373
  UserList := TStringList.Create;
4374
  TableIngredients := DBUser.GetTable('SELECT Name FROM Ingredients');
4375
  with TableIngredients do
4376
    try
4377
      while not Eof do
4378
      begin
4379
        UserList.Add(FieldAsString(FieldIndex['Name']));
4380
        Next;
4381
      end;
4382
    finally
4383
      Free;
4384
    end;
4385
  // Liste des r?gimes
4386
  FeedList := TStringList.Create;
4387
  TableFeeds := DBUser.GetTable('SELECT Name FROM Feeds');
4388
  with TableFeeds do
4389
    try
4390
      while not Eof do
4391
      begin
4392
        FeedList.Add(FieldAsString(FieldIndex['Name']));
4393
        Next;
4394
      end;
4395
    finally
4396
      Free;
4397
    end;
4398
end;
4399

  
4400
procedure TDataModuleDeclaration.DataModuleDestroy(Sender: TObject);
4401
begin
4402
  ClientDataSetClasses.Close;
4403
  ClientDataSetPhytase.Close;
4404
  ClientDataSetInraAfz.Close;
4405
  ClassList.Free;
4406
  UserList.Free;
4407
  FeedList.Free;
4408
  Application.ProcessMessages;
4409
  DBUser.ExecSQL('VACUUM'); // Compacter la base User.sqb
4410
  DBUser.Free;
4411
  Application.ProcessMessages;
4412
end;
4413

  
4414 4547
function TDataModuleDeclaration.InputProximal(Value, MS: Double; ExpressionMode, ProximalUnit: Integer): Double;
4415 4548
begin
4416 4549
  if ProximalUnit = 0

Formats disponibles : Unified diff