Hi All

I'm trying to write to a variable contained within an indexed record. Currently the record is not updating when I assign the new value.

If I create a 'buffer' record and assign the value to the 'buffer' record and then assign the 'buffer' record to the indexed record, I have no problems.

Have I done something wrong when trying to update a individual variable? Can the 'with' directive not be used in this way?

The code:

The record

TRegulatorSettings = record
    RegulatorId : integer;
    LowLimit : double;
    HighLimit : double;
    RegulatorOutputId : Integer;
  end;

The array size is set, but showing the code I feel adds little value

THardwarePressureModule = class(TDataModule)
    procedure DataModuleCreate(Sender: TObject);

  private
    FRegulatorSettingsArray: array of TRegulatorSettings;

    {*
      Procedure to get a regulator settings entry
      @params RegulatorId integer contains number of record to be returned
      @returns TRegulatorSettings contains the requested regulator settings
    }
    function GetRegulatorSettings(RegulatorId : integer) : TRegulatorSettings;

    {*
      Procedure to set a regulator settings entry
      @params RegulatorId integer contains ID number of record to be set
      @params Value TRegulatorSettings contains the regulator settings being set
    }
    procedure SetRegulatorSettings(RegulatorId : integer; Value : TRegulatorSettings);

  public
    property RegulatorSettings[RegulatorId : integer] : TRegulatorSettings
      read GetRegulatorSettings
      write SetRegulatorSettings;

end;

Implementation:

{*
  Procedure to get a regulator settings entry
}
function THardwarePressureModule.GetRegulatorSettings(RegulatorId : integer) : TRegulatorSettings;
var
  RegulatorSettings : TRegulatorSettings;
begin
  if((0 <= RegulatorId) and (RegulatorId < FRegulatorCount)) then
  begin
    RegulatorSettings := FRegulatorSettingsArray[RegulatorId];
  end
  else
  begin
    RegulatorSettings.RegulatorId := RegulatorId;
    RegulatorSettings.LowLimit := -1;
    RegulatorSettings.HighLimit := -1;
    RegulatorSettings.RegulatorOutputId := -1;
  end;

  Result := RegulatorSettings;
end;

{*
  Procedure to set a regulator settings entry
}
procedure THardwarePressureModule.SetRegulatorSettings(RegulatorId : integer; Value : TRegulatorSettings);
begin
  if((0 <= RegulatorId) and (RegulatorId < FRegulatorCount)) then
  begin
    FRegulatorSettingsArray[RegulatorId] := Value;
  end
end;

I'm writing to the record with this:

with HardwarePressureModule.RegulatorSettings[i] do
        begin
          RegulatorOutputId := RegulatorOutputNumber;//StrToInt(ExtractValue(RegulatorList[i]));
        end;

Any tips / thoughts would be greatly appreciated. Thanks in advance.

Cam

Edited 6 Years Ago by CanYouHandstand: Added implementation code.

I think I see your problem: RegulatroSetting is a property, so assigning a value to it will call the SetRegulatorSetting, but, in the Get function you add a equally named variable, RegulatorSetting, that can be -and is- confused with the property it self!

Avoid using the same name for 2 different things: Call this variable TmpRegulatorSetting, for instance!

Another tip: Avoid using "with" as much as possible (and you can avoid it always), may be it works ok now and saves a little typing, but if in a future you add a new property to the base class (form) with the same name as one property on the "with" object, this piece of code, without being modified at all, will change it behaviuor... and you will hardly notice it. Freaking!

function THardwarePressureModule.GetRegulatorSettings(RegulatorId : integer) : TRegulatorSettings;
var
  RegulatorSettings : TRegulatorSettings;
begin
if((0 <= RegulatorId) and (RegulatorId < FRegulatorCount)) then
begin
RegulatorSettings := {Witch one are you referring here? The property or the local variable?}

My advise in general (may be doesn't help here, but I'd try): Use a temporary var to store HardwarePressureModule.RegulatorSettings instead of "with", then manipulate this var:

ThisOne:= HardwarePressureModule.RegulatorSettings;
ThisOne.RegulatorOutputId := RegulatorOutputNumber;

Thanks for your thoughts, I think using a temporary variable is the only appropriate solution.

Cheers.

This article has been dead for over six months. Start a new discussion instead.