Форум: "Базы";
Текущий архив: 2003.04.24;
Скачать: [xml.tar.bz2];
ВнизКак из Table с вычисляемыми полями сделать новую таблицу? Найти похожие ветки
← →
Zn (2003-04-04 10:09) [0]Работаю с dbf. Есть таблица Table1 с несколькими вычисляемыми полями. Данные нужно сохранить в виде физической таблицы. Я создал Table2, в которой в FieldsDefs описаны все поля, такие же как и в Table1. Потом делаю Table2.CreateTable и Table2.BatchMove(Table1, batCopy). Table2.CreateTable таблицу создаёт, а Table2.BatchMove выдаёт ошибку "Invalid record structure" и удаляет физическую таблицу (Table2.TableName).
В чём ошибка? Или такая задача решается как-то по-другому?
← →
Соловьев (2003-04-04 10:19) [1]поробуй просто в цыкле сохранять. Хотя судя по всему ты что-то со структурой намудрил. Код?
← →
Zn (2003-04-04 10:58) [2]Код такой:
unit Unit7;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls,Unit4, Grids, DBGrids, DB, ADODB,DateUtils,
Buttons, Func, ExtCtrls, DBCtrls, Mask, DBTables, ActnList;
type
TForm7 = class(TForm)
BitBtn1: TBitBtn;
Penia: TTable;
Peniakod: TStringField;
Peniavb: TStringField;
Peniard: TStringField;
Peniapg: TStringField;
Peniast: TStringField;
Peniazn: TFloatField;
Peniadateup: TDateField;
Peniavid: TStringField;
PeniaNedoim: TFloatField;
PeniaStruct: TTable;
StringField1: TStringField;
StringField2: TStringField;
StringField3: TStringField;
StringField4: TStringField;
StringField5: TStringField;
FloatField1: TFloatField;
FloatField2: TFloatField;
DateField1: TDateField;
StringField6: TStringField;
procedure BitBtn1Click(Sender: TObject);
procedure PeniaCalcFields(DataSet: TDataSet);
private
{ Private declarations }
public
Dt1, Dt2: string;
{ Public declarations }
end;
var
Form7: TForm7;
implementation
{$R *.dfm}
procedure TForm7.BitBtn1Click(Sender: TObject);
begin
if not PeniaStruct.Exists then PeniaStruct.CreateTable;
PeniaStruct.BatchMove(Penia,batCopy);
end;
procedure TForm7.PeniaCalcFields(DataSet: TDataSet);
begin
PeniaNedoim.AsFloat:=NedoimForSht(Peniavid.AsString,Peniazn.AsFloat);
end;
function NedoimForSht(Vid1: string; Shts: Single): Real;
begin
case StrToInt(Vid1) of
280 : Result:=Shts/0.1;
281 : Result:=Shts/0.2;
282 : Result:=Shts/0.5;
else Result:=0
end;
end;
end.
← →
Соловьев (2003-04-04 11:03) [3]
> создал Table2, в которой в FieldsDefs описаны все поля
где это ты описал?
У тебе надо создать таблицу с полями такими как в той что с вычисляемыми, только в ней не должно быть вычисляемых. И в BatchMove прописать в свойстве Mappings соответсвие полей.
← →
Zn (2003-04-04 11:25) [4]Вот такое описание. Всё вроде как положено, имена и типы совпадают (вроде):
object Penia: TTable
Active = True
OnCalcFields = PeniaCalcFields
DatabaseName = "Tax"
Filter = "VID>="#39"280"#39" and VID<="#39"282"#39
Filtered = True
StoreDefs = True
TableName = "PENIA"
TableType = ttFoxPro
Left = 8
Top = 72
object Peniakod: TStringField
DisplayWidth = 12
FieldName = "kod"
Required = True
FixedChar = True
Size = 10
end
object Peniavb: TStringField
DisplayWidth = 3
FieldName = "vb"
Required = True
FixedChar = True
Size = 2
end
object Peniard: TStringField
DisplayWidth = 5
FieldName = "rd"
Required = True
FixedChar = True
Size = 4
end
object Peniapg: TStringField
DisplayWidth = 3
FieldName = "pg"
Required = True
FixedChar = True
Size = 2
end
object Peniast: TStringField
DisplayWidth = 3
FieldName = "st"
Required = True
FixedChar = True
Size = 2
end
object PeniaNedoim: TFloatField
DisplayWidth = 15
FieldKind = fkCalculated
FieldName = "Nedoim"
DisplayFormat = "### ### ### ##0.00"
currency = True
Precision = 2
Calculated = True
end
object Peniazn: TFloatField
DisplayWidth = 15
FieldName = "zn"
Required = True
DisplayFormat = "### ### ### ##0.00"
currency = True
Precision = 2
end
object Peniadateup: TDateField
DisplayWidth = 12
FieldName = "dateup"
Required = True
end
object Peniavid: TStringField
DisplayWidth = 4
FieldName = "vid"
Required = True
FixedChar = True
Size = 3
end
end
object PeniaStruct: TTable
OnCalcFields = PeniaCalcFields
Filtered = True
FieldDefs = <
item
Name = "Kod"
DataType = ftString
Size = 10
end
item
Name = "Vb"
DataType = ftString
Size = 2
end
item
Name = "Rd"
DataType = ftString
Size = 4
end
item
Name = "Pg"
DataType = ftString
Size = 2
end
item
Name = "St"
DataType = ftString
Size = 2
end
item
Name = "Nedoim"
DataType = ftFloat
Precision = 2
end
item
Name = "Zn"
DataType = ftFloat
Precision = 2
end
item
Name = "Dateup"
DataType = ftDate
end
item
Name = "Vid"
DataType = ftString
Size = 3
end>
StoreDefs = True
TableName = "PENIA1"
TableType = ttFoxPro
Left = 8
Top = 112
object StringField1: TStringField
DisplayWidth = 12
FieldName = "kod"
Required = True
FixedChar = True
Size = 10
end
object StringField2: TStringField
DisplayWidth = 3
FieldName = "vb"
Required = True
FixedChar = True
Size = 2
end
object StringField3: TStringField
DisplayWidth = 5
FieldName = "rd"
Required = True
FixedChar = True
Size = 4
end
object StringField4: TStringField
DisplayWidth = 3
FieldName = "pg"
Required = True
FixedChar = True
Size = 2
end
object StringField5: TStringField
DisplayWidth = 3
FieldName = "st"
Required = True
FixedChar = True
Size = 2
end
object FloatField1: TFloatField
DisplayWidth = 15
FieldKind = fkCalculated
FieldName = "Nedoim"
DisplayFormat = "### ### ### ##0.00"
currency = True
Precision = 2
Calculated = True
end
object FloatField2: TFloatField
DisplayWidth = 15
FieldName = "zn"
Required = True
DisplayFormat = "### ### ### ##0.00"
currency = True
Precision = 2
end
object DateField1: TDateField
DisplayWidth = 12
FieldName = "dateup"
Required = True
end
object StringField6: TStringField
DisplayWidth = 4
FieldName = "vid"
Required = True
FixedChar = True
Size = 3
end
end
end
← →
Соловьев (2003-04-04 11:31) [5]
with Table1 do
begin
if not Active then Open;
First;
while not Eof do
begin
Table2.Insert;
Table2.FieldByName("???").AsString := FieldByName("???").AsString;
...
Table2.Post;
Next;
end;//while
end;//with
и не парь себе мозни с BatchMove или разберись с ним почитай хелп.
← →
Zn (2003-04-04 11:41) [6]Да, наверное так и сделаю. Благодарю за подсказку.
← →
MsGuns (2003-04-04 11:45) [7]Для получения новой таблицы из уже существующей, в которой есть вычисляемые поля, лучше работать так.
Из таблицы-образца получить запросом НД, в котором уже подсчитаны все Calc-поля.
C помощью компонента (но не метода) TBatchMove с Mode=batCopy из этого "полноценного" НД создать таблицу с нужным именем.
Если нужны индексы,ключи, реструктурировать полученную таблицу SQL запросами (DDL-ALTER).
В любом случае твой способ - "грубая работа" (попытка определить структуру несуществующей таблицы в Design-Mode)
ИМХО, проект обречен на частые катаклизмы при малейшей модификации структур БД
← →
Zn (2003-04-04 12:02) [8]
> MsGuns © (04.04.03 11:45)
Вот насчёт компонента TBatchMove - это интересно! Спасибо!
Сейчас полажу по Help"у!
← →
Zn (2003-04-04 12:41) [9]
> MsGuns © (04.04.03 11:45)
Попробовал, но только вычисляемых полей TBatchMove не скопировал. Выдаёт на них ошибку, что такого поля не существует. Без вычисляемых всё нормально. Нужно установить какое-то свойство?
← →
Mike Kouzmine (2003-04-04 13:02) [10]А map составил?
← →
Zn (2003-04-04 13:07) [11]
> Mike Kouzmine © (04.04.03 13:02)
Составил. На вычисляемом поле пишет Field "Calc" not found. Убираю его - остальные поля переносит. Т.е. обращение идёт к физической таблице, а не к НД (насколько я понял).
← →
MsGuns (2003-04-04 13:13) [12]>Zn (04.04.03 13:07)
Обращение идет не к физ.таблице, а к набору данных. Вместо TTable надо использовать в качестве исходного НД TQuery, в котором вычисляемые "виртуальные" (отсутствующие в физ.таблице) поля будет представлены весьма реально и бачмув их вполне "съест", не поперхнувшись ;))
← →
Соловьев (2003-04-04 13:16) [13]
> котором вычисляемые "виртуальные" (отсутствующие в физ.таблице)
>
данная СУБД не поддерживает ХП. А алгоритм, в принцыпе, можно разбить на несколько Query...
← →
MsGuns (2003-04-04 13:29) [14]>Соловьев © (04.04.03 13:16)
А кто вообще говорил о ХП ? Я имел в виду следующее:
Есть таблица 1
1. Кол-во
2. Цена
Надо вывести в таблицу 2
1. Кол-во
2. Цена
3. Сумма
Если таблицу 1 юзать TTable`ом, а поле суммы создавать Calc`ом, то бачмув захавает только 2 первых.
Если написать запрос
SELECT *, CUST(<Кол-во>*<Сумма> as DECIMAL(8.2)) as SUMMA
FROM <Таблица 1>
то вот тут-то бачмув и захавает все 3 поля в Таблицу 2
← →
Zn (2003-04-04 13:43) [15]Я-то думал, что TTable - это тоже НД.
← →
MsGuns (2003-04-04 13:48) [16]>Zn (04.04.03 13:43)
>Я-то думал, что TTable - это тоже НД.
И TTable, и TQuery, и TClientDataSet, и TStordProc, и TADOTable, и TIBQuery и еще очень много разных цацек - все они происходят от одного "папы" - TDataSet`а, который предназначен для ПРЕДОСТАВЛЕНИЯ ПРИЛОЖЕНИЮ (КЛИЕНТУ) НАБОРА ЗАПИСЕЙ, называемого еще курсором. Вот он-то и "обзывется" НАБОРОМ ДАННЫХ или НД
← →
Zn (2003-04-04 14:00) [17]
> MsGuns © (04.04.03 13:48)
Я ж о чём и говорю: раз TTable потомок TDataSet, думал, что и TBatchMove будет с ним работать. Но раз TQuery, пусть будет TQuery. Просто нигде не написано, что с TTable не получится.
← →
Zn (2003-04-04 15:10) [18]Фиг вам! Попробовал через TQuery - аналогично! Не находит вычисляемых полей. А может это от того, что работаю с dbf? Paradox-овские таблицы Delphi понимает лучше.
← →
Mike Kouzmine (2003-04-04 15:15) [19]Вообще-то с парадоксом (попробовать сейчас недосуг), если не изменяет память, проходило.
← →
Соловьев (2003-04-04 15:20) [20]
> TQuery - аналогично! Не находит вычисляемых полей
они должны быть физически...
← →
Zn (2003-04-04 15:37) [21]
> они должны быть физически...
Это размышление или указание к действию? Если второе, прошу объяснить.
Все поля (вычисляемые в том числе) у меня созданы в Fields Editor, в Гриде они видны. Что ещё нужно?
← →
Соловьев (2003-04-04 15:41) [22]
select field1, field2+100 as calc from table
calc и будет вычисляемое.
← →
Zn (2003-04-04 15:51) [23]
> Соловьев © (04.04.03 15:41)
В том-то вся и беда, что для вычисляемого поля я использую свои функции, которые находятся в модулях. Если бы было что-то типа field2+100, то и вопросов бы не было. Придётся, видимо, использовать
Соловьев © (04.04.03 11:31)
with Table1 do
begin
if not Active then Open;
First;
while not Eof do
begin
Table2.Insert;
Table2.FieldByName("???").AsString := FieldByName("???").AsString;
...
Table2.Post;
Next;
end;//while
end;//with
Спасибо за консультацию!
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2003.04.24;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.006 c