Конференция "Начинающим" » Получить названия полей из record [D7]
 
  • Artem78 © (26.10.16 03:47) [0]
    Здравствуйте, товарищи кодеры. Подскажите, как можно получить список всех полей переменной типа record (либо проверить существование поля по переданному названию)?

    Нужно что-то вроде этого:
     TMyRecord = record
       A, B: String;
       C: integer;
     end;

    // ....

    procedure TForm1.Button1Click(Sender: TObject);
    var
     obj: TMyRecord;
     props: array [0..2] of string;
    begin
     props := PropertyList(obj);
     //props = A, B, C
    end;

  • KSergey © (26.10.16 07:45) [1]
    В Delphi из готовых механизмов это доступно только для полей класса, тип которых (полей) есть published.
    Ключевые слова для чтения: RTTI
  • Rouse_ © (26.10.16 12:27) [2]
    program Project1;

    {$APPTYPE CONSOLE}

    {$R *.res}

    uses
     Rtti;

    type
    TMyRecord = record
      A, B: string;
      C: integer;
    end;

    var
     rType: TRttiRecordType;
     I: Integer;
    begin
       rType := TRttiRecordType(TRTTIContext.Create.GetType(TypeInfo(TMyrecord)));
       for I := 0 to Length(rType.GetDeclaredFields) - 1 do
         Writeln(rType.GetDeclaredFields[I].ToString);
     Readln;
    end.
  • Rouse_ © (26.10.16 12:28) [3]
    ЗЫ: это начиная с XE работает, на старых - врятли (тестировал на XE4)
  • Игорь Шевченко © (26.10.16 13:01) [4]
  • iop © (26.10.16 20:39) [5]
    все как обычно под луной......

    приходит чел с неправильным дизайном и вытекающим из него вопросом.
    и ему таки подсказывают как удалить гланды не через горло.

    вот скажи,
    если уж тебе нужны имена значений и нужно проверять лежит ли про указателю та структура, которую ты ожидаешь,

    то нафига же ты выбираешь рекорд для своей задачи?
  • Rouse_ © (26.10.16 22:46) [6]
    Очень интересный ответ, а вот скажи мне, для чего вообще в rtti ввели данную возможность? :)
  • Artem78 © (26.10.16 22:57) [7]

    > ЗЫ: это начиная с XE работает, на старых - врятли (тестировал
    > на XE4)


    Мне для классической семёрки надо.


    > вот скажи,
    > если уж тебе нужны имена значений и нужно проверять лежит
    > ли про указателю та структура, которую ты ожидаешь,
    >
    > то нафига же ты выбираешь рекорд для своей задачи?


    Посчитал что с ним будет проще.

    Сейчас вкратце расскажу суть задачи. Есть сущности "Тип задания". Их несколько штук. У каждой есть некоторые поля - причём часть из них встречается во всех или больше чем в одном типе. Эти свойства нужно менять через графический интерфейс. Мне пришла самая простая идея сделать так. Создать массив с record-ами. Потом в форме есть combobox - "Название типа задания". Также на форме есть поля для редактировния свойств из всех типов. При переключении комбобокса, в контролы подгружаются значения полей выбранного типа, а если "тип" данное свойство не использует, тогда Enabled:=False. При этом вручную добавил многочисленные IF-ы, проверяющие используется ли это поле для текущего "типа" или нет. Очень похожая мешанина кода при сохранении (обратно в массив да ещё в ini файл) и ещё в одном месте. Отсюда возникло желание как-то упростить это дело. Идея такая, чтобы при отображении/сохранение проходить по всем свойствам выбранного объекта - если свойство есть - отображать/сохранять, если нет - поле делать неактивным.

    Очень сумбурно объяснил, но думаю можно понять ) У кого-нибудь есть варианты как это ещё можно организовать?
  • Игорь Шевченко © (26.10.16 23:29) [8]

    > У кого-нибудь есть варианты как это ещё можно организовать?


    Программиста пригласить, например
  • Jeer © (27.10.16 01:13) [9]
    Лучше - пристрелить таких и с такими вопросами.
  • Германн © (27.10.16 01:40) [10]

    > iop ©   (26.10.16 20:39) [5]
    >
    > все как обычно под луной......
    >
    > приходит чел с неправильным дизайном

    А при чём тут "дизайн"?
  • iop © (27.10.16 08:13) [11]
    А при чём тут "дизайн"?

    о нифига себе вопросики на форуме программеров.
    чувак построил дом трехэтажный, со входом с чердака.
    и теперь немного неудобно и есть вопросы

    ему предложили подумать, а правильный ли дизайн выбран.
    но тут приходит строитель и говорит,
    да при чем здесь какой-то дизайн,
    когда надо просто траволатор-эскалатор на чердак с земли прокинуть
  • Dimka Maslov © (27.10.16 08:20) [12]

    > но тут приходит строитель и говорит,


    Но ведь мы, строители, так и работаем :)
  • Gwire (22.02.17 11:50) [13]
    Artem78, структуры не самый удачный выбор для такой унификации.

    Я бы реализовал 3 класса TAttribute, TTask и TTaskList.

    TAttribute = class
    public
     Name: String;
     Value: String;
    end;

    TTask = class(TList)
    private
     funcrion GetAttributes(i: Integer): TAttribute;
    public
     Name: String;
     property Attributes[i: Integer]: TAttribute read GetAttributes; default;
    end;

    TTaskList = class(TList)
    private
     funcrion GetTasks(i: Integer): TTask;
    public
     property Tasks[i: Integer]: TTask read GetTasks; default;
    end;


    Собственно и все список задач в твой ComboBox загружаешь из TaskList.
    При выборе задачи из списка: "Task:= TaskList[ ComboBox.ItemIndex ];"
    А там:

    // Для всех Control-ов "Enableb:= False";
    for i:= 0 to Task.Count-1 do
    begin
       if Task[i].Name = 'prm1' then Control1.Enableb:= True;
       if Task[i].Name = 'prm2' then Control2.Enableb:= True;
       . . .
       if Task[i].Name = 'prmN' then ControlN.Enableb:= True;
    end;
 
Конференция "Начинающим" » Получить названия полей из record [D7]
Есть новые Нет новых   [118426   +56][b:0][p:0.001]