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

Вниз

Массив как параметр функции   Найти похожие ветки 

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

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

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?


 
MBo ©   (2003-02-06 09:41) [1]

var?


 
Романов Р.В. ©   (2003-02-06 09:49) [2]

MBo © (06.02.03 09:41)

Ты по это?

function TTablesDataModule.DoCmd(Command, IdTable, IdRecord: Integer;
var Data: array of TFRec; Param1: Integer = 0): Integer;


 
MBo ©   (2003-02-06 09:53) [3]

Да. Правда, я воспринял array of TFRec не как открытый, а как динамический массив.
С открытым вроде бы не должно быть проблем. Как он внутри обрабатывается? Low и High используется?


 
Романов Р.В. ©   (2003-02-06 10:00) [4]

Обрабатывается он так
for i := 0 to Length(Data) - 1 do
UpdateField(t, Data[i].FieldName, Data[i].Value);

Попробовал var. Не откомпилировалось, т.к. у меня уже есть куча таких вызовов

TablesDataModule.DoCmd(_opChange, _Cargoes,
qryCalcSum.FieldByName(_fIdnCargo).AsInteger,
[FRec(_fCgReceptions, True), FRec(_fDateReceptions, Date())]);


 
Романов Р.В. ©   (2003-02-06 11:47) [5]

Нет мыслей?


 
RWolf   (2003-02-06 11:50) [6]

попробуй вместо [] вставить VarArrayOf([])


 
Романов Р.В. ©   (2003-02-06 12:50) [7]

Что то никак не получается передать пустой массив. Не ругается только когда массив содержит хотя бы один элемент :(


 
REA ©   (2003-02-06 12:54) [8]

Nil? (Я правда наверно глупость сказал, но разбираться лень)


 
Романов Р.В. ©   (2003-02-06 12:55) [9]


> Nil?

Не компилится


 
REA ©   (2003-02-06 13:02) [10]

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


 
MBo ©   (2003-02-06 13:05) [11]

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

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


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


> не 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 // Тут ошибка


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

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


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

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

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

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


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

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

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


 
Паша ©   (2003-02-06 13:56) [16]

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

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 14:23) [17]

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


 
Sha ©   (2003-02-06 14:34) [18]

Вариант #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;


 
Паша ©   (2003-02-06 14:41) [19]

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


 
MBo ©   (2003-02-06 14:58) [20]

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;


 
gek ©   (2003-02-06 14:58) [21]


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


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


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

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; // а здесь принимаем открытый массив


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

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

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

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

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


 
Паша ©   (2003-02-06 15:19) [24]

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

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

function DoCmd( const Data: 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;


 
MBo ©   (2003-02-06 15:23) [25]

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


 
Sha ©   (2003-02-06 15:24) [26]

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

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


 
Паша ©   (2003-02-06 15:29) [27]

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


 
Sha ©   (2003-02-06 15:34) [28]

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


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

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

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

Спасибо



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

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

Наверх




Память: 0.53 MB
Время: 0.033 c
9-52698
pasha676
2002-09-13 09:28
2003.02.17
Пересечения 3D объектов


1-52939
Yarmak_Sergey
2003-02-08 13:10
2003.02.17
Разработка компонента


1-52959
Михаил
2003-02-09 22:24
2003.02.17
Обход фаервола!


1-53077
shane54
2003-02-06 14:01
2003.02.17
Базовы навыки TreeView


14-53249
Broot
2003-02-01 07:50
2003.02.17
Delphi5 standart