PDA

Просмотр полной версии : Обращение к переменной типа Record


Nickers
16.12.2010, 08:56
Как при обращении к переменной типа Record использовать переменную типа String? [Record].[String]
Вот пример: Нужно обратится к определенной Ячейке, но че эт за ячейка знает только Стринг переменная S. Как обратится к Record.Name, если Name записано в S? Record.S? оО

Добавлено через 2 минуты
И есть ли альтернатива?

alexteam
16.12.2010, 13:03
в фастскрипте нет рекордов... какбэ..

supernewbie
16.12.2010, 13:49
и классов, так что все бежим строчить плагины

Nickers
16.12.2010, 14:55
Я пишу что то типо базы... (Естественно от нече делать :D) так вот там был массив на каждый объект есть свое место в матрице типа интегер, (Собственно 1й список это номера объектов, 2й это разные значения и суммы относящиеся к ниму) Но мне понадобились еще значения типов Реал и стринг... Вотя и пытался сделать параллельный список типа Рекорд куда записывал все переменные выпадающие из типа Интегер...

Добавлено через 46 секунд
А плагинами я вообще пользоватся не умею (У меня их в 3.1.8 вообще нет :D)

Добавлено через 1 час 5 минут
Кто-нить бросит описание тстринг?

Breadfan
16.12.2010, 15:05
Да есть гдето на форуме, посмотри в поиске.

Nickers
16.12.2010, 15:20
Type
rec=record
Name:string;
OID:integer;
X:real;
end;

Как через Тстринг вот это записать?

P.S. В поиске лежат только примеры скриптов и эти примеры работы с Тстринг помогают только если писать этот же скрипт...:o

Breadfan
16.12.2010, 15:29
Ну используй не один, а два списка, в одном Name=OID в другом Name=X

var
i,j,k:integer;
NameOID: TStringList;
NameX: TStringList;
procedure Init; //Вызывается при включении скрипта
begin
NameOID :=TStringList.Create;
NameX :=TStringList.Create;
for i:=1 to 10 do begin
j:=10-i;
k:=10*i;
SetValueOID(inttostr(i),inttostr(j)); //для примера - в один список сохраняю i=j (строки)
SetValueX(inttostr(i),inttostr(k));//тут сохраняю i=k
end;

end;
procedure Free; //Вызывается при выключении скрипта
begin
NameOID.savetofile('1.txt'); //сохранение баз в файл при выключении скрипта.
NameX.savetofile('2.txt');
NameOID.free;
NameX.free;
end;
procedure SetValueOID(ValName: string; Value: string);
begin
NameOID.Values[ValName]:=Value;
end;
function GetValueOID(ValName: string): string;
begin
result:=NameOID.Values[ValName];
end;
procedure SetValueX(ValName: string; Value: string);
begin
NameX.Values[ValName]:=Value;
end;
function GetValueX(ValName: string): string;
begin
result:=NameX.Values[ValName];
end;
//основная часть скрипта
//вызывается при приходе каждого пакета если скрипт включен
begin

end. - создается два списка, в одном храни (имя=оид) в другом (имя=Х) - только учитывай что Х - будет стринг - надо переводить как будет необходимо...Сохранение в файл - необязательно.

Nickers
16.12.2010, 15:50
Слушай а если SetValue('Dis' , x[:integer]);
То получим переменную Name.Dis==x типа интеджер?
Тогда может что-то получится...

Добавлено через 36 секунд
Я афк сейчас на пару часов...

Breadfan
16.12.2010, 20:22
Вобщем так, TstringList - это список строк, наподобие <Имя>=<Строка>, и имя и строка - это, ессно, string;
Как вариант можно сделать примерно вот так:
Base:TStringList;
.......................................
Base :=TStringList.Create;
.......................................
procedure SetValueBase(ValName: string; Value: string);
begin
Base.Values[ValName]:=Value;
end;
function GetValueBase(ValName: string): string;
begin
result:=Base.Values[ValName];
end;
........................................
ну и гдето в теле скрипта уже работаешь со списком:
(например ведем базу ников+оид+координаты этого перса)
if fromserver and (pck=charinfo) then begin
NameX:=ReadD(a);
NameY:=ReadD(b);
NameZ:=ReadD(c);
NameOID:=ReadD(y);// порядок считывания на память написан, может неверно быть
Name:=ReadS(x);
SetValue(Name,inttostr(NameOID));
SetValue(Name+'_cX',inttostr(NameX));
SetValue(Name+'_cY',inttostr(NameY));
SetValue(Name+'_cZ',inttostr(NameZ));
end;
.................................................. .........
когда понадобится считывание то читаешь со списка так:
Name:='Ник';
NameOID:=strtoint(GetValue(name));
NameX:=strtoint(GetValue(name+'_cX'));
NameY:=strtoint(GetValue(name+'_cY'));
NameZ:=strtoint(GetValue(name+'_cZ'));

Будет вестись одна база, со строками вида
Ник=ОИД
Ник_сХ=(координатаХ)
Ник_сY=(координатаY)
Ник_сZ=(координатаZ)

Пример - гипотетический, вести подобного рода бд будет удобнее не через ник, как написано выше, а через ОИД персов.

Nickers
17.12.2010, 08:20
С такой системой есть одно неудобство... Если берем массив типа ТстрингЛист то получим куй прийдется записывать в имя N Например так:
SetValue(Name+'_'+inttostr(i),inttostr(NameX));
И обращатся так же прийдется:
NameX:=strtoint(GetValue(name+'_'+inttostr(f)));

Добавлено через 27 минут
Нет я был не прав)) Начал писать отдельный скрипт для проверки функции и понял что там легко к переменным из массива обращения делать...

Const
max=90;
Name='lol';

Var
C:array[1..max] of TStringList;
start:boolean;
i:integerr;
procedure init;
begin
i:=1;
end;
//.......................
procedure SendMsc(msc:string); //Шаблон отправки системных сообщений
begin
buf:=#$4A;
WriteD(0);
WriteD(10);
WriteS('');
WriteS(msc);
SendToClient;
end;
//.......................
procedure SetValue(i:integerr; ValName: string; Value: string);
begin
C.Values[ValName]:=Value;
end;
function GetValue(i:integerr; ValName: string): string;
begin
result:=C[i].Values[ValName];
end;
procedure Free;
var i,j:integer;
begin
for i:=1 to max do
C[i].free;
end;
//.......................
begin
if FromClient and start then
begin
C[i]:=TStringList.Create;
SetValue(i, Name, pck[1]);
if i=max then start:=false;
SendMsc(GetValue(i, Name));
inc(i);
end;
end.
Сейчас буду тестить этот скрипт, если норм все буит (Ну или когда все исправлю, что не норм) буду менять свой скрипт...

Breadfan, Спасибо.

[I]Добавлено через 12 минут
Тееекс гдет ошибка в приеме или уже отправке пакета мб проблема с гет и сет валуе... pck[1] Это ведь стринг верно? Тогда в чем оО

Добавлено через 12 минут
Пле про криейт забыл Т_Т

Добавлено через 9 минут
Все робит но пишет не в 16ти ричной, а буквы и иероглифы))

Breadfan
17.12.2010, 08:33
Надо использовать StrToHex(pck), и (обратная ей) Hstr(string);

Nickers
17.12.2010, 08:39
Hstr берет а StrToHex выплевывает((

Breadfan
17.12.2010, 08:43
Или ставь новую версию Phx (в последних есть встроеная ф-я StrtoHex) или использовать дополнительную процедуру для перевода:

//(c) xkor
function StrToHex(packet: string):string;
var
i:integer;
tmp:byte;

function ByteToHex(b: byte): Char;
begin
if b<10 then result:=chr(b+$30)
else result:=chr(b+$37);
end;

begin
result:='';
for i:=1 to length(packet) do begin
tmp:=ord(packet[i]) div 16;
result:=result+ByteToHex(tmp);
tmp:=ord(packet[i]) - tmp*16;
result:=result+ByteToHex(tmp)+' ';
end;
end;

Nickers
17.12.2010, 09:08
Непонял)

C:=TStringList.Create;
SetValue(i, Name, Hstr(pck[1]));
SendMsc('#$'+GetValue(i, Name));
if i=max then start:=false;
inc(i);

[I]Добавлено через 1 минуту
SendMsc Должен получать '#$'+Hstr(pck[1]) Но при этом выдает мне #$

Breadfan
17.12.2010, 09:11
Тут не совсем верно, вместо
" SetValue(i, Name, Hstr(pck[1]));"
необходимо
" SetValue(i, Name, StrToHex(pck[1]));"

Пример:
a:=#$25+#$00;
SendMsg(a); // выведет - "%"
b:=Hstr(a);
SendMsg(b); // - ""
b:=StrToHex(a);
SendMsg(b); // - "25 00"

Nickers
17.12.2010, 12:01
Все, ясно, спасибо)) Потом прийду буду переделывать скрипт свой)
(Все прекрасно работает)