电竞比分网-中国电竞赛事及体育赛事平台

分享

兩種VC操縱EXCEL的方法

 蘇梅家家 2009-09-17
第一種方法,簡(jiǎn)單的,用CDatabase實(shí)現(xiàn). 程序是一個(gè)基于對(duì)話(huà)框的,步驟:    A,為了避免代碼重復(fù),設(shè)置下面幾個(gè)全局變量(類(lèi)范圍的),要引入頭文件<afxdb.h>
              CDatabase m_db;                     //數(shù)據(jù)庫(kù)
             CString m_dbdriver;                 //要生成的EXCEL文件的目錄
             char m_path[MAX_PATH];       //獲取路徑用的數(shù)組
               CString m_strdir;                      //包括EXCEL文件名在內(nèi)的路徑名.
               CString m_strsql;                    //SQL命令語(yǔ)句,用m_db可直接執(zhí)行.
B,在OnInitDialog方法中,生成一個(gè)xls文件,并插入兩條記錄,可在TRY語(yǔ)句中進(jìn)行,因?yàn)檫@里面要?jiǎng)?chuàng)建一張表,當(dāng)再次啟動(dòng)程序時(shí),會(huì)有異常發(fā)生,說(shuō)表已經(jīng)存在了,這時(shí)就避免了重復(fù)創(chuàng)建和插入.代碼如下:
m_dbdriver="MICROSOFT EXCEL DRIVER (*.XLS)";
GetCurrentDirectory(MAX_PATH,m_path);
m_strdir=m_path;
m_strdir+="http://test.xls";             //上面初始化各個(gè)變量.
m_strsql.Format("DRIVER={%s};DSN='''';FIRSTROWHASNAMES=1;READONLY=FALSE;CREATE_DB=\"%s\";DBQ=%s",m_dbdriver,m_strdir,m_strdir);
TRY
{
  if (m_db.OpenEx(m_strsql,CDatabase::noOdbcDialog))
  {
   m_strsql="Create Table OdbcExl(Name Text,Age Number,Gener Text)";
   m_db.ExecuteSQL(m_strsql);
   m_strsql="Insert Into OdbcExl(Name,Age,Gener) Values('Bob',34,'Male')";
   m_db.ExecuteSQL(m_strsql);
   m_strsql="Insert Into OdbcExl(Name,Age,Gener) Values('Jane',23,'Female')";
   m_db.ExecuteSQL(m_strsql);
   m_db.Close();
  }

}
CATCH_ALL(e)
{
// e->ReportError();
  m_db.Close();
  return FALSE;
}
END_CATCH_ALL;
C,其實(shí)上面已經(jīng)達(dá)到了答題人的要求,但作為一個(gè)程序,這也太不像話(huà)了,于是我又稍微加了點(diǎn)不值一提的東西,在對(duì)話(huà)框上輸入信息,再插入到EXCEL表中去,這一切都在按下"插入"按鈕后發(fā)生:
UpdateData();
m_strsql.Format("DRIVER={%s};DSN='''';FIRSTROWHASNAMES=1;READONLY=FALSE;CREATE_DB=\"%s\";DBQ=%s", m_dbdriver,m_strdir,m_strdir);
TRY
{
  if (m_db.OpenEx(m_strsql,CDatabase::noOdbcDialog))
  {
   m_strsql.Format("Insert into OdbcExl(Name,Age,Gener)Values('%s',%d,'%s')",m_name,m_age,m_gener);
   m_db.ExecuteSQL(m_strsql);
  }
}
CATCH_ALL(e)
{
  e->ReportError();
// db.Close();
}
END_CATCH_ALL;
m_db.Close();
可以說(shuō),只要對(duì)CDatabase稍有了解,對(duì)SQL語(yǔ)句稍有了解,這個(gè)問(wèn)題就很容易解決,如果要說(shuō)這是一個(gè)針對(duì)Excel文件操作的方法,那是因?yàn)樵贠penEx初始化數(shù)據(jù)庫(kù)對(duì)象(不是"打開(kāi)"哦)時(shí)用的文件后綴名為.xls而已,我們可以像在普通的數(shù)據(jù)庫(kù)中一樣進(jìn)行其他操作,如用SELECT語(yǔ)句來(lái)讀取EXCEL文件的內(nèi)容等, 第一種方法完.
下面是第二種方法,這里涉及的原理要復(fù)雜一些了,傳說(shuō)中的OLE(對(duì)象鏈接與嵌入)技術(shù)在這里用上了,EXCEL.EXE作為一個(gè)組件服務(wù)器,應(yīng)用程序作為客戶(hù)端......,還是直接寫(xiě)過(guò)程吧,頭暈暈的,只能平鋪直述了.
A,從classwizard中add class處from type library,去office的安裝目錄下引入excel.exe(這是office 2003的選擇,其他版本都是用olb文件),服務(wù)器就算引入了,這時(shí)會(huì)彈出對(duì)話(huà)框,要求加入一些類(lèi),這些類(lèi)都是一些接口,里面有大量的方法,類(lèi)的對(duì)象表征著excel文件的一個(gè)個(gè)部分,常用的有這幾個(gè)_application,workbooks,_workbook,worksheets,_worksheet,Range,它們分別代表不同的意義._application代表了EXCEL服務(wù)器,workbooks表示整個(gè)Excel服務(wù)器(表現(xiàn)為一個(gè).xls文件)里所有的表,(可以通過(guò)"新建"得到多個(gè)表,即MDI程序里的一個(gè)視窗一樣,所有的視窗就是workbooks), _workbook就是一個(gè)表,相當(dāng)于MDI中的一個(gè)視窗, worksheets表示所有的表單,每個(gè)表都可能有很多表單(建立一個(gè)Excel文件之后,打開(kāi),可以看到有sheet1,sheet2等,所有這些sheetn就組成了worksheets), _worksheet就表示一個(gè)表單, range表示元素的集合. 搞清楚上面這幾個(gè)名詞的意思非常重要.
B,在dlg.h中聲明下面幾個(gè)變量:
_Application exlapp;   //組件服務(wù)器的各個(gè)classes
_Workbook wbk;
Workbooks wbks;
_Worksheet wht;
Worksheets whts;
LPDISPATCH lpDisp;
并在app.cpp的InitInstance方法中加入下面兩句AfxInitOle(); AfxEnableControlContainer();
C,這里我沒(méi)有像上面一樣完全用程序來(lái)生成一個(gè)Excel文件,而是在開(kāi)始時(shí)就在當(dāng)前目錄下生成了一個(gè)Excel文件,在對(duì)話(huà)框上我設(shè)置了兩個(gè)按鈕,下面是"顯示"按鈕的代碼:
//創(chuàng)建Excel服務(wù)器
if(!exlapp.CreateDispatch("Excel.Application"))
{
  AfxMessageBox("無(wú)法啟動(dòng)Excel服務(wù)器!");
  return;
}
COleVariant  avar((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
exlapp.SetVisible(TRUE);//使Excel可見(jiàn)
exlapp.SetUserControl(TRUE);//允許其它用戶(hù)控制Excel,否則Excel將一閃即逝.

//Open an excel file
char path[MAX_PATH];
GetCurrentDirectory(MAX_PATH,path);
CString strPath = path;
strPath += "[url=file://vcopexcel/]\\VCOpExcel[/url]";
wbks.AttachDispatch(exlapp.GetWorkbooks());

lpDisp=wbks.Open(strPath,
  avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar);

wbks.ReleaseDispatch();
exlapp.ReleaseDispatch();
D,與上面第一種方法一樣,可以插入記錄:
UpdateData();     //讀入數(shù)據(jù)
if (""==m_name)     //判斷名字輸入有效
{
  MessageBox("Please input a right name");
  return;
}
if (0>=m_age||100<=m_age)  //判斷年齡輸入有效
{
  MessageBox("Please input a right age");
  return;
}
char *p=strupr(_strdup(m_gener));
if (strcmp(p,"FEMALE")&&strcmp(p,"MALE")) //判斷性別輸入有效
{
  MessageBox("Please input a right gener");
  return;
}

Range range;
Range usedRange;
COleVariant  avar((long)DISP_E_PARAMNOTFOUND,VT_ERROR);

if(!exlapp.CreateDispatch("Excel.Application")) //啟動(dòng)服務(wù)器
{
  AfxMessageBox("無(wú)法啟動(dòng)Excel服務(wù)器!");
  return;
}
char path[MAX_PATH];
GetCurrentDirectory(MAX_PATH,path);
CString strPath = path;
strPath += "[url=file://vcopexcel/]\\VCOpExcel[/url]";
wbks.AttachDispatch(exlapp.GetWorkbooks());
lpDisp=wbks.Open(strPath,            //初始化.
  avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar);
wbk.AttachDispatch(lpDisp);
whts.AttachDispatch(wbk.GetWorksheets());
lpDisp=wbk.GetActiveSheet();
wht.AttachDispatch(lpDisp);



usedRange.AttachDispatch(wht.GetUsedRange());
range.AttachDispatch(usedRange.GetRows());
long iRowNum=range.GetCount();//已經(jīng)使用的行數(shù)
range.AttachDispatch(wht.GetCells());

range.SetItem(COleVariant(long(iRowNum+1)),COleVariant(long(1)),COleVariant(m_name));
range.SetItem(COleVariant(long(iRowNum+1)),COleVariant(long(2)),COleVariant(m_age));
range.SetItem(COleVariant(long(iRowNum+1)),COleVariant(long(3)),COleVariant(m_gener));

wbk.Save();
wbk.Close(avar,COleVariant(strPath),avar);
wbks.Close();
exlapp.Quit();
第二種方法完.


來(lái)自:http://blog.csdn.net/biblereader/archive/2006/06/26/834663.aspx

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多