Russian Qt Forum
Ноябрь 24, 2024, 13:32 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Прочитать DBF  (Прочитано 14888 раз)
varkon
Гость
« Ответ #15 : Сентябрь 09, 2010, 17:21 »

А почему вы кодировку cp1251 выставляете? Вам же надо cp866?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #16 : Сентябрь 09, 2010, 21:26 »

В какой кодировке исходники?
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Astrologer
Гость
« Ответ #17 : Сентябрь 10, 2010, 09:43 »

Это файл qdbf.cpp в котором происходит чтение DBF, запись в модель и связывание модели с таблицей QTableView
Код:
#include "qdbf.h"

QDbf::QDbf(QWidget *parent) :
    QWidget(parent)
{
    QHBoxLayout *mainLayout = new QHBoxLayout(this);

    readDBF();

    QString query;
    QSqlQuery getData(QSqlDatabase::database("dbfEditor"));

            int i;

            query = "SELECT id_";
            query += tableName;
            query += ",";
            for (i=0;i<fieldsCollection.count();i++)
                {
                    query += fieldsCollection.at(i)->fieldName;
                    if (i<fieldsCollection.count()-1)
                        query += ",";
                }
            query +=" FROM ";
            query += tableName;

            model = new QDbfSqlModel(this);

            for (i=0;i<fieldsCollection.count();i++)
                {
                    if (fieldsCollection.at(i)->fieldType == "C")
                        model->addCharField(i+1);
                    if (fieldsCollection.at(i)->fieldType == "Y")
                        model->addCurrencyField(i+1);
                    if (fieldsCollection.at(i)->fieldType == "N")
                        model->addNumericField(i+1);
                    if (fieldsCollection.at(i)->fieldType == "F")
                        model->addNumericField(i+1);
                    if (fieldsCollection.at(i)->fieldType == "D")
                        model->addDateField(i+1);
                    if (fieldsCollection.at(i)->fieldType == "T")
                        model->addTimeField(i+1);
                    if (fieldsCollection.at(i)->fieldType == "B")
                        model->addDoubleField(i+1);
                    if (fieldsCollection.at(i)->fieldType == "I")
                        model->addIntField(i+1);
                    if (fieldsCollection.at(i)->fieldType == "L")
                        model->addLogicalField(i+1);
                    if ((fieldsCollection.at(i)->fieldType == "M") && (fieldsCollection.at(i)->fieldSize == 10))
                        model->addMemoField(i+1);
                    if ((fieldsCollection.at(i)->fieldType == "M") && (fieldsCollection.at(i)->fieldSize == 4))
                        model->addMemo4Field(i+1);
                    if (fieldsCollection.at(i)->fieldType == "G")
                        model->addGeneralField(i+1);
                }

            model->setQuery(query, QSqlDatabase::database("dbfEditor"));

            QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Windows-1251"));
            QTextCodec::setCodecForTr(QTextCodec::codecForName("Windows-1251"));
            QTextCodec::setCodecForLocale(QTextCodec::codecForName("Windows-1251"));
            QString trava_str = tr("?????");
            //query = "SELECT SUMMA FROM " + tableName + " WHERE TYPE LIKE '%" + trava_str + "%';";
            //query = "SELECT SUMMA, MEAN FROM " + tableName;
            //model->setQuery(query, QSqlDatabase::database("dbfEditor"));

            /*QStringList myList;
            for (int i = 0 ; i < model->rowCount();i++)
                myList.push_back(model->record(i).value("TYPE").toString());
            query = "SELECT * FROM " + tableName + " WHERE TYPE LIKE '%" + myList[24] + "%';";
            model->setQuery(query, QSqlDatabase::database("dbfEditor"));*/

            //int str = model->record(0).value("ID").toInt();

            int k = 0;

            if (model->lastError().isValid())
                {
                    QMessageBox::critical(this, tr("Eroare"), model->lastError().text());
                }

            QString tempChar;
            QString tempValue;

            model->setHeaderData(0, Qt::Horizontal, tr("ID"));

            for (int i=0; i<fieldsCollection.count(); ++i)
                {
                    tempValue = fieldsCollection.at(i)->fieldName;

                    /*tempValue += " (";
                    tempValue += fieldsCollection.at(i)->fieldType;
                    tempChar.setNum(fieldsCollection.at(i)->fieldSize);
                    tempValue += tempChar;
                    if (fieldsCollection.at(i)->fieldDecimals != 0)
                        {
                            tempValue += ",";
                            tempChar.setNum(fieldsCollection.at(i)->fieldDecimals);
                            tempValue += tempChar;
                        }
                    tempValue += ")";*/

                    model->setHeaderData(i+1, Qt::Horizontal, tempValue);
                }
            view = new QTableView(this);
            view->setModel(model);

            view->resizeRowsToContents(); //
            view->resizeColumnsToContents();// Вот здесь вылетает
}

void QDbf::readDBF()
{
    QString query;
    QFile file;
    QByteArray fieldDescription;
    int i;
    int j;
    unsigned char a,b,c,d,e,f,g,h;
    double db;

    QString dbfFileName("d:\\dbf\\1.dbf");

    QFileInfo fileInfo(dbfFileName);
    tableName = "d_"+fileInfo.baseName();
    strTableName = "s_"+fileInfo.baseName();

    file.setFileName(dbfFileName);
    if (!file.open(QIODevice::ReadOnly))
        {
            QMessageBox::critical(this, tr("Error"), tr("DBF open error"));
            return;
        }

    sizesHeader.clear();

    sizesHeader = file.read(16);

    a = sizesHeader.at(4);
    b = sizesHeader.at(5);
    c = sizesHeader.at(6);
    d = sizesHeader.at(7);
    e = sizesHeader.at(8);
    f = sizesHeader.at(9);
    g = sizesHeader.at(10);
    h = sizesHeader.at(11);

    numberOfRecords = a + (b << 8) + (c << 16) + (d << 24);
    headerLength = e + (f << 8);
    recordLength = g + (h << 8);

    file.seek(0);
    dbfFileHeader = file.read(headerLength);

    file.seek(32);
    fieldDescriptions.clear();
    fieldDescriptions = file.read(headerLength - 32);
    fieldDescriptions.truncate(fieldDescriptions.lastIndexOf('\x0D'));

    numberOfFields = fieldDescriptions.count() >> 5;

    qint16 tempOffset = 1;

    for (i=0;i<numberOfFields;i++)
        {
            fieldDescription = fieldDescriptions.mid(i*32,32);
            fieldsItem = new QFieldsItem;
            fieldsItem->fieldName = "";
            j = 0;
            while (fieldDescription[j] != '\x00')
                {
                    fieldsItem->fieldName += fieldDescription[j];
                    j++;
                }

            a = fieldDescription.at(12);
            b = fieldDescription.at(13);
            c = fieldDescription.at(14);
            d = fieldDescription.at(15);
            e = fieldDescription.at(16);
            f = fieldDescription.at(17);

            fieldsItem->fieldType = fieldDescription[11];
            fieldsItem->fieldOffset = a + (b << 8) + (c << 16) + (d << 24);

            fieldsItem->fieldOffset = tempOffset;

            tempOffset += e;

            fieldsItem->fieldSize = e;
            fieldsItem->fieldDecimals = f;
            fieldsCollection.append(fieldsItem);
        }

    QSqlQuery getData(QSqlDatabase::database("dbfEditor"));

    query = "DROP TABLE IF EXISTS ";
    query += tableName;

    getData.prepare(query);
    getData.exec();
    if (getData.lastError().isValid())
        {
            QMessageBox::critical(this, tr("Error"), getData.lastError().text());
            return;
        }

    QString tempValue;

    query = "CREATE TABLE ";
    query += tableName;
    query += " ( id_";
    query += tableName;
    query += " integer primary key autoincrement,";

    for (i=0; i<fieldsCollection.count(); ++i)
        {
            query += fieldsCollection.at(i)->fieldName;

            if (fieldsCollection.at(i)->fieldType == "C")
                {
                    query += " text";
                }
            else if (fieldsCollection.at(i)->fieldType == "L")
                {
                    query += " text";
                }
            else if (fieldsCollection.at(i)->fieldType == "M")
                {
                    if (fieldsCollection.at(i)->fieldSize == 10)
                        {
                            query += " numeric";
                        }
                    if (fieldsCollection.at(i)->fieldSize == 4)
                        {
                            query += " blob";
                        }

                }
            else if (fieldsCollection.at(i)->fieldType == "N")
                {
                    query += " text";
                }
            else if (fieldsCollection.at(i)->fieldType == "F")
                {
                    query += " text";
                }
            else if (fieldsCollection.at(i)->fieldType == "D")
                {
                    query += " text";
                }
            else
                {
                    query += " blob";
                }

            if (i<(fieldsCollection.count()-1))
                query += ",\n";
        }

    query += ")";

    getData.prepare(query);
    getData.exec();
    if (getData.lastError().isValid())
        {
            QMessageBox::critical(this, tr("Error"), getData.lastError().text());
            return;
        }

    quint32 q;
    bool ok;

    for (q=0;q<numberOfRecords;q++)
        {
            query = "INSERT INTO ";
            query += tableName;
            query += " (";
            for (j=0; j<fieldsCollection.count(); ++j)
                {
                    query += fieldsCollection.at(j)->fieldName;
                    if (j<fieldsCollection.count()-1)
                        query += ",";
                }
            query += ") VALUES (";

            recordData.clear();
            file.seek(headerLength + q*recordLength);
            recordData=file.read(recordLength);
            if (recordData.at(0) == '*')
                continue;

            QString tempDate;
            QString tempString;

            for (j=0; j<fieldsCollection.count(); j++)
                {
                    fieldsItem = fieldsCollection.at(j);
                    fieldsItem->fields = "'";
                    if (fieldsItem->fieldType == "D")
                        {
                            tempDate = recordData.mid(fieldsItem->fieldOffset,fieldsItem->fieldSize);
                            if (tempDate == "        ")
                                fieldsItem->fields+="";
                            else
                                {
                                    fieldsItem->fields += tempDate.mid(0,4);
                                    fieldsItem->fields += "-";
                                    fieldsItem->fields += tempDate.mid(4,2);
                                    fieldsItem->fields += "-";
                                    fieldsItem->fields += tempDate.mid(6,2);
                                }
                        }
                    else if (fieldsItem->fieldType == "C")
                        {
                            tempString = recordData.mid(fieldsItem->fieldOffset,fieldsItem->fieldSize);
                            //fieldsItem->fields += tempString.replace("'","''");
                            //
                            QTextCodec *codec = QTextCodec::codecForName("IBM 866");
                            QString str = codec->toUnicode(recordData.mid(fieldsItem->fieldOffset,fieldsItem->fieldSize));
                            tempString = str;
                            fieldsItem->fields += tempString.replace("'","''");
                            //
                            int k=0;
                        }
                    else if ((fieldsItem->fieldType == "N") || (fieldsItem->fieldType == "F"))
                        {
                            tempString = recordData.mid(fieldsItem->fieldOffset,fieldsItem->fieldSize);
                            db = tempString.toDouble(&ok);
                            tempString.setNum(db,'f',fieldsItem->fieldDecimals);
                            fieldsItem->fields += tempString;
                        }
                    else if (fieldsItem->fieldType == "L")
                        {
                            tempString = recordData.mid(fieldsItem->fieldOffset,fieldsItem->fieldSize);
                            fieldsItem->fields += tempString;
                        }
                    else if ((fieldsItem->fieldType == "M") && (fieldsItem->fieldSize == 10))
                        {
                            tempString = recordData.mid(fieldsItem->fieldOffset,fieldsItem->fieldSize);
                            fieldsItem->fields += tempString;
                        }
                    else
                        {
                            tempString = recordData.mid(fieldsItem->fieldOffset,fieldsItem->fieldSize).toHex().toUpper();
                            fieldsItem->fields += tempString;
                        }
                    fieldsItem->fields += "'";

                    query += fieldsItem->fields;

                    if (j<fieldsCollection.count()-1)
                        query += ",";
                }
            query += ")";

            getData.prepare(query);
            getData.exec();
            if (getData.lastError().isValid())
                {
                    QMessageBox::critical(this, tr("Error"), getData.lastError().text());
                    return;
                }
        }

    query = "DROP TABLE IF EXISTS ";
    query += strTableName;

    getData.prepare(query);
    getData.exec();
    if (getData.lastError().isValid())
        {
            QMessageBox::critical(this, tr("Error"), getData.lastError().text());
            return;
        }

    query = "CREATE TABLE ";
    query += strTableName;
    query += " ( id_";
    query += strTableName;
    query += " integer primary key autoincrement, \n";
    query += "fieldName text, \n";
    query += "fieldType text, \n";
    query += "fieldLength numeric, \n";
    query += "fieldDecimals numeric)";

    getData.prepare(query);
    getData.exec();
    if (getData.lastError().isValid())
        {
            QMessageBox::critical(this, tr("Error"), getData.lastError().text());
            return;
        }

    for (i=0; i<fieldsCollection.count(); i++)
        {
            query = "INSERT INTO ";
            query += strTableName;
            query += " (fieldName, fieldType, fieldLength, fieldDecimals) VALUES ('";
            query += fieldsCollection.at(i)->fieldName;
            query += "','";
            query += fieldsCollection.at(i)->fieldType;
            query += "','";
            tempValue.setNum(fieldsCollection.at(i)->fieldSize,10);
            query += tempValue;
            query += "','";
            tempValue.setNum(fieldsCollection.at(i)->fieldDecimals,10);
            query += tempValue;
            query += "')";

            getData.prepare(query);
            getData.exec();
            if (getData.lastError().isValid())
                {
                    QMessageBox::critical(this, tr("Error"), getData.lastError().text());
                    return;
                }
        }

    file.close();
}

Вот это qdbf.h^
Код:
#ifndef QDBF_H
#define QDBF_H

#include <QWidget>
#include <QtGui>
#include <QSqlDatabase>
#include <QSqlQueryModel>
#include <QtSql>

#include "customsqlmodel.h"
#include "structures.h"

class QDbf : public QWidget
{
Q_OBJECT
public:
    explicit QDbf(QWidget *parent = 0);

    void readDBF();

    QFieldsItem* fieldsItem;
    QList<QFieldsItem*> fieldsCollection;

    QByteArray sizesHeader;
    QByteArray fieldDescriptions;
    QByteArray dbfFileHeader;
    QByteArray recordData;

    quint32 numberOfRecords;
    quint16 headerLength;
    quint16 recordLength;
    quint16 numberOfFields;

    QTableView* view;
    QDbfSqlModel* model;

    QString tableName;
    QString strTableName;

signals:

public slots:

};

#endif // QDBF_H


Вот это файл mainwindow.cpp:
Код:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "qdbf.h"


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QDbf* dbf_new = new QDbf(this);
    setCentralWidget(dbf_new);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

Не могу понять почему вылетает. Если resize не делать, то нормально загружается, однако таблица сжата так, что ничего нельзя разобрать. Помогите пожалуйста!
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #18 : Сентябрь 10, 2010, 10:06 »

http://gitorious.org/qdbfredactor
Изучай. Это мой редактор dbf. Если будут вопросы, обращайся.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Astrologer
Гость
« Ответ #19 : Сентябрь 10, 2010, 10:16 »

Спасибо большое - буду разбираться. Я новичок в QT и вот пытаюсь открыть ваш проект в креаторе. При попытке скомпилировать:
Код:
Выполняется сборка проекта QDBFRedactor...
Запускается: c:/qt/2010.02.1/qt/bin/qmake.exe D:/my_projects/qdbfredactor-qdbfredactor-master/qdbfredactor-qdbfredactor/QDBFRedactor.pro -spec win32-g++ -r
WARNING: Failure to find: src\dbfredactor.cpp
WARNING: Failure to find: src\dbfredactormodel.cpp
WARNING: Failure to find: src\dbfredactorsortfilterproxymodel.cpp
WARNING: Failure to find: src\filterdialog.cpp
WARNING: Failure to find: src\sortdialog.cpp
WARNING: Failure to find: src\dbfredactor.h
WARNING: Failure to find: src\dbfredactormodel.h
WARNING: Failure to find: src\dbfredactorsortfilterproxymodel.h
WARNING: Failure to find: src\filterdialog.h
WARNING: Failure to find: src\sortdialog.h
WARNING: Failure to find: src\dbfredactor.cpp
WARNING: Failure to find: src\dbfredactormodel.cpp
WARNING: Failure to find: src\dbfredactorsortfilterproxymodel.cpp
WARNING: Failure to find: src\filterdialog.cpp
WARNING: Failure to find: src\sortdialog.cpp
WARNING: Failure to find: src\dbfredactor.h
WARNING: Failure to find: src\dbfredactormodel.h
WARNING: Failure to find: src\dbfredactorsortfilterproxymodel.h
WARNING: Failure to find: src\filterdialog.h
WARNING: Failure to find: src\sortdialog.h
Завершено с кодом 0.
Запускается: C:/Qt/2010.02.1/mingw/bin/mingw32-make.exe -w
mingw32-make: Entering directory `D:/my_projects/qdbfredactor-qdbfredactor-master/qdbfredactor-qdbfredactor'
C:/Qt/2010.02.1/mingw/bin/mingw32-make -f Makefile.Debug
mingw32-make[1]: Entering directory `D:/my_projects/qdbfredactor-qdbfredactor-master/qdbfredactor-qdbfredactor'
mingw32-make[1]: Leaving directory `D:/my_projects/qdbfredactor-qdbfredactor-master/qdbfredactor-qdbfredactor'
mingw32-make: Leaving directory `D:/my_projects/qdbfredactor-qdbfredactor-master/qdbfredactor-qdbfredactor'
mingw32-make[1]: *** No rule to make target `src/dbfredactor.cpp', needed by `build/dbfredactor.o'. Stop.
mingw32-make: *** [debug] Error 2
Завершено с кодом 2.
Ошибка во время сборки проекта QDBFRedactor
Во время выполнения сборки на этапе 'Make'
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #20 : Сентябрь 10, 2010, 10:38 »

Я pro не поддерживаю, надо его удалить. Открывай CMakeLists.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Astrologer
Гость
« Ответ #21 : Сентябрь 10, 2010, 18:04 »

Не пинайте сильно, но кто нибудь может объяснить куда сохраняется база физически. Вот открыли мы соединение, создали кучу таблиц. И как все это богатство сохранить? В каком формате, как потом опять считывать? Абстрагируясь пока от dbf файлов.  Улыбающийся

Далее. У меня большое количество dbf файлов. Мне их все нужно открыть, считать и занести в отдельную базу и с ней потом работать. Как эту базу сохранить, открыть?
« Последнее редактирование: Сентябрь 10, 2010, 18:21 от Astrologer » Записан
Astrologer
Гость
« Ответ #22 : Сентябрь 12, 2010, 11:01 »

Код:
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "dbfEditor");
        db.setDatabaseName("myBase.dat");
        bool okk = db.open();

okk - false возвращает. Файл не существует, но я хочу чтобы база сохранялась в файл. Как это сделать?)
Записан
nixman05
Гость
« Ответ #23 : Сентябрь 12, 2010, 11:22 »

Код:
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "dbfEditor");
        db.setDatabaseName("myBase.dat");
        bool okk = db.open();

okk - false возвращает. Файл не существует, но я хочу чтобы база сохранялась в файл. Как это сделать?)

А что возвращает db.lastError.text() ?
Записан
Astrologer
Гость
« Ответ #24 : Сентябрь 17, 2010, 08:51 »

Проблема решена. Все работает.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #25 : Сентябрь 17, 2010, 09:37 »

Проблема решена. Все работает.
Что было неверно?
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Astrologer
Гость
« Ответ #26 : Сентябрь 17, 2010, 10:07 »

Код:
void QDbfReader::openConnection()
{
    {
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "dbfEditor");
   //dbFile = "myBase.dat"
    if (!QFile::exists(dbFile)) return;
    db.setDatabaseName(dbFile);
        if (!db.open()) {
            QMessageBox::critical(0, qApp->tr("Cannot open database"),
                qApp->tr("Unable to establish a database connection.\n"
                         "This example needs SQLite support. Please read "
                         "the Qt SQL driver documentation for information how "
                         "to build it.\n\n"
                         "Click Cancel to exit."), QMessageBox::Cancel);
        }

        _base_is_open = true;
    }
}

Так работает. Хотя когда писал, db.open() иногда возвращало false. Всем большое спасибо.
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.049 секунд. Запросов: 23.