Обсуждение:Класс TDbf позволяющий создавать DBF-файлы без описания их структуры в словаре
0 (0)
Обсуждение:Класс TDbf позволяющий создавать DBF-файлы без описания их структуры в словаре ( Обсуждение примера 13.01.2004 10:04 )
0(0)Класс реализует набор возможностей по работе с файлами в формате DBASE III и Visual FoxPro. При помощи данного класса можно создавать DBF файлы из макропрограмм на RSL, не описывая заранее структуру будущего файла в словаре. В отличие от стандартной RSL-ной работы с DBF, понимает файлы формата Visual FoxPro.
Пример обновлен 27.03.2006
Посмотреть пример
>> Ответитьметод Delete() ( Outcast 13.01.2004 10:08 )
0(0)1) не мешало бы к классу добавить метод удаления записи из DBF
2) + метод удаления/восстановления всех помеченных записей из DBF
>> Ответитьметод Delete() ( yu 13.01.2004 13:11 )
0(0)Учту. Сейчас просто вместо Delete - MarkRecordByNumber и MarkCurrentRecord, они помечают записи на удаление. Ну и Pack потом добавлю, чтобы физически удалял помеченные записи.
>> ОтветитьА переход по записям в таблице планируется? типа Next/Prev (-) ( dik 15.01.2004 07:50 )
0(0)Not specified
>> ОтветитьА переход по записям в таблице планируется? типа Next/Prev (-) ( yu 15.01.2004 12:48 )
0(0)Планируется, планируется. Next вот готов. В ближайших планах Prev, Pack, GetItem.
>> Ответить
Обсуждение:Класс TDbf позволяющий создавать DBF-файлы без описания их структуры в словаре ( yu 15.01.2004 12:47 )
0(0)Обновил пример. Теперь можно создавать файлы в формате Visual FoxPro, добавлены методы GoToRecord(number), Next(number)
>> ОтветитьДля полного счастья не хватает GetItem :-) (-) ( dik 28.01.2004 06:30 )
0(0)Not specified
>> ОтветитьДля полного счастья не хватает GetItem :-) ( yu 02.02.2004 13:28 )
0(0)Теперь есть
>> Ответить
Обсуждение примера ( yu 02.02.2004 13:27 )
0(0)Пример обновлен. Добавлены методы Pack, GetItem, FieldsCount, FileType, CurrentRecord. Изменен метод Next (чтобы поудобнее было с ним работать). Ошибки класса теперь можно отлавливать в OnError.
>> ОтветитьЕсли вставил метод FieldsCount - считаю нужен и методы типа NameField, TypeField (-) ( dik 02.02.2004 14:56 )
0(0)Not specified
>> ОтветитьДобавлю... и в методе SetItem(number,value) - не только по номеру, но и имени поля :-) (-) ( dik 02.02.2004 15:00 )
0(0)Not specified
>> ОтветитьПожалуйста ;-) ( yu 03.02.2004 11:18 )
0(0)Пример обновлен.
Добавлены методы FldName, FldNumber, FldType. Изменен метод SetItem (теперь можно не только по номеру, но и по инени поля значение устанавливать).
>> Ответить
Пример обновлен ( yu 09.02.2004 12:51 )
0(0)Добавлены методы Rewind, Prev
>> ОтветитьВ процессе работы захотелось ещё... ( dik 22.03.2004 09:48 )
0(0)Замечено - если файл dbf не открыт - а делаешь команду close - выходит ошибка исполнения - конечно не критично - но есть некоторые неудобства :-)
Как вариант - сделать чтобы close не ругалось - а просто игнорировало или думаю уже назрело - потихонечку вводить свойства объекта, а именно - свойство открыт ли файл, какой файл открыт, в каком режиме и т.д....
Второе замечание
когда первый раз открываешь файл - указатель стоит на "нулевой" записе - т.е. если потом делаю цикл
while (aaa.next) ... end; - всё ок
но вот появилась ситуация более усложненная - мне надо 2 раза файл прогнать по циклу
первый раз - всё проходит ок, а вот во второй раз - пытаюсь вернуть запись на начало - есть только команда GoTop - но она указатель ставит на 1 запись - т.е. по тупому next уже второй раз не получится - при заходе в цикл пойдет со второй записи - т.е. предложение сделать что-нибудь вроде rewind
C уважением
>> ОтветитьСорри... про rewind не увидел чуть выше :-) (-) ( dik 22.03.2004 09:50 )
0(0)Not specified
>> ОтветитьClose поправил, пример обновил ( yu 22.03.2004 10:52 )
0(0)По поводу остального, хотелось бы поконкретнее, что нужно
>> ОтветитьКонкретнее... ( dik 22.03.2004 12:08 )
0(0)На текущий момент вижу следующие свойства объекта:
1. В каком режиме открыт файл 0-чтение 1-изменение
2. Имя файла dbf - который открыт при помощи объекта (путь файла?)
3. Может быть ещё - кодировка файла 866 или 1251
С уважением
>> Ответить
Create.... некоторые замечания ( Outcast 25.05.2004 15:21 )
0(0)1) Не секрет, что во всех DBF с 1-3 байт( три байта ) пишется Дата последнего обновления в формате YYMMDD ( в нулевом байте номер версии 03h), во всех DBF файлах, созданных Create у меня получается 66h 05h 19h, год берется не совсем корректно, т.е. 102 - 2002
я поменял в часах год на 2007 получил 69h - 105 - 2005
2) Читем в readme.txt
Close - Закрывает файл (обязательно использовать при создании нового файла).
Хотя в примерe 1 после создания DBF, сразу идет очистка буфера, заполнение и вставка записей.
Но я использую Close после Create
>> ОтветитьCreate.... некоторые замечания ( yu 27.05.2004 02:05 )
0(0)1. Действительно, для версии файлов FoxPro у меня из года вычитается 1900 и еще 2. Почему, сейчас на вскидку уже не скажу, посмотрю попозже. При работе же с версией файлов Visual FoxPro из текущего года вычитается 2000.
2. Имелось ввиду что Close обязательно использовать если файл создается с нуля (т.е. структуру создаем и т.д.). Необязательно создавать структуру, потом закрывать файл, а потом с ним работать. Можно сразу работать с файлом, главное потом не забыть Close вызвать.
>> Ответитьконструктор ( Outcast 27.05.2004 09:46 )
0(0)1. Не которые программы вычитают из текущего года и 1900, и 1990, и 2000. А вот почему еще 2 непонятно...
2. Сейчас используется пустой конструктор! А почему бы не сделать конструктор, как это сделано например, в TBfile и в нем указываем как открывать/создавать DBF. Можно ведь еще передать в него какую-нибудь структуру, по которой создаются поля и тогда необходимость постоянных вызовов (AddFields) при создании DBF отпадает. Большинство программ так и требуют: сначало создается структура базы, потом в нее добавляются записи. А необходимость добавить еще какое-нибудь поле (AddFields) в уже созданном и заполненнном DBF встречается довольно редко, НО есть!
3. В противоположность методу AddFields предлагаю и удалять поля(е) - метод DelField!
>> Ответить
открытие нескольких файлов ( grave 25.02.2005 14:31 )
0(0)хотел создать столько dbf, сколько клиентов.
первую dbf создает,
a.Create(filepath,0); (filepath = ..\\Export\\shina.dbf)
закрываем ее,
при попытке создать вторую dbf
a.Create(filepath,0); (filepath = ..\\Export\\nsktech.dbf)
onError отлавливает в этой строке такое:
Error: выполнение метода Id:1
файл НЕ создается.
>> Ответитьоткрытие нескольких файлов ( yu 25.02.2005 14:43 )
0(0)да пожалуйста :) ( grave 25.02.2005 15:00 )
0(0)/* */ /* */ /* */ /* выбор выгружаемых форм*/ /* разнесение выгрузки по разным файлам */ /* последнее изменение: */ import tdbf; const DBF_OPEN_WRITE=1; const ExportDir = "..\\Export\\"; var oOrg = tbfile ("o_Org.dbt"); macro GetInnFromINNKPP(str) var i = index(str,"/"); if (i==0) i = index(str,"\\"); end; if (i==0) return str; else return SubStr(str,1,i-1); end; end; MACRO CreateDbf(filepath) if (existfile(filepath)) delfile(filepath); end; var a=TDbf(); println(filepath); a.Create(filepath,0); a.AddFields("C","FIELD",10,0); a.Close(); END; var filenam; while(oOrg.Next) if (StrLen(oOrg.Rec.NamA)) filenam = trim(oOrg.Rec.NamA); else filenam = GetInnFromINNKPP(oOrg.Rec.INN); end; filenam = ExportDir + filenam +".DBF"; CREATEDBF(filenam); end; OnError(err) Println(err.Message+" in module "+err.Module+":"+err.Line);
РЕЗУЛЬТАТ:
..\Export\Shina.DBF
..\Export\NSKTECH.DBF
Error: выполнение метода Id:1 in module c:\ClientW\Kazna\Distrib\MAC\vyp2dbf.mac:30
>> ОтветитьСтранно, у меня работает ... ( yu 25.02.2005 15:21 )
0(0)import tdbf; MACRO CreateDbf(filepath) if (existfile(filepath)) delfile(filepath); end; var a=TDbf(); println(filepath); a.Create(filepath,0); a.AddFields("C","FIELD",10,0); a.Close(); END; createdbf("c:\\rsl\\ddd.dbf"); createdbf("c:\\rsl\\ddd1.dbf"); createdbf("..\\fff.dbf"); createdbf("..\\fff1.dbf"); OnError(err) Println(err.Message+" in module "+err.Module+":"+err.Line);
У Вас последний вариант dlm-ки? Последний был v. 854 (22.06.2004):
tdbf.d32 64512 22.06.04 13:16
>> Ответитьда, последняя. ( grave 25.02.2005 15:34 )
0(0)так и не работает. первый создает, дальше нет.
с тою же ошибкой. версия rsl 864. ща другую попробую.
>> Ответитьможно попробовать ... ( yu 25.02.2005 15:43 )
0(0)... вынести var a=TDbf(); за процедуру createDbf
>> Ответитьне помогло. и версию рсл не могу изменить - встроена видимо ( grave 25.02.2005 15:49 )
0(0)Not specified
>> Ответитьспас вынос процедуры создания в отдельный мас-модуль и ExecMacroFile.. ( grave 25.02.2005 16:14 )
0(0)Not specified
>> Ответитьпришлось вынести в отдельный модуль и процедуру заполнения ( grave 25.02.2005 17:22 )
0(0)которой давалось filepath
там шло open, setitem,insert,close
так вот и она тоже заполняла только первый файл. :(
>> ОтветитьА можно создание скроллинга на основе DBF? ( GreenStar 26.02.2005 08:47 )
0(0)Подскажите пожалуйста,
а этот класс TDBF можно использовать для создания скроллинга на основе DBF данных (средствами RSL) конечно?
>> ОтветитьА можно создание скроллинга на основе DBF? ( yu 27.02.2005 17:25 )
0(0)Можно взять за основу rslscr.mac и переделать его под использование этого класса
>> Ответить
Первый раз решил попользоваться TDbf и сразу наступил на грабли :( ( KAIssa 27.10.2005 09:34 )
0(0)Имеем следующий код
import tdbf; var a=TDbf(); a.Create("..\\test\\somefile.dbf"); a.AddFields("N","Field0",10,0); a.ClearRecord(); a.SetItem(0,1234567890); /* Field0 */ a.Insert(); a.Close();
В результате в DBF-файл записывается значение 123456789
Почему?
>> ОтветитьПервый раз решил попользоваться TDbf и сразу наступил на грабли :( ( yu 27.10.2005 11:55 )
0(0)Ошибка исправлена, пример обновлен.
>> Ответить
Обнаружилась такая проблема ( dik 08.02.2007 16:33 )
0(0)При открытии файла с расширением dbf - но не являющимся по настоящему файлом формата DBF (издержки конвертирования юзером из экселя) - программа вылетает по эксепшину
>> Ответитьсорри вопрос кажись снимается -увидел что есть обновление на эту тему (-) ( dik 08.02.2007 16:35 )
0(0)Not specified
>> Ответить
Как изменить запись? ( Wega 06.09.2007 11:55 )
5(1)Что-то я не пойму, уже существующую запись изменить как-нибудь можно или можно только добавить новую?
>> Ответитьневерно работает GetItem ( eselev 02.09.2008 16:36 )
0(0)В приведенном ниже примере результат сравнения переменной buf и GetItem - False
import tdbf;
var i,buf=77,
db=TDbf(), fp=TDbf();
db.Open("..\\MAC\\01.dbf",0);
fp.Create("..\\MAC\\007.dbf",0);
// fp.FileType = 1;
fp.AddFields("N","Field0",10,0);
fp.AddFields("C","Field1",20,0);
fp.AddFields("N","Field2",10,3);
fp.AddFields("D","Field3");
fp.ClearRecord();
fp.SetItem(0,buf); /* Field0 */
fp.SetItem(1,"text text text"); /* Field1 */
fp.SetItem(2,52.34); /* Field1 */
fp.SetItem(3,date()); /* Field1 */
msgbox((buf == fp.GetItem(0));
fp.Insert();
fp.Close();
>> ОтветитьНесколько вопросов ( fplab 31.03.2014 14:46 )
0(0)Давненько не было обсуждения по этому классу. А ведь инструмент полезный. Пользую его время от времени.
Вопросы:
1. можно ли как-то проверять помечена запись на удаление или нет?
2. правильно я понимаю, что обновление текущей записи производится путем установки новых значений методом SetItem?
И отдельно вопрос автору: планируется ли работа с индексами?
Спасибо!
>> Ответитьвызов метода ClearRecord() перед заполнением записи обязателен ( AsperZ 30.03.2022 09:39 )
0(0)в противном случае есть вероятность что будет сгенерирован файл с невалидными записями
>> Ответить