Что нам потребуется Чтобы приведённый ниже код заставить работать необходимо проделать следующее: - include <afxdb.h>
- include <odbcinst.h>
- инсталлировать ODBC-драйвер под названием "MICROSOFT EXCEL DRIVER (*.XLS)" (или что-то вроде этого)
- У Вас должен быть установлен Администратор (Admin) ODBC версии 3.5 или выше
Недостатки Использование псевдо DSN работает только с ODBC Администратором версии 3.51 и выше. Использование класса CRecordset напрямую (без наследования) позволяет только считывать. Любые попытки изменить данные в базе приведут к отказу в доступе. Если Вам всё-таки надо произвести такую операцию, то прийдётся использовать CRecordset обычным путём. Другой недостаток состоит в том, что большой по объёму CRecordset существенно замедляет производительность. Решение этого недостатка заключается в использовании класса CSQLDirect находящегося в https://www.codeguru.com/mfc_database/direct_sql_with_odbc.shtml. Исходный код// Запрос файла Excel void CReadExcelDlg::OnButton1() { CDatabase database; CString sSql; CString sItem1, sItem2; CString sDriver; CString sDsn; CString sFile = "ReadExcel.xls"; // имя файла. также можно использовать // что-то вроде C:\\Sheets\\WhatDoIKnow.xls // Очищаем содержимое listbox m_ctrlList.ResetContent(); // Ищем имя драйвера Excel. Это необходимо, // потому что Microsoft имеет особенность использовать // специфицеские имена типа "Microsoft Excel Driver (*.xls)" вместо // "Microsoft Excel Treiber (*.xls)" sDriver = GetExcelDriver(); if (sDriver.IsEmpty()) { // Не получается найти этот драйвер! AfxMessageBox("No Excel ODBC driver found"); return; } // Создаём псевдо DSN, включая имя драйвера и файла Excel // теперь нам не понадобится иметь явный DSN, установленный в // нашего Администратора ODBC sDsn.Format("ODBC;DRIVER={%s};DSN='';DBQ=%s", sDriver, sFile);
TRY { // Открываем базу данных, используя предварительно созданный // псевдо DSN database.Open(NULL, false, false, sDsn); // Распределяем записи CRecordset recset(&database);
// Конструируем строку SQL запроса // Заполните имена секций данных в Excel таблице, используя // "Insert->Names"(Вставка->Имя), чтобы можно было работать данными // как с таблицей в реальной базе данных. В Excel файле так же // может содержаться более одной таблицы. sSql = "SELECT field_1, field_2 " "FROM demo_table " "ORDER BY field_1"; // Выполняем данный запрос (косвенно открывая recordset) recset.Open(CRecordset::forwardOnly, sSql, CRecordset::readOnly);
// получаем результаты while (!recset.IsEOF()) { // читаем строку результата recset.GetFieldValue("field_1", sItem1); recset.GetFieldValue("field_2", sItem2);
// Вставляем результат в список m_ctrlList.AddString(sItem1 + " --> "+sItem2);
// Skip to the next resultline recset.MoveNext(); }
// Закрываем базу данных database.Close(); } CATCH(CDBException, e) { // Открытие базы данных вызвало исключение, проще говоря ошибку... AfxMessageBox("Database error: " + e->m_strError); } END_CATCH; }
// Получаем имя Excel-ODBC драйвера CString CReadExcelDlg::GetExcelDriver() { char szBuf[2001]; WORD cbBufMax = 2000; WORD cbBufOut; char *pszBuf = szBuf; CString sDriver;
// Получаем имена проинсталлированных драйверов // ("odbcinst.h" должен быть включён в проект ) if (!SQLGetInstalledDrivers(szBuf, cbBufMax, &cbBufOut)) return ""; // Ищем драйвер... do { if (strstr(pszBuf, "Excel") != 0) { // Нашли ! sDriver = CString(pszBuf); break; } pszBuf = strchr(pszBuf, '\0') + 1; } while (pszBuf[1] != '\0');
return sDriver; }
|