Текущий архив: 2003.07.17;
Скачать: CL | DM;
ВнизКонвертация 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;
Скачать: CL | DM;
Память: 0.56 MB
Время: 0.01 c