Maciej Lipski

Maciej Lipski Senior Software
Engineer

Temat: Problem z plikami dbf

Witam.
Mam pewien problem z wyciaganiem i przetwarzaniem danych pochodzacych z plikow .dbf (dBase III plus). Sposob jakim wyciagam wszystkie dane z pliku:


OleDbConnectionStringBuilder lv_build = new OleDbConnectionStringBuilder();
lv_build.Provider = "Microsoft.Jet.OLEDB.4.0";
lv_build.DataSource = directory_name;
OleDbConnection lv_con = new OleDbConnection(lv_build.ToString() + ";Extended Properties=dBASE IV;");
String l_str_query = "SELECT * FROM " + file_name + ""; //file_name - nazwa pliku
OleDbDataAdapter lv_adap = new OleDbDataAdapter(l_str_query, lv_con);
DataSet lv_ds = new DataSet();
lv_adap.Fill(lv_ds);


I niby wszystko ok, dane sa wyciagniete. Tylko ze polskie znaki, ktore sa w nich sa w formie 'krzaczkow'. Musze z tej bazy wyciagac niektore dane, a niektore zmieniac. Ale niestety nie jestem w stanie wyszukiwac poprawnie, w przypadku gdy w klauzuli selekcji pojawiaja sie krzaczki. To znaczy gdy musze porownac "... WHERE col_1='ążńó'" w przypadku gdy col_1 zawiera krzaczaki, znaki nie sa sobie rowne.

Myslalem ze rozwiazalem problem, robiac cos takiego:

class libEncode
{
private const String lv_src = "windows-1250";
private const String lv_dst = "ibm852";

static public String Get(String str)
{
return Encoding.GetEncoding(lv_dst).GetString(Encoding.GetEncoding(lv_src).GetBytes(str));
}
}

Niby dla niektorych przypadkow dzialalo i moglem robic:


String lv_query = "... WHERE col_1='"+ libEncode.Get("ń") +"'";


No ale jak sie okazalo, jednak tylko dla niektorych polskich znakow trafilem w to kodowanie. Problem pozostal, tylko ze nie moge znalezc kodowania, ktore 'trafi' w te, ktore jest wykorzystane w pliku. Nawet po napisaniu:


String l_str_check = "ąćńół"; //string do sprawdzenia wyciagniety z .dbf, przypisanie ma charakter symboliczny zebyscie wiedzieli co tam jest
foreach (EncodingInfo ei1 in Encoding.GetEncodings())
{
foreach (EncodingInfo ei2 in Encoding.GetEncodings())
{
String l_str_compare = "ąćńół";
l_str_compare = Encoding.GetEncoding(el1.CodePage).GetString(Encoding.GetEncoding(el2.CodePage).GetBytes(l_str_compare));
if(l_str_check.Equals(l_str_compare)) MessageBox.Show("El1: "+ el1.CodePage +" El2: "+ el2.CodePage);
}
}


Wybralem sobie kilka przykladowych kolumn z polskimi znakami, tak zeby sprawdzic jak najwiecej. Napisalem ich odpowiedniki (tak jak w powyzszym przykladzie l_str_compare). No i klops - nie moge znalezc tego kodowania.

Moze to jakos naprowadzi kogos z Was: Sciagnalem tez 3 programy do podgladania plikow .DBF (np DBF Viewer czy DBF Lister (do totalcmd)) i wszystkie poprawnie wyswietlaja polskie znaki. Istnieje tam opcja nazywana "DOS/ANSI" lub "Use OEM characters", ktora zamienia widok z krzaczkow, ktore ja widze, na polskie znaki:

Use OEM characters
Hot key: F12
If set ON use OEM characters


Ma ktos jakies podpowiedzi jak mozna rozwiazac problem, tak, bym mogl swobodnie korzystac z polskich znakow w tym .dbf? Dodam ze nie moge konwertowac tego .dbf na inna strone kodowa - plik .dbf i jego strona kodowa musza zostac nieruszone (sa wykorzystywane przez inny, istniejacy juz program ktorego nie moge modyfikowac).
Maciej Lipski

Maciej Lipski Senior Software
Engineer

Temat: Problem z plikami dbf

Z napisaniem wlasnej funkcji tez mam problem...


class libEncode
{
private const String lv_dbase_src = "ąĄćĆęĘłŁńŃóÓżŻźŹ";
private const String lv_dbase_dst2 = "¦ąŠĂŕ¦-ú˝ĐˇË¬»čĆ";
private const String lv_dbase_dst = "¹¥æÆêʳ£ñÑóÓ¿¯Ÿ";

static public String dBase(String str)
{
for (int i = 0; i < lv_dbase_src.Length; i++)
{
str = str.Replace(lv_dbase_src[i], lv_dbase_dst[i]);
}
return str;
}
}


lv_dbase_dst2 to ciag wyciagniety z DBF Viewer
lv_dbase_dst to ciag wyciagniety z DataSetu do wyciagniecia wszystkiego.
Przy okazji Visual poprosil o zmiane strony kodowej bo nie wszystkie znaki mozna zakodowac.. no i znowu.. wybralem inna strone kodowa i znowu klops. Troche mnie to meczy. Musi byc przeciez inny sposob pracy na tych dbf
Maciej Lipski

Maciej Lipski Senior Software
Engineer

Temat: Problem z plikami dbf

Edit 2:
Dotarlem do funkcji CharToOem oraz OemToChar z user32.dll



[DllImport("user32.dll")]
static extern bool CharToOem(byte[] lpszSrc, byte[] lpszDst);

function void Bum() {
ArrayList done = new ArrayList();
foreach (EncodingInfo ei1 in Encoding.GetEncodings())
{
foreach (EncodingInfo ei2 in Encoding.GetEncodings())
{
foreach (String cur in al) //al zawiera stringi, ktore sam napisalem z polskimi znakami na zasadzie al.Add("ąćń") etc., a ktore odpowiadaja ciagom z .dbf
{
byte[] byt_1 = Encoding.GetEncoding(ei1.CodePage).GetBytes(cur.ToUpper());
byte[] byt_2 = new byte[byt_1.Length];
CharToOem(byt_1, byt_2);
String str = Encoding.GetEncoding(ei2.CodePage).GetString(byt_2);
done.Add(str);
}
}
}
foreach (DataRow cur in ds.Tables[0].Rows) //wartosci z polskimi znakami z DataSet
{
String value = ((String)cur[0]);
if(!done.Contains(value)) {
MessageBox.Show("BRAK: "+ value);
}
else MessageBox.Show("Jest: " + value);
}
}


Ponownie dalem zagniezdzone petle bo juz mi nerwy puszczaja... kolejny raz klapa. Posrod 176 400 roznie zapisanych wersji tych slow, nie znalazly sie takie, ktore by pasowaly...

Temat: Problem z plikami dbf

Nie znam sie dobrze na dbase, ale czy przypadkiem on nie koduje w UTF?? A ty chcesz z tego windows-1250?? Czy nie przez to sa problemy z krzaczkami??Łukasz Sibielak edytował(a) ten post dnia 29.11.07 o godzinie 09:45
Maciej Lipski

Maciej Lipski Senior Software
Engineer

Temat: Problem z plikami dbf

Oj jakbys doczytal do konca to bys zauwazyl ze probowalem wszystkie kodowania :) Zrobilem 'wszystko ze wszystkim' w zagniezdzonej petli z Encoding.GetEncodings();
Wiec probowalem takze i z utf-utf. Jakkolwiek problem tkwi w zamienieniu mojego ciagu, na ten jego.
Ja nie chce zamieniac rzeczy z .dbf tylko jesli np w .dbf jest kolumna 'column_a' z wartoscia 'ąćń' (zakodowana w ten jego dziwny sposob), to chciablym w klauzuli selekcji nadac SELECT * FROM plump.dbf WHERE column_a='ąćń'
Przy czym to moje 'ąćń' w column_a='TUTAJ' nie moze zostac porownane ze wzgledu na odmienne kodowanie.
Dlatego chcialem zamienic ciag pisany w C# jako String a = "ąćń", z windows-1250 NA ibm852 (system DOSowy). I myslalem ze zalatwilem sprawe, az nie natknalem sie na takie polskie znaki, ktore wyjasnily mi ze sprawa nie jest wyjasniona :P
A pozniej probowalem juz wszystkie kodowania ze wszystkimi i tez klops. Musi byc jakis inny sposob pracy na .dbf ale niestety nie znalazlem takiego w sieci.

Pozdrawiam

Temat: Problem z plikami dbf

Próbowałeś może : Encoding.Default ??
Poza tym od kiedy visual studio koduje w windows-1250, on koduje w utf8.
Maciej Lipski

Maciej Lipski Senior Software
Engineer

Temat: Problem z plikami dbf

Std zapisem, o ile dobrze patrze, jest windows-1250.
Sorrki ze tak malo odpowiadam, ale obecnie mam troche inne rzeczy na glowie :)
Pozdrawiam :)
Zbigniew R.

Zbigniew R. Kierownik Działu IT,
SKOK Kujawiak

Temat: Problem z plikami dbf

Maciej Lipski:
Ma ktos jakies podpowiedzi jak mozna rozwiazac problem, tak, bym mogl swobodnie korzystac z polskich znakow w tym .dbf? Dodam ze nie moge konwertowac tego .dbf na inna strone kodowa - plik .dbf i jego strona kodowa musza zostac nieruszone (sa wykorzystywane przez inny, istniejacy juz program ktorego nie moge modyfikowac).

Jeśli modyfikacja pliku źródłowego nie jest możliwa z uwagi na jego równoczesne wykorzystywanie w innej aplikacji, może spróbuj pracować na kopii tego pliku lub skonwertuj go do jakiejś relacyjnej bazy?

Jeśli masz możliwość/możesz to podeślij mi przykładowy plik, robiłem już z dbfami różne rzeczy, być może coś pomogę.

Może w czymś się przyda:
http://www.ogonki.agh.edu.pl/
http://www.clicketyclick.dk/databases/xbase/format/dbf...

Następna dyskusja:

Problem z plikami dbf




Wyślij zaproszenie do