兩種VC操縱EXCEL的方法
A,為了避免程式碼重複,設定下面幾個全域性變數(類範圍的),要引入標頭檔案<afxdb.h>
CDatabase m_db; //資料庫
CString m_dbdriver; //要生成的EXCEL檔案的目錄
char m_path[MAX_PATH]; //獲取路徑用的陣列
CString m_strdir; //包括EXCEL檔名在內的路徑名.
CString m_strsql; //SQL命令語句,用m_db可直接執行.
B,在OnInitDialog方法中,生成一個xls檔案,並插入兩條記錄,可在TRY語句中進行,因為這裡面要建立一張表,當再次啟動程式時,會有異常發生,說表已經存在了,這時就避免了重複建立和插入.程式碼如下:
m_dbdriver="MICROSOFT EXCEL DRIVER (*.XLS)";
GetCurrentDirectory(MAX_PATH,m_path);
m_strdir=m_path;
m_strdir+="//test.xls"; //上面初始化各個變數.
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,其實上面已經達到了答題人的要求,但作為一個程式,這也太不像話了,於是我又稍微加了點不值一提的東西,在對話方塊上輸入資訊,再插入到EXCEL表中去,這一切都在按下"插入"按鈕後發生:
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();
可以說,只要對CDatabase稍有了解,對SQL語句稍有了解,這個問題就很容易解決,如果要說這是一個針對Excel檔案操作的方法,那是因為在OpenEx初始化資料庫物件(不是"開啟"哦)時用的檔案字尾名為.xls而已,我們可以像在普通的資料庫中一樣進行其他操作,如用SELECT語句來讀取EXCEL檔案的內容等, 第一種方法完.
下面是第二種方法,這裡涉及的原理要複雜一些了,傳說中的OLE(物件連結與嵌入)技術在這裡用上了,EXCEL.EXE作為一個元件伺服器,應用程式作為客戶端......,還是直接寫過程吧,頭暈暈的,只能平鋪直述了.
A,從classwizard中add class處from type library,去office的安裝目錄下引入excel.exe(這是office 2003的選擇,其他版本都是用olb檔案),伺服器就算引入了,這時會彈出對話方塊,要求加入一些類,這些類都是一些介面,裡面有大量的方法,類的物件表徵著excel檔案的一個個部分,常用的有這幾個_application,workbooks,_workbook,worksheets,_worksheet,Range,它們分別代表不同的意義._application代表了EXCEL伺服器,workbooks表示整個Excel伺服器(表現為一個.xls檔案)裡所有的表,(可以通過"新建"得到多個表,即MDI程式裡的一個視窗一樣,所有的視窗就是workbooks), _workbook就是一個表,相當於MDI中的一個視窗, worksheets表示所有的表單,每個表都可能有很多表單(建立一個Excel檔案之後,開啟,可以看到有sheet1,sheet2等,所有這些sheetn就組成了worksheets), _worksheet就表示一個表單, range表示元素的集合. 搞清楚上面這幾個名詞的意思非常重要.
B,在dlg.h中宣告下面幾個變數:
_Application exlapp; //元件伺服器的各個classes
_Workbook wbk;
Workbooks wbks;
_Worksheet wht;
Worksheets whts;
LPDISPATCH lpDisp;
並在app.cpp的InitInstance方法中加入下面兩句AfxInitOle(); AfxEnableControlContainer();
C,這裡我沒有像上面一樣完全用程式來生成一個Excel檔案,而是在開始時就在當前目錄下生成了一個Excel檔案,在對話方塊上我設定了兩個按鈕,下面是"顯示"按鈕的程式碼:
//建立Excel伺服器
if(!exlapp.CreateDispatch("Excel.Application"))
{
AfxMessageBox("無法啟動Excel伺服器!");
return;
}
COleVariant avar((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
exlapp.SetVisible(TRUE);//使Excel可見
exlapp.SetUserControl(TRUE);//允許其它使用者控制Excel,否則Excel將一閃即逝.
//Open an excel file
char path[MAX_PATH];
GetCurrentDirectory(MAX_PATH,path);
CString strPath = path;
strPath += "file://VCOpExcel/";
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(); //讀入資料
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")) //啟動伺服器
{
AfxMessageBox("無法啟動Excel伺服器!");
return;
}
char path[MAX_PATH];
GetCurrentDirectory(MAX_PATH,path);
CString strPath = path;
strPath += "file://VCOpExcel/";
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();//已經使用的行數
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();
相關推薦
兩種VC操縱EXCEL的方法
第一種方法,簡單的,用CDatabase實現. 程式是一個基於對話方塊的,步驟: A,為了避免程式碼重複,設定下面幾個全域性變數(類範圍的),要引入標頭檔案<afxdb.h> CDatabase m_db;
.Net MVC 導入導出Excel總結(三種導出Excel方法,一種導入Excel方法) 通過MVC控制器導出導入Excel文件(可用於java SSH架構)
ets esp llb pat lencod cnblogs 創建 etime mmd public class ExcelController : Controller { // // GET: /Excel/ M
兩種進入容器的方法 - 每天5分鐘玩轉 Docker 容器技術(23)
工作 技術 啟動進程 gin attach ant while col -c 我們經常需要進到容器裏去做一些工作,比如查看日誌、調試、啟動其他進程等。有兩種方法進入容器:attach 和 exec。 docker attach 通過 docker attach 可以 a
python兩種生成md5的方法
spa date hex clas pda upd hash tty digest 一. 使用md5包 import md5 src = ‘this is a md5 test.‘ m1 = md5.new() m1.update(src) print
python全棧脫產第34天------開啟進程的兩種方式、join方法、進程對象其他相關的屬性和方法、僵屍進程、孤兒進程、守護進程、互斥鎖
for roc -- don 操作 windows main 周期 僵屍 一、開啟進程的兩種方式 方式一: from multiprocessing import Processimport timedef task(name): print(‘%s is run
Servlet中的兩種接收請求的方法
首先說一下,dopost和doget兩種方法都是來接收使用者請求的。但是還是有以下幾種區別 get:提交的資料大小有所限制; 請求通過url位址列顯示 post:沒有大小的限制; 通過http請求附件傳送 (以下舉例在某頁面點選提交後的請求傳送過程) 第一步  
兩種介面重新整理的方法Invalidate(),postInvalidate()
原部落格 https://www.cnblogs.com/rayray/p/3437048.html Android中實現view的更新有兩組方法,一組是invalidate,另一組是postInvalidate,其中前者是在UI執行緒自身中使用,而後者在非UI執行緒中使用。 Andro
資料的兩種歸一化方法
資料標準化(歸一化)處理是資料探勘的一項基礎工作,不同評價指標往往具有不同的量綱和量綱單位,這樣的情況會影響到資料分析的結果,為了消除指標之間的量綱影響,需要進行資料標準化處理,以解決資料指標之間的可比性。原始資料經過資料標準化處理後,各指標處於同一數量級,適合進行綜合對比評價。 一般而言,
java中兩種轉換時間的方法
將String ->util date - > sql date 在學過mvc後,可以新建一個工具類,把轉換程式碼寫到util包中 public class DateUtil { private static SimpleDateFormat sdf = new Sim
【翻譯】學習兩種禁用IE的方法
Learn two ways to disable Internet Explorer學習兩種禁用IE的方法作者:Michael Mullins CCNA, MCP翻譯:endurer關鍵字:網頁瀏覽器 | 安全威脅 | 微軟Windows | 安全管理Takeaway: In
java兩種啟動執行緒方法根本不同,Thread繼承和實現Runable介面
java實現多執行緒有兩種方法 1、繼承Thread類,實現run方法 2、實現Runable介面,實現run方法 示例程式截圖(程式來自瘋狂java講義) 實現步驟 (1)定義Thread類的子類,並重寫該類的run()方法,該run()方法的方法體就代表了執行緒需要
Android兩種播放視訊的方法(SurfaceView、MediaPlayer、SeekBar)和(VideoView、MediaController)等兩種方法。
package com.example.android_playmusic;import android.media.MediaPlayer;import android.net.Uri;import android.support.v7.app.AppCompatActivity;import
fstream與 C 風格(例如fread 和 fwrite )兩種讀寫檔案方法的效率比較
為了探錄c++ 風格的fstream與 C 風格(例如fread 和 fwrite )兩種讀寫檔案的方法的效率,我特意做了兩個實驗。 我的機器是Windows XP, Visual Studio 2008 1. 測試寫檔案速度 程式設計思路: 將TEST_SIZE個
Eclipse/Myeclipse/Scala IDEA for Eclipse裡兩種新增外掛的方法(線上和離線)
不多說,直接上乾貨! 方法1:線上安裝 第一步,在eclipse選單欄下,選中help ---->Install New Software 第二步,點選圖中 add 新增軟體下載地址 第三步 ,選中需要的內容,安
Eclipse中SVN的安裝步驟(兩種)和使用方法
一、給Eclipse安裝SVN,最常見的有兩種方式:手動方式和使用安裝嚮導方式。具體步驟如下: 方式一:手動安裝 1、從官網下載site-1.6.9.zip檔案,網址是:subclipse.tigris.org2、從中解壓出features與plugins資料夾,複製到E
C# 兩種啟動bat檔案方法的區別——關鍵在於程序的工作目錄
1、 private void RunBat(string batPath) { Process pro = new Process(); FileInfo file = new FileInfo(batPath); pro.StartInfo.Work
jsgrid 和 grid 兩種加easyui的方法
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Basic DataGrid - jQuery EasyUI Demo</title> <
insert into 的兩種表複製插入方法
insert into 語句除了基本的 insert into 表名(a,b,c)values(a1,b1,c1)外 。 還有更進一步的,從一個表複製其中全部欄位資料或者是部分欄位資料插入到另一個表中的用法。 有兩種方式可以實現,insert into select
Android 載入html,兩種新增Cookies的方法!
方式一: public void synCookies(Context context, String url) { CookieSyncManager.createInstance(context); CookieManager coo
iOS常用的兩種延時的方法
//1 [selfperformSelector:@selector(obj:) withObject:@"可傳引數"afterDelay:3]; //2 程式碼直接bl