Имя: Пароль:
IT
 
Обойти поля Record в Дельфи в цикле.
0 H A D G E H O G s
 
08.10.14
17:34
Дня доброго.

Есть ли итератор для обхода полей записи (Record)?

аналог:

Для Каждого КлючЗначение Из Структура
1 H A D G E H O G s
 
08.10.14
17:38
Даже не так - пните в сторону написания аналога Структура
2 H A D G E H O G s
 
08.10.14
17:41
Это будет TList с элементами
TStructureElement=record
Name:String;
Data:pointer;
DataSize:NativeUInt;
DataType:byte;
end;

как то так, не?
3 H A D G E H O G s
 
08.10.14
17:42
Это будет наследник TList с доп. методами

Insert()
Property()
Delete()
Count()
Clear()
Get() - я могу себе это позволить :-)
4 Мыш
 
08.10.14
17:44
Fields.Count() и потом по индексу
5 Мыш
 
08.10.14
17:45
А, сори, попутал
6 Serginio1
 
08.10.14
18:00
7 ilya_
programmist
 
08.10.14
18:01
for d in A do smth();
8 H A D G E H O G s
 
08.10.14
18:13
(6) Ядрить-мадрить, какая няшечка этот TRTTI;
Спасибо.
9 Serginio1
 
08.10.14
18:14
(8) Помню на семерке даже можно было достучаться.
А на Net вообще рефлексия рулит
10 H A D G E H O G s
 
08.10.14
18:17
(9) Только там проблема - он вытягивает своства для ТИПА, а не для ЗНАЧЕНИЯ ТИПА. Беда.
11 H A D G E H O G s
 
08.10.14
18:18
Все таки я попробую запилить свою "Структуру" с шлюхами и блэкджеком в Дельфи.
12 Serginio1
 
08.10.14
18:23
А в Delphi же есть GetType?
  fld := rttiContext.GetType(TypeInfo(defaults)).GetField('dims');
  i := fld.GetValue(@myRec).AsInteger;
  fld.SetValue(@myRec, 42);
13 Serginio1
 
08.10.14
18:49
14 H A D G E H O G s
 
08.10.14
20:16
(12)
  fld := rttiContext.GetType(TypeInfo(defaults)).GetField('dims');

defaults - это Тип значения, а не само значение!!!
15 Banned
 
08.10.14
20:17
И на что только люди не пойдут, чтобы не писать на 1с....
16 User_Agronom
 
08.10.14
20:24
(11) Не выйдет))
17 H A D G E H O G s
 
08.10.14
20:35
(16) че это?
18 Кирпич
 
08.10.14
20:51
Ума не приложу, зачем такое нужно
19 H A D G E H O G s
 
08.10.14
20:54
(18) Из Дельфи в 1С надо вернуть Структуру 1С.
20 Кирпич
 
08.10.14
20:57
Жуть какая
21 Кирпич
 
08.10.14
21:03
(19)а чо уже можно так делать?
22 H A D G E H O G s
 
08.10.14
21:04
Даже не так.
Вернуть структура 1С из внешки я могу без проблем, но вот хранить эту структуру1С во внешке нельзя - 1С не завершает работу из -за неучтенного объекта, внешка не выполняет Done() из за того, что 1С не завершает работу :-)

Костыли в виде ОбъектВК.ЗавершитьРаботу() мне не нравятся.
23 H A D G E H O G s
 
08.10.14
21:04
(21) Можно, можно..
24 H A D G E H O G s
 
08.10.14
21:05
Только окунувшись в стандартизацию, понимаешь, как было тяжко разработчикам WinAPI
25 Кирпич
 
08.10.14
21:07
(22)ты либо непостижимый гуру, либо пьян )
26 H A D G E H O G s
 
08.10.14
21:11
(25) Когда - нибудь я допишу Нетленку 3.0 и выложу исходники, за которые не стыдно.
27 Кирпич
 
08.10.14
21:15
(26) а чо стыдно? Из интернета копипастишь?
28 H A D G E H O G s
 
08.10.14
21:16
(27) Из инета я копипастил только продвинутый base64, в котором разобрался и допилил напильником под фенечки 1С.
29 H A D G E H O G s
 
08.10.14
21:18
Воот под это дело
v8: Base64Строка(). Боль. Страдание. Унижение.

И там эти переносы строк нельзя заменить пустым символом, иначе на многомегабайтных данных будут тормоза. Там надо аккуратно с памятью отработать в самом base64
30 Serginio1
 
09.10.14
10:19
(0) Переходи на Net. Я очень люблю Delphi, но реальность такова, что под Net и примеров куча и реально платформа мощнее.
Сделай свой COM аналог структуры, либо можно через XSD и сериализацию
31 Кирпич
 
09.10.14
10:34
(30) блин. как вы угадываете, что они хотят? я вот вообще не понял зачем ему этот "итератор для обхода полей записи (Record)". Уж сколько лет пишу читаю и ни разу мне такое в голову не пришло.
32 User_Agronom
 
09.10.14
10:59
(17) Ну, безумству храбрых можно петь песню?

Может стоит замутить array of record?

Например, так

Const N = 10;
type TRecord = Record
                  NamePole:  String;
                  ValuePole: String;
                end;

      TStructura = array [0..N] of TRecord;
33 Кирпич
 
09.10.14
11:02
(32) да можно замутить всё что угодно, но "итератор для обхода полей записи (Record)"...
34 H A D G E H O G s
 
09.10.14
11:12
(32) ППЦ. И эти нубы запрещают ковырятся в носу?

Вот как то так.


unit ExtendedStructure;

interface

uses Classes, sysutils, Windows, Variants;

type
  PStructureElement = ^TStructureElement;

  TStructureElement = record
    Name:String[255];
    Data:OleVariant;
  end;

type
  TStructure = class(TList)
  public
    Procedure Insert(Name:string; Data:OleVariant);
    Function Get(Name:string):OleVariant;
    procedure Delete(Name:string);
    procedure Clear();
    Constructor Create;
    Destructor Destroy; Override;
  protected
    Function FindIndexByName(Name:string):NativeInt;
  end;

implementation

{ TStructure }

procedure TStructure.Clear;
var
  i:NativeUInt;
  CurrentStructureElement:PStructureElement;
begin
  for i:=0 to Self.Count - 1 do
  begin
    CurrentStructureElement:=Self.Items[i];
    if CurrentStructureElement <> nil then
    begin
      FreeMem(CurrentStructureElement, sizeof(TStructureElement));
    end;
  end;
  Inherited Clear();
end;

constructor TStructure.Create;
begin
  inherited;
end;

destructor TStructure.Destroy;
begin
  Self.Clear();
  inherited;
end;

procedure TStructure.Insert(Name:string; Data:OleVariant);
var
  index:NativeInt;
  UpperName:String;
  CurrentStructureElement:PStructureElement;
begin
  CurrentStructureElement:=nil;
  UpperName:=UpperCase(Name);
  Index:=FindIndexByName(UpperName);
  if index <> -1 then
  begin
    CurrentStructureElement:=Self.Items[index];
    if CurrentStructureElement <> nil then
      CurrentStructureElement^.Data:=Unassigned;
  end;
  if CurrentStructureElement = nil then
    GetMem(CurrentStructureElement, sizeof(TStructureElement));
  if index = -1 then
    Self.Add(CurrentStructureElement);
  CurrentStructureElement^.Name:=UpperName;
  CurrentStructureElement^.Data:=Data;
end;

procedure TStructure.Delete(Name:string);
var
  UpperName:String;
  index:NativeInt;
  CurrentStructureElement:PStructureElement;
begin
  UpperName:=UpperCase(Name);
  Index:=FindIndexByName(UpperName);
  if index = -1 then
    exit;
  CurrentStructureElement:=Self.Items[Index];
  if CurrentStructureElement <> nil then
  begin
    CurrentStructureElement^.Data:=Unassigned;
    FreeMem(CurrentStructureElement, sizeof(TStructureElement));
    (Self as TList).Delete(Index);
  end;
end;

function TStructure.FindIndexByName(Name:string):NativeInt;
var
  i:NativeInt;
  CurrentStructureElement:PStructureElement;
begin
  result:=-1;
  for i:=0 to Self.Count - 1 do
  begin
    CurrentStructureElement:=Self.Items[i];
    if CurrentStructureElement <> nil then
    begin
      if CurrentStructureElement <> nil then
      begin
        if CurrentStructureElement^.Name = Name then
        begin
          result:=i;
          break;
        end;
      end;
    end;
  end;
end;

function TStructure.Get(Name:string):OleVariant;
var
  index:NativeInt;
  UpperName:String;
  CurrentStructureElement:PStructureElement;

begin
  result:=Unassigned;
  UpperName:=UpperCase(Name);
  Index:=FindIndexByName(UpperName);
  if Index = -1 then
    exit;
  CurrentStructureElement:=Self.Items[Index];
  result:=CurrentStructureElement^.Data;
end;

end.
35 User_Agronom
 
09.10.14
11:13
(33) >>...итератор для обхода полей записи (Record)...

Такого невозможно.

Задача стояла не совсем так. Задача стояла как перебор некого набора значений разных типов.

Что такое структура? Это, по сути дела, некий набор пар ключ/значение.

Пару я реализовал типом TRecord. А структура - набор TStructura. В Array итератор есть))

Конечно, минусов у этого решения много, но типы значений из delphi в 1С (или из 1С в delphi) H A D G E H O G s всё равно не сможет притащить. Так что вполне годный обмен получится.
36 H A D G E H O G s
 
09.10.14
11:14
(35) "или из 1С в delphi"

Это делается с полпинка.
37 H A D G E H O G s
 
09.10.14
11:18
Ну и к (34) еще присобачить возврат массива имен полей и все будет ок.
38 User_Agronom
 
09.10.14
11:19
(34) Ну и в чём различие? В объектно-ориентированной модели?

Кстати,

constructor TStructure.Create;
begin
  inherited;
end;

зря написал. Если потомок такого метода не содержит, всё равно вызывается метод родителя.

(36) Ну-на расскажи мне, как ты передашь в delphi тип, например, СправочникСсылка.Контрагенты?
39 Кирпич
 
09.10.14
11:20
Короче я понял. Автор спрашивает одно, а решает другое. Слава богу разобрались.
40 H A D G E H O G s
 
09.10.14
11:21
(38) "зря написал. Если потомок такого метода не содержит, всё равно вызывается метод родителя. "

Я слаб в этих, объектно-ориентированных.

"Ну-на расскажи мне, как ты передашь в delphi тип, например, СправочникСсылка.Контрагенты?"

Можно параметром метода компоненты, можно самому внутри ВК создать объект.
41 H A D G E H O G s
 
09.10.14
11:22
(39) Автор спросил одно, понял, что решения нет, либо оно затянется, открыл для себя TRTTI, порадовался. и запилил свое решение с блэкджеком.
42 Кирпич
 
09.10.14
11:25
(41) а в чем блэкджек? всем когда нибудь приходится всякие динамические структуры писать. Ты впервые открыл для себя TList и возвестил об этом форуму? :)
43 User_Agronom
 
09.10.14
11:26
(40) Я delphi вообще один раз видел. Не программировал, а видел))
Выводы делаю из знаний стандартного Pascal, ну и Turbo Vision немного изучал (практически ничего не писал, но в университете что-то сдавал на эту тему).

То что я использовал Array. а ты породил класс от TList принципиального различия не несёт. Весь этот текст мне на форуме было бы лень писать))
44 Жан Пердежон
 
09.10.14
11:53
(26) приоткрой тайну, о чем вообще твоя конфа?
45 Serginio1
 
09.10.14
11:55
(31) Обойти поля можно только через рефлексию. в Delphi это RTTI или комовские ITypeInfo
46 Кирпич
 
09.10.14
12:07
(45) да накой мне её обходить, если record структура статическая и все поля в ней разных типов.
47 H A D G E H O G s
 
09.10.14
12:27
Если кому понадобиться -

  if CurrentStructureElement = nil then
    GetMem(CurrentStructureElement, sizeof(TStructureElement));

заменить на

  if CurrentStructureElement = nil then Begin
    GetMem(CurrentStructureElement, sizeof(TStructureElement));
ZeroMemory(CurrentStructureElement,sizeof(TStructureElement));
end;

Ибо при динамическом выделении в памяти - мусор, и OleVariant из за этого бесится :-)
48 Serginio1
 
09.10.14
12:33
(46) Бывают случаи типа утиной типизации или сравнение версий итд.
49 Кирпич
 
09.10.14
12:36
(48) а можно пример сравнения версий? что и с чем сравнивать с помощью RTTI?
50 Кирпич
 
09.10.14
12:43
(47) А ты сделай TStructureElement как класс, будет еще проще.
51 Кирпич
 
09.10.14
12:48
+(50) будет

if CurrentStructureElement = nil then
    CurrentStructureElement := TStructureElement.Create;

и компилятор тебе сам поля инициализирует
52 Serginio1
 
09.10.14
14:03
(49) Например сделал когда то сериализацию в формате XML с помощью RTTI и хочешь десериализовать с помощью RTTI но из старой версии при этом не сот минимальное количество 0 в описании схемы
53 Кирпич
 
09.10.14
14:38
(52) фигня какая то, но спасибо на добром слове.