Текущий архив: 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.5 MB
Время: 0.009 c