Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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
3-76808
Дмитрий Баранов
2003-04-06 15:32
2003.04.24
Динамический SQL в ORACLE


6-77045
Programist21
2003-02-20 16:21
2003.04.24
Post в IdHTTP


1-76953
Pitay
2003-04-12 17:56
2003.04.24
Создание компонент во время работы проложения


7-77181
Frakt
2003-03-04 22:14
2003.04.24
ISA


8-77038
Mr.Ice
2002-12-22 02:39
2003.04.24
Поддержка скинов





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский