Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / FoxPro, Visual FoxPro Новый топик    Ответить
 Модификация таблицы FoxPro 2.6  [new]
Chek_Fedor
Member

Откуда:
Сообщений: 2011
Подскажите, пожалуйста, как модифицировать структуру таблицы программно. Мне нужно перебрать n-е количество файлов DBF и вставить туда новый столбец (H_DOP), при этом данные не должны потеряться.
3 июн 11, 10:56    [10757502]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
tanglir
Member

Откуда:
Сообщений: 28966
Chek_Fedor, ЕМНИП, вы этот вопрос уже поднимали. Курите заново хелп по copy structure extended + create from
3 июн 11, 11:07    [10757574]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
Chek_Fedor
Member

Откуда:
Сообщений: 2011
Спасибо. Нашел тот скрипт.
3 июн 11, 11:18    [10757653]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
Chek_Fedor
Member

Откуда:
Сообщений: 2011
Посмотрите скрипт, пожалуйста
set safety off
For i = 1 to ADir(arDbfs, 'E:\temp\kaf????.dbf')
	?arDbfs[i,1]
USE 'E:\Temp\'+arDbfs[i,1] EXCLUSIVE alias Tab1
SET DECIMALS TO 0
select PR, GOD, FO, FAKULT, SPEC, S_FAK, SPK, KURS, KOLST, OPLP, OPLX, KOLGR, KOLPGR, SEM, PG, NED;
, PPNAME, KBLOK, NBLOK, KAF, PRED, DISZIP, NKAF, LEK, LAB, PRA, IND_RUK, EKZ, ZA, KUR, KONT, GOS;
, H_LEK, H_LAB, H_PRA, H_IND_RUK, H_ZA, H_EKZ, H_GOS, H_KONS, H_KONTR, H_KUR, H_DIPL_RUK, H_DIPL_REZ;
, H_PRA_U, H_PRA_P, H_ASP_RUK, H_SOISK_RU, H_EKZV, H_RUK, H_FDP, H_OTHER, H_VSE, H_VSEP, H_VSEX, KPBLOK;
 from Tab1  into cursor tCursor
sele Tab1
use
use TMP3
copy stru to ('E:\Temp\'+arDbfs[i,1])
sele tCursor
copy to ('E:\Temp\'+arDbfs[i,1])
use 
Next
пытаюсь структуру TMP3 скопировать в Tab1 в чем ошибка. Спасибо.
3 июн 11, 12:07    [10758040]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
IgorNG
Member

Откуда: Москва
Сообщений: 956
Chek_Fedor,

Новую структуру в существующий файл???
3 июн 11, 12:17    [10758121]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
Chek_Fedor
Member

Откуда:
Сообщений: 2011
IgorNG
Chek_Fedor,

Новую структуру в существующий файл???

Да, потом в этот файл нужно скопировать записи которые были в tab1. В общем мне нужно добавить столбец в Tab1, без потери данных.
3 июн 11, 12:20    [10758137]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
tanglir
Member

Откуда:
Сообщений: 28966
Мой моцк был съеден...
set safety off
For i = 1 to ADir(arDbfs, 'E:\temp\kaf????.dbf')
	?arDbfs[i,1]
USE 'E:\Temp\'+arDbfs[i,1] EXCLUSIVE alias Tab1
SET DECIMALS TO 0 --это зачем??
select <список_полей> from Tab1  into cursor tCursor
sele Tab1 --вместо этих 2 строк пишем
use       --use in Tab1
use TMP3 --откуда он взялся? открыт раньше?
copy stru to ('E:\Temp\'+arDbfs[i,1]) --а вот это вообще нечто
sele tCursor                          --создаём файл по структуре, лежащей в файле tmp3
copy to ('E:\Temp\'+arDbfs[i,1])      --после чего поверх него записываем
use                                   --НОВЫЙ файл из курсора. Ну и зачем?
Next --это откуда вообще??
пытаюсь структуру TMP3 скопировать в Tab1 в чем ошибка. Спасибо.
В коде.
В общем мне нужно добавить столбец в Tab1, без потери данных.
Вкратце алкоритм:
юзе старая_таблица
копи стру экстендед ту арр_стру
добавляем в арр_стру записи о новых колонках
креате новая_таблица фром арр_стру (синтаксис точно не помню, ну да в хелпе есть)
всё, новая таблица готова, дальше хоть инсерт-селектом, хоть сканом перегоняете в неё данные, тут же можно и в новые колонки инфо забить (а можно и потом)
повторить для каждого файла :)
3 июн 11, 12:38    [10758274]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
Chek_Fedor
Member

Откуда:
Сообщений: 2011
Я сделал так
set safety off
For i = 1 to ADir(arDbfs, 'E:\temp\kaf????.dbf')
	?arDbfs[i,1]
USE 'E:\Temp\'+arDbfs[i,1] EXCLUSIVE alias Tab1
SET DECIMALS TO 0
select PR, GOD, FO, FAKULT, SPEC, S_FAK, SPK, KURS, KOLST, OPLP, OPLX, KOLGR, KOLPGR, SEM, PG, NED;
, PPNAME, KBLOK, NBLOK, KAF, PRED, DISZIP, NKAF, LEK, LAB, PRA, IND_RUK, EKZ, ZA, KUR, KONT, GOS;
, H_LEK, H_LAB, H_PRA, H_IND_RUK, H_ZA, H_EKZ, H_GOS, H_KONS, H_KONTR, H_KUR, H_DIPL_RUK, H_DIPL_REZ;
, H_PRA_U, H_PRA_P, H_ASP_RUK, H_SOISK_RU, H_EKZV, H_RUK, H_FDP, H_OTHER, H_VSE, H_VSEP, H_VSEX, KPBLOK;
 from Tab1  into dbf tCursor
sele Tab1
close all
use TMP3 //таблица с нужной мне структурой
copy stru to ('E:\Temp\'+arDbfs[i,1])
close all
use tCursor
USE 'E:\Temp\'+arDbfs[i,1]
APPEND FROM E:\Temp\tCursor.DBF
use 
Next //Перебор всех файлов с маской "kaf????"


3 июн 11, 16:56    [10760627]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
tanglir
Member

Откуда:
Сообщений: 28966
омфг, лучники в шоке. Ещё скажите, что оно работает
особенно порадовало это
sele Tab1
close all
и это
use TMP3 //таблица с нужной мне структурой
copy stru to ('E:\Temp\'+arDbfs[i,1]) --делаем таблицу со стру2
close all
use tCursor
USE 'E:\Temp\'+arDbfs[i,1] 
APPEND FROM E:\Temp\tCursor.DBF --а теперь (о чудо!) пихаем туда данные со стру1
И где, #$%, в вашем коде copy structure EXTENDED???
ЗЫ. Чуть не пропустил:
close all
use tCursor
И вы ещё будете утверждать, что ЭТО работaет? МВАХАХАХАХАХАХАХАХАХАХА!!!!!!! /*безумный демонический хохАД*/
3 июн 11, 19:32    [10761412]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
tanglir
И вы ещё будете утверждать, что ЭТО работaет? МВАХАХАХАХАХАХАХАХАХАХА!!!!!!! /*безумный демонический хохАД*/

Вообще-то, ЭТО действительно будет работать, если таблица TMP3 создана ранее. Ну, да, много лишних "телодвижений", но ничего такого, что привело бы к ошибкам в работе. Собственно, для FP2.6 принципиально улучшить код проблематично. Разве что, убрать некоторые лишние команды.

Исходим из предположения, что TMP3 - это таблица с той структурой, которая должна получиться в итоге у всех таблиц указанной папки. Тогда, если убрать лишнее, имеем

* Настройка, предотвращающая возникновения запроса в случае создания таблицы с именем уже существующей таблицы
* Необходимо молча удалить ранее существующую таблицу и создать новую с тем же именем в том же месте
set safety off

* Цикл, перебирающий найденные таблицы
For i = 1 to ADir(arDbfs, 'E:\temp\kaf????.dbf')

	* Для отладки и чтобы контролировать процесс
	?arDbfs[i,1]

	* Открываем очередную таблицу, задавая ей фиксированный алиас
	USE 'E:\Temp\'+arDbfs[i,1] EXCLUSIVE alias Tab1

	* Копируем содержимое таблицы во временную таблицу с фиксированным именем
	* Можно было бы использовать COPY TO, но Select-SQL - более универсальное решение
	select PR, GOD, FO, FAKULT, SPEC, S_FAK, SPK, KURS, KOLST, OPLP, OPLX, KOLGR, KOLPGR, SEM, PG, NED;
	, PPNAME, KBLOK, NBLOK, KAF, PRED, DISZIP, NKAF, LEK, LAB, PRA, IND_RUK, EKZ, ZA, KUR, KONT, GOS;
	, H_LEK, H_LAB, H_PRA, H_IND_RUK, H_ZA, H_EKZ, H_GOS, H_KONS, H_KONTR, H_KUR, H_DIPL_RUK, H_DIPL_REZ;
	, H_PRA_U, H_PRA_P, H_ASP_RUK, H_SOISK_RU, H_EKZV, H_RUK, H_FDP, H_OTHER, H_VSE, H_VSEP, H_VSEX, KPBLOK;
	from Tab1  into dbf tCursor

	* Закрываем как исходную таблицу, так и ее копию
	close all

	* Открываем таблицу с образцовой структурой
	use TMP3

	* На основе образцовой таблицы создаем таблицу с именем очередной таблицы, 
	* но со структурой, совпадающей со структурой образцовой таблицы и пустую
	* При этом, ранее существовавшая таблица с тем же именем уничтожается
	copy stru to ('E:\Temp\'+arDbfs[i,1])

	* Закрываем все открытые таблицы
	close all

	* Открываем только что созданную таблицу с новой структурой, но пустую
	USE 'E:\Temp\'+arDbfs[i,1]

	* Копируем в нее данные из копии исходной таблицы
	APPEND FROM E:\Temp\tCursor.DBF

	* Закрываем все открытые таблицы
	close all

next

Использовать INTO CURSOR для Fp2.x - опасно. Нет гарантии, что получится именно курсор, а не исходная таблица с наложенным фильтром. В данном случае - это критически важно, поскольку исходная таблица просто удаляется.

Если структура TMP3 отличается от структуры исходных таблиц только наличием дополнительного столбца, то APPEND FROM вполне уместна. Скопирует то что нужно и куда нужно.

Здесь еще можно "пооптимизировать" с алиасами и рабочими областями, чтобы не использовать close all и закрывать таблицы "точечно" через команду USE. Но, в принципе, суть останется той же самой.
3 июн 11, 21:44    [10761885]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
golsa
Member

Откуда: Красноярск
Сообщений: 789
Оператор типа:
select *, 0000.00 as H_DOP from tab1 into dbf tab2
сразу может создать dbf нужной структуры.

Останется только переименовать таблицу tab2 в tab1.
Будет работать практически в 2 раза быстрее.
7 июн 11, 09:08    [10774448]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
golsa
Оператор типа:
select *, 0000.00 as H_DOP from tab1 into dbf tab2
сразу может создать dbf нужной структуры.

Теоретически. А практически, размерность поля H_DOP придется подбирать методом "научного тыка". Нет никакой гарантии, что размерность этого поля будет, скажем N(7,2), а не N(13,2). Т.е. числовым-то оно будет, но какая будет размерность - без гарантий.
7 июн 11, 11:01    [10775057]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
DoctoRJurius
Guest
table1 - table with data
htable - table with defined H_DOP column
table2 - result table

select T.*, H.H_DOP from table1 T, htable H into dbf table2
10 янв 12, 20:45    [11881405]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
AndreTM
Member

Откуда: Где-то в вологодских лесах...
Сообщений: 6901
DoctoRJurius, и вы ЭТО пробовали запустить на FPD2.6? Получилось?
11 янв 12, 01:21    [11882312]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
Boban5
Member

Откуда:
Сообщений: 43
Выдрал из старинного приложения. Проверь...

К сообщению приложен файл (ModiStru.rar - 1Kb) cкачать
11 янв 12, 09:08    [11882736]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
DoctoRJurius
Guest
AndreTM, yes. success.

table1 - table with data (has x records)
htable - table with defined H_DOP column (has 1 record with 0.00 value)
table2 - result table (has x*1 records)


select T.*, H.H_DOP* from table1 T, htable H into dbf table table2.dbf

select * from table1, htable into table table2.dbf
11 янв 12, 11:25    [11883506]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
thunder2
Member

Откуда:
Сообщений: 380
ВладимирМ
golsa
Оператор типа:
select *, 0000.00 as H_DOP from tab1 into dbf tab2
сразу может создать dbf нужной структуры.

Теоретически. А практически, размерность поля H_DOP придется подбирать методом "научного тыка".

Не придётся. Размерность будет такая как укажите, а именно 7,2 при условии, что не будет UNION. Я этот прием регулярно использую.
15 янв 12, 14:22    [11906688]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
thunder2
Member

Откуда:
Сообщений: 380
golsa
Оператор типа:
select *, 0000.00 as H_DOP from tab1 into dbf tab2
сразу может создать dbf нужной структуры.

Останется только переименовать таблицу tab2 в tab1.
Будет работать практически в 2 раза быстрее.

Правильно. Не фиг алгоритмизацией заниматься на фоксе. Не для этого он. Только пакетная обработка данных спасет мир.
15 янв 12, 14:24    [11906696]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
thunder2
ВладимирМ
пропущено...
Теоретически. А практически, размерность поля H_DOP придется подбирать методом "научного тыка".

Не придётся. Размерность будет такая как укажите, а именно 7,2 при условии, что не будет UNION. Я этот прием регулярно использую.

Это Вам просто повезло. Неявные преобразования тем и плохи, что их невозможно проконтролировать. Никогда не знаешь какая настройка или последовательность действий приведет к тому, что то, что раньше работало "вдруг" перестает работать.

Если Вам требуется точная размерность, то и инструмент для ее установки необходим точный. Вы ведь не знаете почему собственно прибавляется 2 знака к указанной размерности. А почему не 3 или 1? Вам не известны те критерии, по которым выбирается этот "довесок". То, что "я регулярно использую" - не аргумент.

Ну, например, сделайте такой тест

create table test (f1 C(10))
select f1, 0000.0 as f2 from test into table test2

Несмотря на общее правило, что размерность будет N+2, где N - количество символов в константе, но в данном случае размерность будет N(6,1). Т.е. явно не такая, как Вы надеялись. Другое правило действует. Размерность точно равна заданной константе.

Нет, можно, конечно, заняться исследованиями и вывести некое общее правило какая будет размерность в зависимости от "количества пятен на солнце", но это не имеет особого смысла, если есть возможность точного задания размерности.
15 янв 12, 15:01    [11906777]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
Dima T
Member

Откуда:
Сообщений: 15282
ВладимирМ,
Бывает иногда пользуюсь конструкцией типа "select 000.0 as nField". Цели как правило замена NULL значений в расчетных полях запросов.
Я в хэлпе не находил, но опытным путем установлено что фокс создает поле типа нумерик размерностью такой чтобы это число нулей вошло, под точку отводится отдельный разряд (особенность хранения типа numeric). Например:
0000 - N(4)
0000.0 - N(6,1)
0000.00 - N(7,2)

На предмет точного совпадения размерности никогда не обращал внимания, но точно могу сказать что за всю мою практику не было случаев когда бы фокс создал поле меньшего размера или меньшей точности после запятой. Иначе бы были неточности в расчетах или ошибки типа Numeric overflow

Если есть уверенность что не может быть меньше, то почему бы не быть уверенным что фокс создает размер поля точно по заданной нулями маске ?
15 янв 12, 15:27    [11906856]     Ответить | Цитировать Сообщить модератору
 Re: Модификация таблицы FoxPro 2.6  [new]
thunder2
Member

Откуда:
Сообщений: 380
ВладимирМ
Ну, например, сделайте такой тест

create table test (f1 C(10))
select f1, 0000.0 as f2 from test into table test2

Несмотря на общее правило, что размерность будет N+2, где N - количество символов в константе

С хрена ли валенки упали ?
, но в данном случае размерность будет N(6,1). Т.е. явно не такая, как Вы надеялись. Другое правило действует. Размерность точно равна заданной константе.

Владимир , по моему, Вы себе противоречите. Вы задали число 0000.0, т.е. 6 - общая длинна и 1 знак для дроби этот рез-тат Вы и получили. Тест Ваш я выполнил, результат ожидаемый. Вы кого и в чем пытаетесь убедить ? Может Вам освежить знания по типу NUMERIC ? Так я напомню Вам. Numeric (N,D) - хранит цело общей длиной N знаков, включая десятичный разделитель и D знаков после десятичного разделителя. Т.е. запись Numeric (10,1) хранит числа общей длинной 10 знаков и 1 знак после запятой. Физически Numeric в DBF таблице вообще строка !
Единственный случай когда такой подход даст сбои - вложенные запросы или UNION. Вот там да, можно получить и не то, что ожидается. И то, если во всех подзапросах и UNOIN'ах указаывать одинаковую размерность, будете получать ожидаемый результат.
16 янв 12, 00:22    [11908326]     Ответить | Цитировать Сообщить модератору
Все форумы / FoxPro, Visual FoxPro Ответить