Jump to content

Tommi Prami

Members
  • Content Count

    511
  • Joined

  • Last visited

  • Days Won

    6

Posts posted by Tommi Prami


  1. 44 minutes ago, Lars Fosdal said:

     

    
    procedure ConnectFields(Query: TDataSet; const Fields: TArray<TField>; const Names: TArray<string>);
    begin
      Assert(Length(Fields) = Length(Names), 'Number of fields and number of names must match');
      for var ix := 0 to Length(Fields) - 1
      do begin
        Fields[ix] := Query.FieldByName(Names[ix]);
        if not Assigned(Fields[ix])
        then raise Exception.Create(Format('Field %s not found.', [Names[ix]]); 
      end;
    end
      
    // usage
    var
      Field1, Field2, Field3, Field4: TField;
    begin
      ConnectFields(Query,
       [ Field1,   Field2,   Field3,   Field4], 
       ['Field1', 'Field2', 'Field3', 'Field4']);
    ...

     which doesn't save you that much code, really.

    Does not work, know because I've tried that approach in the past, and retried your code and it does nothing. (outside of procedure, which is the important part),

     

    // usage
    var
      Field1, Field2, Field3, Field4: TField;
    begin
      Field1 := nil; // ...   Field2,   Field3,   Field4
      ConnectFields(Query,
       [ Field1,   Field2,   Field3,   Field4], 
       ['Field1', 'Field2', 'Field3', 'Field4']);
     // Fields star as they are in here, nil or not nil, doesnt matter... But eassy to check by nilling the fields becore and after call.

     

    Other problem in this tat compiler starts to complain about Fields are uninitialized. But that is separate issue...


  2. 15 minutes ago, uligerhardt said:

    Seems like an array should be the way:

    
    type
      TMyFields = array[1..4] of TField;
    
    procedure TForm1.FormCreate(Sender: TObject);
    var
      LFields: TMyFields;
      i: Integer;
    begin
      for i := Low(TMyFields) to High(TMyFields) do
        LFields[i] := Query.FieldByName('FIELD' + IntToStr(i));
    end;

     

    Nice could be done something like that,. but field names are not indexed, usually and after that it is just the same as the my original example I am trying to solve...

     

    But Not looking for workaround...
     

    -Tee-


  3. 13 minutes ago, Sinspin said:

    You have also access to the list of fields. 

    
    Query.Fields[0..N]

    No need to address the fields always by their names.

    Yes...

    But totally different thing...

    And would have exact same problem. Would need to initialize variables for indexes by name. Constant magic number indexes leads to buggy code.

    I am looking for solution for getting fields, and also solution for other cases I could adapt it to.

    Getting fields is just one use case of this type of procedure I would like to use...

     

    -Tee-


  4. 1 hour ago, Lars Fosdal said:

    So it is not about visual use?

    If not, I need to understand more about how the TFields will be used.

    var
      LTotal: Double;
      LField1: TField;
      LField2: TField;
      LField3: TField;  
      LField4: TField;  
    begin
      LField1 := Query.FieldByName('FIELD1');
      LField2 := Query.FieldByName('FIELD1');
      LField3 := Query.FieldByName('FIELD1');
      LField4 := Query.FieldByName('FIELD1'); 
    
      Query.First;
      while not Query.Eof do
      begin
        LTotal := LTotal + LField1.AsFloat;
        // More stuff done with local field variables...
        Query.Next;
      end;

    In this case, TDataSet and TField are RTL stuff or their descendants...

    So implementation should be kind that works if I have no control over the API of the class..

     

    -Tee-


  5. 8 minutes ago, Lars Fosdal said:

    There are many ways to do this. Will you need to reference the TField components in any way, or are they just for display or editing? Will there be a need for different data format handing for different fields? Different titles, sizes, validation, etc?

    In this case I get the field usually when they are needed in the loop, or get rid of with-clause or something like that.


  6. Hello,

    I was pondering folowin situation, where there are easily quite many repeating code lines, and how to make int onew liner.

    var

    var
      LField1: TField;
      LField2: TField;
      LField3: TField;  
      LField4: TField;  
    begin
      LField1 := Query.FieldByName('FIELD1');
      LField2 := Query.FieldByName('FIELD1');
      LField3 := Query.FieldByName('FIELD1');
      LField4 := Query.FieldByName('FIELD1');  
      // ...
      // Should be nice to have it like this
      InitField(Query, [LField1, LField2, LField3, LField4], ['FIELD1', 'FIELD2', 'FIELD3', 'FIELD4', ]);

    It would be easy to make local procedure, case by case with var parameters etc, but that would not be very elegant.

    What I mean by dynamic, is that it would handle any number of fields and field names, oas long as there are same number of them passed to the procedure..

    Other case would be that could pass local variables and the routine would create those objects for me on single line.


  7. 8 hours ago, Vincent Parrett said:

    Embarcadero would need to move to a multi pass compiler to achieve this - something they have always resisted. I can understand this 10-15 yrs ago, but on modern hardware the compiler performance loss from multiple passes would not be that noticeable.

    Even something like 1.5 pass compiler that would enable some functionality or extend existing would be cool to have...

    -Tee-


  8. On 2/19/2024 at 2:30 PM, Lars Fosdal said:

    2. Make HighDPI actually works as intended - it is useless in a team as is - unless everyone runs the same scaling

    This would be good start.

    People in any teams have different level of eyesight. Different scaling needs etc. 

    This should have been implemented from the start the way that values in dfm would have been normalized to 96 as default dpi. Or something like that. Sure there could have been rounding errors, most likely. 


  9. On 1/1/2024 at 4:10 PM, TurboMagic said:

    Now I wanted to migrate it to a newer version (currently 3.0, but at the end 4.x is planned).

     

    Skip 4.x, and go directly to the FB5. From

     

    point of your app, FB4.x and FB5 are more than less the same, only minor ODS version change, form 13.0 to 13.1, so no new data types etc.

    If scared of new release, wait for couple of weeks/months to see is there something needed to fix (that you care about).

     

    If there is valid reason not to go to the FB5, I would for sure to skip FB3 at least, would jump directly to the FB 4.0.4.. Also I would try to avoid setting data type compatibility mode to some to the old version, I would just fix DB and code, should not take too long.

     

    On 1/1/2024 at 4:10 PM, TurboMagic said:

    This is a problem already discussed in German DP:
    https://www.delphipraxis.net/214354-backup-problem-nach-umstellung-auf-v3-0-embedded.html
    but the hints I got from there weren't working yet or not exactly how I wanted things to work.

     

    Embedded needs exclusive access to the DB, so you need to close all connections to the DB, at the App and external Db tools etc. Not sure that is this the problem tough, because I saw no error message, and did not go through the german forum thoroughly.

    -Tee-


  10. 17 minutes ago, Clément said:

    How low is you range. Can you use a simple array?

     

    A[1]:=1;

    A[2]:=1;

    A[3]:=1;

    ...

    A[7]:=-1; // Non existing range

    ...

    A[102]:=2;

    A[103]:=2;

    ....

    A[149]:=2;

    A[150]:=2;

     

    All elements must have a value. 

     

     

     

    Very small ranges that would be simple lookup. I think I have to realistically be mentally prepared upper bounds of few hundreds of  thousands, Maybe even millions.

    Most case it will be 100k or less..

    But anyhow, interesting take on this. Thanks...

     

    -Tee-


  11. 26 minutes ago, Kas Ob. said:

    so to recap what i get you have non-overlapped integer ranges in a list, and want to implement the best solution to check for an integer to get its range if exist, right ?

    I think exactly that.

    integer ranges like
    1-5: 1
    15-40: 1

    102-150: 2

    and if I search for:
     1 -> I'll get that range exists and get also associated value 1
     7 -> No range, and no value
     149 -> Range exists and associated value 2 returned

    code could be something like:
     

    if FRanges.Contains(1, LRangeValue) then
    begin
      case LRangeValue of
        1: HandleRangeType1; 
        2: HandleRangeType2;
      end;
    end;

     


  12. Hello,

     

    Was looking for what is out there and Interval tree etc has too much functionality than I need, but still might be way to go, not sure.

     

    I have ranges of integer, which do not overlap, and are inherently in right order while adding. In which I need to search if the given more than  less random integer falls in any of those ranges, and retrive what type of the range is (Currently there is only two distinct types, and of course the state when integer value is not found in any of the ranges.) List would have 0-couple hundred of ranges at max, usually low numbers.

     

    That's why I was thinking that balancing of the tree structures while adding might be unwanted overhead.

    Was thinking using list that could use list, adn starts are in ascending order, and binary search, but was thinking how to binary search something that most likely is not in the list. Now that I write it out, have to just compare two items and/or is it first/last at the list, quite complex compare but nothing too bad, I think). For the list I was thinking that is there list implementation that can be marked as sorted without doing actual sort operation and would have binary search that could have custom compare that I could find the start of the range, maybe end of the range in the dictionary with start as a key.

     

    As you can see, I am not sure how this would be smart to implement.

×