Access 使用者建立的資料表在 `MSysObjects` 系統表中 `Type` 欄位值為 1 (或 `TABLE` 字串)。ADO `OpenSchema(adSchemaTables)` 可枚舉所有資料表,篩選 `TABLE_TYPE = 'TABLE'` 即得使用者資料表清單。
void OpenSchemaX(TCHAR* TableName) { // TableName = 完整 .mdb 路徑
_ConnectionPtr pConn("ADODB.Connection");
_RecordsetPtr pRs("ADODB.Recordset");
try {
pConn->ConnectionString = _bstr_t(
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=") + TableName;
pConn->Open("", "", "", adModeUnknown);
// 關鍵:開啟 Schema 資料集
pRs = pConn->OpenSchema(adSchemaTables);
while (!pRs->EndOfFile) {
_bstr_t tableName = pRs->Fields->GetItem("TABLE_NAME")->Value;
_bstr_t tableType = pRs->Fields->GetItem("TABLE_TYPE")->Value;
CString strType((LPCTSTR)tableType);
if (strType == _T("TABLE")) { // 篩選使用者資料表
m_strList.AddString((LPCTSTR)tableName);
}
pRs->MoveNext();
}
pRs->Close(); pConn->Close();
}
catch (_com_error& e) {
PrintComError(e);
PrintProviderError(pConn);
}
::CoUninitialize();
}
void PrintProviderError(_ConnectionPtr pConn) {
if (pConn->Errors->Count > 0) {
for (long i = 0; i < pConn->Errors->Count; ++i) {
ErrorPtr pErr = pConn->Errors->GetItem(i);
CString msg; msg.Format(_T("Error 0x%X: %s"), pErr->Number, (LPCTSTR)pErr->Description);
AfxMessageBox(msg);
}
}
}
void PrintComError(_com_error& e) {
CString msg; msg.Format(_T("COM Error: %s (0x%X)"), e.ErrorMessage(), e.Error());
AfxMessageBox(msg);
}
void CMyDlg::OnBtnSelectMdb() {
TCHAR bigBuff[2048] = {0};
TCHAR szFilter[] = _T("Access Files (*.mdb)|*.mdb|All Files (*.*)|*.*||");
CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT, szFilter);
dlg.m_ofn.lpstrFile = bigBuff;
dlg.m_ofn.nMaxFile = 2048;
if (dlg.DoModal() == IDOK) {
m_strList.ResetContent();
OpenSchemaX(dlg.GetPathName());
}
}
LRESULT CMyDlg::WindowProc(UINT msg, WPARAM wp, LPARAM lp) {
if (msg == WM_CLOSE) ::CoUninitialize();
return CDialog::WindowProc(msg, wp, lp);
}
| 環節 | 關鍵代碼/設定 |
|---|---|
| ADO 導入 | `#import "msado15.dll" rename("EOF","EndOfFile")` |
| 連接字串 | `Provider=Microsoft.Jet.OLEDB.4.0;Data Source=xxx.mdb` |
| Schema 類型 | `adSchemaTables` (枚舉資料表) |
| 篩選條件 | `TABLE_TYPE == "TABLE"` (排除系統表/檢視/查詢) |
| 資源管理 | `CoInitialize`/`CoUninitialize` 配對,Recordset/Connection 及時 Close |
// 取得指定資料表的欄位清單
pRs = pConn->OpenSchema(adSchemaColumns,
vtMissing, vtMissing, _variant_t((LPCSTR)tableName));
while (!pRs->EndOfFile) {
_bstr_t colName = pRs->Fields->GetItem("COLUMN_NAME")->Value;
_bstr_t dataType = pRs->Fields->GetItem("DATA_TYPE")->Value;
// ...
pRs->MoveNext();
}
ADO `OpenSchema` 是獲取資料庫中繼資料的標準途徑,比直查 `MSysObjects` 更跨資料庫 (支援 SQL Server、Oracle 等)。掌握 `adSchemaTables`/`adSchemaColumns`/`adSchemaIndexes` 三大 Schema,即可構建通用的資料庫物件瀏覽器。