Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.118.1.158] |
|
Сообщ.
#1
,
|
|
|
Подскажите, пожалуйста, как создать вычислимое поле во время выполнения (Run-Time).
|
Сообщ.
#2
,
|
|
|
DataSet.Fields.Add()
Тока я сомневаюсь, что Делфи тебе даст это сделать на открытой базе и без рекреейта таблицы... |
Сообщ.
#3
,
|
|
|
Пробовал с DataSet.Fields.Add - не получается
|
Сообщ.
#4
,
|
|
|
Что не получается ?
Будем гадать на кофейной гуще или кусок кода приведешь ? Кстати, а почему в DesignTime не создать это поле ? В чем проблема ? |
Сообщ.
#5
,
|
|
|
код примерно такой:
procedure TForm1.Button1Click(Sender: TObject); var TF: TField; begin TF:=TField.Create(Query1); TF.SetFieldType(ftInteger); TF.FieldName:='NID'; TF.Calculated:=True; Database1.Open; TF.DataSet:=Query1; Query1.Open; Query1.Fields.Add(TF); end; Не работает: пишет что поле не может быть вычислимым. Если убираю, что поле вычислимое - то пишет, что такое поле не найдено. А не могу во время разработки задать поля, потому что не знаю какие из них будут выбраны пользователем(запрос формируется динамически при выборе юзером полей). А вообще задача в том, чтобы задать поле, которое бы нумеровало записи. С пом. SQL (MSSQL) это получается корявенько и долго. Хотя может кто знает лучше метод? Я же пока делаю так: select IDENTITY(INT, 1, 1) AS NID, ....др поля... into #temp from ТАБЛИЦА select * from #temp |
Сообщ.
#6
,
|
|
|
А вот так работает...
Твоя ошибка, в том, что ты используешь родительский класс TField, а надо бы более конкретный TIntegerField... Да, еще такая фишка, поле не уничтожается владельцем и после его использования надо самому делать .FREE... <br> TF:=TIntegerField.Create(Table1);<br> TF.SetFieldType(ftInteger);<br> TF.FieldName:='CALCFLD';<br> TF.Calculated:=True;<br> TF.DataSet:=Table1;<br> Table1.Open;<br> Table1.Fields.Add(TF);<br> P.S. А кто тебе мешает создать поле в Design-Time, и просто его не показывать если оно не нужно, IMHO это проще... А вот еще пример из хелпа: <br>Creates an instance of TIntegerField.<br><br>constructor Create(AOwner: TComponent); override;<br><br>Description<br><br>Call Create to create and initialize an instance of TIntegerField. After calling the inherited constructor, Create sets the DataType property to ftInteger, MinValue to -2147483648, and MaxValue to 2147483647.<br><br>After instantiating a TIntegerField, associate it with a specific field by setting its FieldName property to the name of the field. Give the TIntegerField a unique identifier in the Name property. Establish where the field appears in the collection of fields by providing an ordinal number in the Index property. Associate the TIntegerField with a dataset component by setting its DataSet property to the name of the dataset component.<br><br>The example below creates a TIntegerField object for a field named Quantity accessed through a TQuery named Query1.<br><br>var<br><br> T: TIntegerField;<br>begin<br> Query1.Close;<br> T := TIntegerField.Create(Self);<br> T.FieldName := 'Quantity';<br> T.Name := Query1.Name + T.FieldName;<br> T.Index := Query1.FieldCount;<br> T.DataSet := Query1;<br> Query1.FieldDefs.UpDate;<br> Query1.Open;<br><br>end;<br> |
Сообщ.
#7
,
|
|
|
сенкью вери мач! :D
|
Сообщ.
#8
,
|
|
|
Итоговый листинг (добил ;)). Может кому понадобится...(задача не из самых редких)
procedure TForm1.Button1Click(Sender: TObject); var TF: TField; i: Integer; begin Query1.Close; Query1.Prepare; TF:=TIntegerField.Create(Query1); TF.FieldName:='NID'; TF.Calculated:=True; TF.FieldKind:=fkCalculated; TF.Name:=Query1.Name+TF.FieldName; TF.DataSet:=Query1; Query1.FieldDefs.Update; for i:=0 to Query1.FieldDefs.Count-1 do begin if Query1.FieldDefs[i].FieldClass.ClassNameIs('TAutoIncField') then TF:=TAutoIncField.Create(Query1) else if Query1.FieldDefs[i].FieldClass.ClassNameIs('TStringField') then TF:=TStringField.Create(Query1) else if Query1.FieldDefs[i].FieldClass.ClassNameIs('TDateTimeField') then TF:=TDateTimeField.Create(Query1) else if Query1.FieldDefs[i].FieldClass.ClassNameIs('TIntegerField') then TF:=TIntegerField.Create(Query1) else if Query1.FieldDefs[i].FieldClass.ClassNameIs('TFloatField') then TF:=TFloatField.Create(Query1) else if Query1.FieldDefs[i].FieldClass.ClassNameIs('TCurrencyField') then TF:=TCurrencyField.Create(Query1); TF.FieldName:=Query1.FieldDefs[i].Name; TF.Name:=Query1.Name+TF.FieldName; TF.DataSet:=Query1; Query1.FieldDefs.Update; end; Query1.Open; end; procedure TForm1.Query1AfterClose(DataSet: TDataSet); begin Query1.Fields.Clear; end; Спасибо тем, кто помог добиться этого результата. |