Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2003.07.17;
Скачать: [xml.tar.bz2];

Вниз

Конвертация DBF из DOS в Win   Найти похожие ветки 

 
SCORPION ZP   (2003-06-19 13:14) [0]

Задача стоит перевести все базы dBASE из ОЕМ(DOS)в Win, сохранив все данные и структуру. Решаю на Delphi7.
Сейчас перекодировка полей Character реализована, а вот есть вопросы по Memo и Logical. Записи поля Logical в DOS видны, а вот в Database Desktop
только первая, а остальные пусты. При конвертации естественно получаю в
этом поле только первую запись, а остальные теряю. Поле Memo(*.DBT) я
не могу передавать в функцию конвертации как string. В этом случае нужна перекодировка всего файла DBT. Или нет?
------------------------------------------
function ConvertOemToAnsi(const S : string) : string;

{$IFNDEF WIN32}
var
Source, Dest : array[0..255] of Char;
{$ENDIF}
begin
{$IFDEF WIN32}
SetLength(Result, Length(S));
if Length(Result) > 0 then
OemToAnsi(PChar(S), PChar(Result));
{$ELSE}
if Length(Result) > 0 then
begin
OemToAnsi(StrPCopy(Source, S), Dest);
Result := StrPas(Dest);
end;
{$ENDIF}
end;
-------------------------


 
Anatoly Podgoretsky   (2003-06-19 13:22) [1]

У тебя Win16


 
kudatsky   (2003-06-19 14:01) [2]

По поводу Memo. Не проще ли так:
1. Выгрузить из Memo в файл
2. Перекодировать
3. Загрузить


 
SCORPION ZP   (2003-06-20 10:21) [3]

Anatoly Podgoretsky
У меня Win32. С полями Logical вообще проблем. Не видны Database Desktop и я через приложение невижу пусть даже в кодировке OEM.

kudatsky
1. Я вообще не загружаю базы( около 10 000 шт.) Я указываю каталог и прога конвертит все DBF, включая подкаталоги, точнее поля character(есть еще и поля D, L, N, M)- передаю их как строку в функцию конвертации. А вот поля <BLOB Memo> находятся
конечно в *.DBT.
2. Перекодировать файл DBT:
так что ли:
...
var F:TextFile; //Memo - строки текста
s:string;
begin
AssignFile(F,FileName);
Reset(F);
while Not(F) do
begin
Readln(F,s);
Writeln(ConvertOemToAnsi(s));
end;
CloseFile;
end;





 
sniknik   (2003-06-20 10:37) [4]

SCORPION ZP © (20.06.03 10:21)
> Anatoly Podgoretsky
> У меня Win32. С полями Logical вообще проблем. Не видны Database Desktop и я через приложение невижу пусть даже в кодировке OEM.

The OemToAnsi function is obsolete.

For compatibility with 16-bit versions of Windows, this function is implemented as a macro that calls the OemToChar function, which should be used for new Win32-based applications.

как сочетается с {$IFNDEF WIN32}? поправь код. должно работать.


 
SCORPION ZP   (2003-06-20 11:12) [5]

sniknik
Хорошо ты можешь накатать как использовать OemToChar.
Типа
.
var
Str, Src: string;
i:integer;
begin
...
try
Table1.Open;
Table1.FieldDefs.Update;
while (i<>FieldDefs.Count) do //цикл по полям в таблице
begin
FindFirst;
if (Fields[i].DataType = ftString)then
begin
if not Table1.IsEmpty then while not Eof do
begin
SetLength(Str, Table1.Fields[i].Size);
Src:=PChar(Table1.Fields[i].AsString);
OemToChar(Src,PChar(Str));
Table1.Edit;
Table1.Fields[i].AsString:=Str;
Table1.Post;
Table1.Next;
end;
end;
i:=i+1; // на следующее поле i
end;
finally
SetLength(Str, 0);
Table1.Close;
end;
end;
-------------------------------------------
Но может я не так довожу... Поля стринг у меня и так конвертятся
Я еще не знаю как логическое(его записи не видны под Win) и как
проконвертить Memo - точнее файл DBT???


 
Anatoly Podgoretsky   (2003-06-20 11:35) [6]

SetLength(Str, Table1.Fields[i].Size);
Src:=PChar(Table1.Fields[i].AsString);
OemToChar(Src,PChar(Str));
---------
Src:=Table1.Fields[i].AsString;
if Length(Src)>0 then OemToChar(PChar(Src),PChar(Src));

Ну и устранить прочие ошибки, но они не относятся к преобразованию


 
SCORPION ZP   (2003-06-20 12:24) [7]

Anatoly Podgoretsky

OemToChar я приводил как 2-й вариант и ещё не проверенный.
OemToAnsi на моей проге работает нормально, но только я
не знаю , что делать с полями Мемо и логическими???


 
sniknik   (2003-06-20 13:19) [8]

> что делать с полями Мемо и логическими???
в смысле проблема прочитать/записать после конвертации?

если да может помочь
читать в Mемо
var MS: TMemoryStream;
begin
MS := TMemoryStream.Create;
try
TBlobField(Table1.FieldByName("MemoFieldName")).SaveToStream(MS);
MS.Position:= 0;
Memo1.Lines.LoadFromStream(MS);
finally
MS.Free;
end;
end;


а с логическими по моему ничего делать не надо.


 
SCORPION ZP   (2003-06-20 14:03) [9]

sniknik

1.Я понимаю, что мне нужно:
...
открыть DBT
прочесть первую строку
----------ЦИКЛ---------
перекодировать
перезаписать
прочесть следующую
----------END----------

А как у тебя с потоком(?) пример. Как будет
в твоем примере, если сделать по циклу описанному выше?
Или дай пояснение своему.

2. //а с логическими по моему ничего делать не надо.
Я считываю каждое поле и в поле прохожу по записям. Дохожу
до логического, а в нем (например) первая запись есть,
а остальные пусты. Соответственно я получаю то же в результате.
НО!!!! В DOS (!) все записи для этого поля заполнены
В DOS - F,T
B Win - False,True
....


 
sniknik   (2003-06-20 14:42) [10]

> Как будет в твоем примере, если сделать по циклу описанному выше?
никак, я в примере в DBT напрямую не лезу.

> Или дай пояснение своему.
считал(куданибудь, тот же Мемо1) -> сконвертировал -> записал.
можно метод потока переписать и конвертировать на передаче.

> НО!!!! В DOS (!) все записи для этого поля заполнены
> В DOS - F,T
> B Win - False,True
представление только, под запись и там и там 1байт.


 
SCORPION ZP   (2003-06-20 15:04) [11]

sniknik
Ладно попробую с потоком, если получится...
А вот fields Logical ....


 
Anatoly Podgoretsky   (2003-06-20 15:26) [12]

Неприменима такая операция к логическим полям, у них два значения True/False


 
SCORPION ZP   (2003-06-20 15:40) [13]

Anatoly Podgoretsky

> Неприменима такая операция к логическим полям, у них два
> значения True/False

Хорошо кааааааааак работать с этим полем в Win, если его значения
не видны(!) -нет их(!). НО в DOS(!) все(!) записи есть!!!

sniknik
При следуещем коде в Memo1 ничего нет. Проверь сам...

var MS: TMemoryStream;
begin
MS := TMemoryStream.Create;
try
Table1.DatabaseName:="d:\1\";
Table1.TableName:= "d:\1\ORDER.DBF";
Table1.Open;
TBlobField(Table1.FieldByName("LIST_SMETA")).SaveToStream(MS);
MS.Position:= 0;
Memo1.Lines.LoadFromStream(MS);
Table1.Close;
finally
MS.Free;
end;
end;


 
sniknik   (2003-06-20 15:59) [14]

sniknik
> При следуещем коде в Memo1 ничего нет. Проверь сам...
присылай таблицу, проверю. в моих все есть.


 
Anatoly Podgoretsky   (2003-06-20 16:04) [15]

SCORPION ZP © (20.06.03 15:40)
В Виндоус значения этого поля видны, а в конкретной программе еще и в том виде в каком нужно.



 
SCORPION ZP   (2003-06-20 17:15) [16]

sniknik
Загляни в ящик!

Anatoly Podgoretsky

> В Виндоус значения этого поля видны, а в конкретной программе
> еще и в том виде в каком нужно

Значения логических полей(подчеркиваю)не видныыыыыы(т.е. средствами Database Desktop и через DBGrid)!!! а в проге мне просто не счем работать, т.к. ... нет записей!


 
Anatoly Podgoretsky   (2003-06-20 17:28) [17]

У тебя что то неверно сделано, видно все прекрасно в Database Desktop и через DBGrid (здесь даже в том виде в каком скажу)


 
SCORPION ZP   (2003-06-20 17:42) [18]

Anatoly Podgoretsky
> У тебя что то неверно сделано, видно все прекрасно в Database
> Desktop и через DBGrid (здесь даже в том виде в каком скажу)
>

Прошу прощения какую базу вы просматриваете - сделанную в DOS
или под Win? На какой ящик прислать вам одну из них?


 
SCORPION ZP   (2003-06-20 17:52) [19]

sniknik
А у тебя в потоке
...
TBlobField(Table1.FieldByName("MemoFieldName")).SaveToStream(MS);
MS.Position:= 0;
Memo1.Lines.LoadFromStream(MS);
...


считывается текущее значение мемо-поля или все записи этого поля?


 
Anatoly Podgoretsky   (2003-06-20 17:56) [20]

Обе и постоянно работаю с большим количество их, базы именно dBase и FoxPro


 
SCORPION ZP   (2003-06-20 18:22) [21]

Anatoly Podgoretsky
> Обе и постоянно работаю с большим количество их, базы именно
> dBase и FoxPro

Куда прислать свою? Куда прислать свою? Куда прислать свою?

sniknik

Я вижу у тебя в потоке считывается текущее значение мемо-поля
точнее первое(а то в Мемо1 я получаю всё время пусто, потому как многие записи мемо-поля, в том числе и первая не заполнены)
А как зациклить поток по всем записям этого поля?
Не удивляйся, что спрашиваю. С потоком не дружу....


 
SCORPION ZP   (2003-06-20 18:33) [22]

Или как мне с потока на ходу передавать строку (как стринг) в процедуру конвертации. И так по цыклу пока не последняя запись
в мемо-поля


 
sniknik   (2003-06-20 19:23) [23]

сорри отвлекся на работу. ;о)

внеси изменения в код от

SCORPION ZP © (20.06.03 15:40)
> sniknik
> При следуещем коде в Memo1 ничего нет. Проверь сам...

var MS: TMemoryStream;
begin
MS := TMemoryStream.Create;
try
Table1.DatabaseName:="d:\1\";
Table1.TableName:= "d:\1\ORDER.DBF";
Table1.Open;
Table1.MoveBy(6);
TBlobField(Table1.FieldByName("LIST_SMETA")).SaveToStream(MS);
MS.Position:= 0;
Memo1.Lines.LoadFromStream(MS);
Table1.Close;
finally
MS.Free;
end;
end;

тогда и увидиш хоть чтото. (исходя из присланных табличек, если чегто поудалял/добавил начало непустого мемо изменится).


 
SCORPION ZP   (2003-06-20 21:12) [24]

sniknik
1.

> Table1.MoveBy(6);

Я уже заметил то, что записи не все и первой небудет в Memo1...
Сейчас борюсь с тем, что передаю строку из Memo1(содержимое тек. записи из BLOB-Memo)-> конверчу -> и записываю в базу:
Table1.FieldByName("LIST_SMETA").Value:=ConvertOemToAnsi(Memo1.Lines.Strings[0]);
так вот обрезаются при записи все строки, которые в Memo1 идут
после нулевой. Если я сделаю там типа

var
i, Max : Integer;
begin
...
i:=0;
Max := Memo1.Lines.Count;
while i< Max do
begin
...
Table1.FieldByName("LIST_SMETA").Value:=ConvertOemToAnsi(Memo1.Lines.Strings[ i]);
....

но в этом коде строка в Memo-поле будет перезаписываться, а как
сделать чтобы добавлялась к уже отконвертированной(если например
в одной записи Memo несколько строк, а не одна)

2. А ты смотрел базу REGISTER.DBF и его логическое поле ISOPEN
У тебя есть в нем записи????


 
sniknik   (2003-06-20 23:00) [25]

1. как читается через блоб так и пишется, причем все сразу а не построчео. набери справку по блоб полям, и не мучайся.
2. только в 1ой записи есть значение false. ничего нестандартного нет, размерность поля как и ожидалось 1 байт.


 
SCORPION ZP   (2003-06-21 09:55) [26]

sniknik
> только в 1ой записи есть значение false. ничего нестандартного
> нет, размерность поля как и ожидалось 1 байт.

Ты знаешь прогу DBDFS или др. Просмотри базу REGISTER.DBF через
неё и увидишь, что есть все записи (false) в поле ISOPEN!!!

> как читается через блоб так и пишется, причем все сразу
> а не построчео. набери справку по блоб полям, и не мучайся.

Я же немогу передавать в функцию перекодировки многострочную
запись(из одной ячейки им. ввиду) Memo-поля. Передаю построчно
А в одной записии Memo-поля строк то будет от 0 до N. Через поток
записываем запись в Memo1 а из последнего построчно перекодирываю
После того как в Memo1 прохожу поледнюю строку для данной
записи Memo-поля буду присваивать результат(многострочный перекодированный текст). Ещё не пробовал как это сработает...


 
SCORPION ZP   (2003-06-21 12:58) [27]

Как сделать чтобы из потока в Memo1 попадали только строки
тек. записи Memo-поля, а не наращивались как в след. коде:
var MS: TMemoryStream;
i,k,Max : Integer;
begin
MS := TMemoryStream.Create;
try
Table1.Open;
Table1.FieldDefs.Update;
i:=0; // перебор по полям
while (i<>Table1.FieldDefs.Count) do
begin
if (Table1.Fields[i].DataType = ftMemo) then
begin
Table1.FindFirst;
if not Table1.IsEmpty then
while not Table1.EOF do
begin
TBlobField(Table1.Fields[i]).SaveToStream(MS);
MS.Position:=0;
Memo1.Lines.LoadFromStream(MS);
Max :=Memo1.Lines.Count;
k:=0; // перебор по строкам в Memo1
while k<> Max do
begin
Memo1.Lines.Strings[k]:=ConvertOemToAnsi(Memo1.Lines.Strings[k]);
k:=k+1;
end;
Table1.Edit;
//Table1.Fields[i].AsString:=Memo1.Lines.Text;
Table1.Fields[i].Value:=Memo1.Lines.Text;
Table1.Post;
Table1.Next;
Memo1.Clear;
//MS.Position:=MS.Position+1;
end;
end;
i:=i+1;
end;
finally
MS.Free;
end;

Можно ли использовать MS.Position или нет?


 
SCORPION ZP   (2003-06-21 15:21) [28]


> Как сделать чтобы из потока в Memo1 попадали только строки
> тек. записи Memo-поля

это я уже сделал так что для каждой записи(!) Memo-поля делаю
...
MS := TMemoryStream.Create; //
...
MS.Free;

sniknik
2. А ты смотрел базу REGISTER.DBF и его логическое поле ISOPEN
У тебя есть в нем записи????



 
SCORPION ZP   (2003-06-21 16:12) [29]

Остался один вопрос. Как бороться со следующим явлением:
В Database Desktop для DOS dbf-таблиц(для др. не проверял)
обнаружен след. глюк. Если кол. записей в табл. не велико
(напр. 10-20 или около того), то в логическом поле записи
появляются в произвольном порядке - 1,2 шт(и где бог послал) при том, что должы быть заполнены все без исключения.
А вот если записей в таблице например 600 или 6000, то только
тогда в этом полеот ображается все верно.
Какой выход подскажете господа? Ведь я конвертирую то, что видит Database Desktop (/Delphi). Большие базы -без потерь, а маленькие
с "дырами" в логических полях.


 
Anatoly Podgoretsky   (2003-06-21 16:26) [30]

В логическом поле нет записей, говори связно.


 
SCORPION ZP   (2003-06-21 18:47) [31]

Ув. Anatoly Podgoretsky

> В логическом поле нет записей, говори связно.

Они то есть, если просматривать через DBDFS или wdbfview, а вот
Database Desktop их не показывает!!!
Ещё раз - все записи всех полей, которые не логические, видны как есть, а вот логические показываются по схеме не поддающейся
ни какому анализу!

Дайте адрес своего ящика - я пришлю очень маленькую базу(без вирусов!) для проверки


 
panov   (2003-06-21 19:04) [32]

Мне вышли пример такой посмотреть, плиз.


 
SCORPION ZP   (2003-06-21 19:18) [33]

panov

> Мне вышли пример такой посмотреть, плиз.

Пример чего??? Я говорил об одной из маленьких баз dbf, в кот.
и опять всё сначала.... У меня их несколько тысяч!
А ты, что хотел код проги?


 
sniknik   (2003-06-21 19:45) [34]

SCORPION ZP © (21.06.03 15:21)
> А ты смотрел базу REGISTER.DBF и его логическое поле ISOPEN
У тебя есть в нем записи????
sniknik © (20.06.03 23:00)
> 2. только в 1ой записи есть значение false. ничего нестандартного нет, размерность поля как и ожидалось 1 байт.
повторить, еще раз?

> Ты знаешь прогу DBDFS или др. Просмотри базу REGISTER.DBF через
неё и увидишь, что есть все записи (false) в поле ISOPEN!!!
нет в DBDFS не смотрел и не буду. у меня достаточно других редакторов/просмотршиков.
что ты в нем видиш могу пояснить. (только поверь сразу, второй раз и доказывать не буду)

первое логическое поле имеет размерность 1 байт (говорим только про dBase до 5 версии)

второе dBase все поля держит в тексте имеет кучу драйверов которые с ним работают и записывают исходя из собственных "понятий".

третье для логического поля есть только 2 значения true/false значения Null не существует, но (но есть всегда) смотри второе.

четвертое в "понятии" проги DBDFS скорее всего все что не True есть False, что в принципе правильно, это тебе и показывают, но (не забыл еще? но есть всегда) записанного значения в полях нет (только 1-е поле заполнено), претензии к драйверу/программе/разработчику с помощью которого эту таблицу заполняли. хотя какие претензии? он скорее тоже считает все что не true то false и у него все правильно. вобще т.к. на самом деле поле в тексте многие драйвера обращаются с ним достаточно "вольно".

пятое самый правдивый редактор тот который не делает преобразований, текстовый в досе (NC -> F4). открой, найди строчку 2003041407:59:58 F, вот эта F единственное заполненное поле в той таблице (попробуй найди другие).

шестое не видя кода трудно чтото сказать. но могу предположить что при переносе ты не используеш AsBoolean а используеш Value у которого (вот ирония) есть значение Null, и которое при этом значении просто ничего не пишет. сам повторяеш то что описано в четвертом, но только наполовину, не пишеш но при чтении не делаеш правила "что не true то false", отсюда "дыры". (AsBoolean должен бы был привести атоматически, но... Value?)

седьмое и самое главное, не путай данные и их представление на экране. я тебе могу сделать чтобы значения на экране менялись там где true будет false, но данные в таблице это совсем не то.


 
SCORPION ZP   (2003-06-21 21:08) [35]

sniknik
1. Я очень тебе благодарен за очень толковое разъяснение!!!
DBDFS ввел меня в заблужение. Так как он работает под DOS и просматривает базы, написанные под DOS, я и поверил, что то
что видет он, то и есть в реальной базе. А потом ведь wDBFview
работающий под Win)показал мне то же, что и DBDFS.
Но VC/NC не врут!!! 2003041407:59:58F, вот эта F единственное заполненное поле в той таблице...

2.
> не видя кода трудно чтото сказать. но могу предположить
> что при переносе ты не используеш AsBoolean а используеш
> Value у которого (вот ирония) есть значение Null, и которое
> при этом значении просто ничего не пишет. сам повторяеш
> то что описано в четвертом, но только наполовину, не пишеш
> но при чтении не делаеш правила "что не true то false",
> отсюда "дыры". (AsBoolean должен бы был привести атоматически,
> но... Value?)

Дело в том, что я конверчу только поля Character и Memo, а поля
Number, Date и Logical оставляю в том же виде. Может я не прав?
А "дыры" мне привидились из-за DBDFS. Я сам был ошарашен - когда
проконвертировав таблицу, нетрогая(!) поле Logical, получил в нем
первую запись, а остальные "потерял". И из-за этого взялся за голову, т.к. таких(подобных) таблиц у меня много и все нужно конвертить(автоматом конечно).
Так, что всем спасибо! Если я не прав по-поводу нужно ли конвертить Number, Date и Logical жду от вас доказательств.
А так на них я не теряю время при конвертации...


 
SCORPION ZP   (2003-06-23 12:44) [36]

Нет все-таки логические, которые Fields[i].Value=Null я заполню
на False.



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2003.07.17;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.011 c
1-55624
Franzy
2003-07-03 19:57
2003.07.17
Создание своих компонент - технический вопрос


1-55557
Navi
2003-07-06 22:52
2003.07.17
Вставка текста в ячейку TStringGrid


1-55586
AlexA
2003-07-03 10:29
2003.07.17
Не могу записать значение ключа для INI файла


11-55491
naHkep
2002-11-12 20:46
2003.07.17
свойство Default у кнопки в коле нету


14-55775
Карелин Артем
2003-06-30 13:48
2003.07.17
Как распаковать экзешник, запакованный с помощью UPX?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский