Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Массив как параметр функции [D5, Win2k]


Страницы:   1 2

Романов Р.В. ©   (2003-02-06 09:35:00) 

Доброе утро всем. Есть у меня функция

function TTablesDataModule.DoCmd(Command, IdTable, IdRecord: Integer;
Data: array of TFRec; Param1: Integer = 0): Integer;
var
t: TTable;
i: Integer;
begin // EVariantError InvalidVariant operation
...

где
TFRec = record
FieldName: string;
Value: Variant;
end;

В одном из вызовов параметр Data не нужен, и я вызываю функцию так
TablesDataModule.DoCmd(_opDel, _Cargoes, qryCargoes.FieldByName(_fIdnCargo).AsInteger, []);

При этом в самом начале функции возникает ошибка EVariantError InvalidVariant operation.
Я что то не могу сообразить как передать в функцию пустой параметр Data?


Романов Р.В.   (2003-02-06 16:17:00) [1]

Хорошая мысля приходит опосля :)

Паша © (06.02.03 15:19)
const Data: array of TFRec

Спасибо


Sha   (2003-02-06 15:34:00) [2]

2 Паша © (06.02.03 15:19)
Используя const, ты обещаешь компилятору не менять открытый массив. Возможно, в данном случае это годится.


Паша   (2003-02-06 15:29:00) [3]

MBo © (06.02.03 15:23)
Согласен, это по инерции, опять же, вычислений меньше:)


Sha   (2003-02-06 15:24:00) [4]

2 Романов Р.В. © (06.02.03 15:09)
Это 2 разные вещи:

const
NillData: array of TFRec= nil; // пустой массив с нулевым количеством элементов (High=-1)
_NullFRec: TFRec = (FieldName: ""); // будет преобразовано в массив с 1 таким элементом,
// что потребует дополнительных проверок в подпрограмме


MBo   (2003-02-06 15:23:00) [5]

>Паша
Не стоит пользоваться length в тех случаях, для которых предназначено high
почитай в хелпе про Open Arrays Parameters


Паша   (2003-02-06 15:19:00) [6]

Все равно не понял, нафига эти массивы нужны, но на такие грабли тоже наступал. Все гораздо проще:

type
TFRec = record
FieldName: string;
Value: Variant;
end;

function DoCmd( constData: array of TFRec): Integer;
begin
result:= -1;
if length(data)>=1 then
result:= data[0].Value;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption:= inttostr(DoCmd([]));
end;


Романов Р.В.   (2003-02-06 15:09:00) [7]

MBo © (06.02.03 14:58)
Я тоже смотрел в эту сторону, но array of const не переваривает Record.

Спасибо всем за внимание.

Состряпал такую константу
const
_NullFRec: TFRec = (FieldName: "");

Буду вставлять ее там где не нужны параметры.


Sha   (2003-02-06 15:00:00) [8]

2 Паша © (06.02.03 14:41)

TarrayTFRec = array of TFRec; // это динамический массив
NillData: array of TFRec= nil; // это тоже динамический массив

function DoCmd(Data: TarrayTFRec): Integer; // принимаем динамический массив
function DoCmd(Data: array of TFRec): Integer; // а здесь принимаем открытый массив


gek   (2003-02-06 14:58:00) [9]


> чем эти массивы отличаются


Динамический массив - массив с переменным размером
Размер устанавливается SetLength


MBo   (2003-02-06 14:58:00) [10]

function sum(a:array of const):string;
var i:integer;
begin
Result:="";
for i:=Low(a) to High(a) do
with a[i] do
case VType of
vtChar: Result := Result + VChar;
vtAnsiString: Result := Result + string(VAnsiString);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
caption:=sum(["a","bcd"])+sum([]);
end;


Паша   (2003-02-06 14:41:00) [11]

Sha © (06.02.03 14:23)
Прошу прощения, можно несколько развить тему - чем эти массивы отличаются (недостаток образования, пардон)?:)


Sha   (2003-02-06 14:34:00) [12]

Вариант #3. Навеяно Пашей © (06.02.03 13:56)

var
NillData: array of TFRec= nil;

function DoCmd(Data: array of TFRec): Integer;
begin;
Result:= High(Data);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin;
Caption:=IntToStr(DoCmd(NillData));
end;


Sha   (2003-02-06 14:23:00) [13]

2 Паша © (06.02.03 13:56)
TarrayTFRec = array of TFRec; // это динамический массив


Паша   (2003-02-06 13:56:00) [14]

Может, не совсем то, но работает:

type
TFRec = record
FieldName: string;
Value: Variant;
end;
TarrayTFRec = array of TFRec;

function DoCmd(Data: TarrayTFRec): Integer;
begin
result:= -1;
if data = nil then exit;
if length(data)>=1 then
result:= data[0].Value;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Label1.Caption:= inttostr(DoCmd(nil));
end;


Sha   (2003-02-06 13:52:00) [15]

Есть два решения. Тебе выбирать.
1. Перекрой свою функцию функцией без Data - и все дела.
2. Посмотри мой пример переопределения функций, работающих с открытым массивом:
http://delphibase.endimus.com/?action=viewfunc&topic=mathcalc&id=10382

В первоначальном варианте вызвать ее никак не удастся, потому что для компилятора открытый массив - это адрес первого элемента плюс индекс последнего.


Романов Р.В.   (2003-02-06 13:49:00) [16]

Написал тестовую функцию
procedure Test(a, b: Integer; d: array of XXX);

Вызываю Test(1, 2, []);
Работает при XXX = integer; double; Char;
Вызывает AV при XXX = string, Variant.

Печальный результат :(


gsu   (2003-02-06 13:35:00) [17]

1. можно еще функцию добавить без data
2. и почему б не послать туда то, что предполагалось при проектировании ?


Романов Р.В.   (2003-02-06 13:27:00) [18]


> не Length(Data) а High(Data) !!!

Хорошо переделаю

> REA © (06.02.03 13:02)

Ошибка возникает на строке begin. Если смотреть в окне CPU то годе то в процедуре @AddRefArray

function TTablesDataModule.DoCmd(Command, IdTable, IdRecord: Integer;
Data: array of TFRec; Param1: Integer = 0): Integer;
var
t: TTable;
i: Integer;
begin // Тут ошибка


MBo   (2003-02-06 13:05:00) [19]

>Романов Р.В. © (06.02.03 10:00)

не Length(Data) а High(Data) !!!


REA   (2003-02-06 13:02:00) [20]

А где именно в коде вылетает? При обращении к чему? Попробуй убери всю обработку из функции и локализуй ошибку.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо