Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.05.15;
Скачать: CL | DM;

Вниз

Функция Format. Проблема, однако...   Найти похожие ветки 

 
BlackTiger   (2003-05-02 19:51) [0]

Есть такая замечательная функция Format. Принимает она два параметра - строку-шаблон (а ля C) и массив параметров. Все дело в том, что этот массив типа array of TVarRec.
А я хочу предварительно сформаровать массив моих значений и только потом передать его этой функции.

Т.е. вместо


Format("%-20s %-50s %15.2f",["aaa","asdasdasd",568.25])


написать что-то вроде


var
MyArray: array of TVarRec;
begin
//...
MyArray[0] := MyTable.Fields[0].AsString; // "aaa"
MyArray[1] := MyTable.Fields[0].AsString; // "asdasdasd"
MyArray[2] := MyTable.Fields[0].AsFloat; // 568.25
//...
ResultStr := Format("%-20s %-50s %15.2f",MyArray);
end;

Проблема вылезла в типах данных. При попытке сделать
MyArray[0] := TVarRec(MyTable.Fields[0].AsString); ругается на невозможность такого преобразования ( invalid typecast).

Можно ли это обойти? Или может есть аналог, работающий с "array of variant" (в моем случае, данные вообще OleVariant)?


 
vuk ©   (2003-05-02 20:39) [1]

Попробовать сделать можно, но я не до конца уверен, что будет правильная работа со строками (подсчет ссылок).

В принципе, можно заставить работать Ваш вариант. Для этого нужно точно знать как для каждого типа данных производится упаковка в TVarRec. В Вашем примере нужно писать не

MyArray[2] := MyTable.Fields[0].AsFloat;

а, например, так:

MyArray[2].VExtended := MyTable.Fields[0].AsFloat;


Можно также сделать следующее:


type
TVarRecArray = array of TVarRec;

function VarRecArray(const Args : array of const ) : TVarRecArray;
var
i : integer;
begin
SetLength(Result, length(Args));
for i := Low(Args) to High(Args) do
Result[i] := Args[i];
end;

function Test : string
var
Args : TVarRecArray;
begin
Args := VarRecArray([123,"123"]);
ResultStr := Format("%d, %s", Args);
end;




 
evvcom ©   (2003-05-04 00:55) [2]

Во-первых, в TVarRec может храниться любой тип данных, поэтому надо конкретизировать, какой тип хранится в данный момент, например:
MyArray[0].VType := vtExtended
И во-вторых, не надо забывать, что не для каждого типа в поле данных записи TVarRec хранится значение, очень часто там хранятся указатели. Например для vtExtended:
MyArray[0].VExtended := @Extended(MyTable.Fields[0].AsFloat) // Преобразование к Extended обязательно! Так как Extended и Double занимают разное количество байт.

Естественно не надо забывать про SetLength для динамических массивов и научиться пользоваться кроме F1 еще и "Find Declaration"


 
vuk ©   (2003-05-04 02:51) [3]

to evvcom:

>MyArray[0].VExtended := @Extended(MyTable.Fields[0].AsFloat)

А вот с этим, если не ошибаюсь, компилятор вообще куда подальше пошлёт. Адрес-то чей брать хотите?


 
evvcom ©   (2003-05-04 03:03) [4]


> А вот с этим, если не ошибаюсь, компилятор вообще куда подальше
> пошлёт. Адрес-то чей брать хотите?

Не буду спорить, возможно. Скорее всего да, компилятор пошлет. AsFloat вроде метод. Значит сделать присваивание локальному Extended, его адрес и присваивать. Подобные мелочи быстро выявляются после F9, главное указать идею.



Страницы: 1 вся ветка

Текущий архив: 2003.05.15;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.011 c
3-46608
real_dimedrol
2003-04-22 21:11
2003.05.15
Вопрос по Quickreport


14-46981
Valentino
2003-04-25 15:53
2003.05.15
Как еще кроме Application.ExeName найти каталог моей программы?


6-46889
Карелин Артем
2003-03-04 13:07
2003.05.15
RAS без Entry. Возможно ли это?


3-46561
pathfinder
2003-04-22 18:15
2003.05.15
IBQuery или IBSQL?


1-46681
Denich
2003-05-03 16:33
2003.05.15
Проблемы с Random ...