![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Массив как параметр функции [D5, Win2k]
Романов Р.В. © (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]А где именно в коде вылетает? При обращении к чему? Попробуй убери всю обработку из функции и локализуй ошибку.