山本ワールド
Windowsプログラミング
アルゴリズム Vitual C++ 2008/2013によるWin32/Win64 APIレベルのプログラム 基礎 Vitual C++ 2008/2013によるAPIレベルのプログラム(32/64bit) Wix3でインストーラーを作る Visual C++ 2008 Standard Editonによるフォームアプリケーションのプログラム(32/64bit) Vitual C++ 2008 Standard EditonによるAPIレベルのプログラム(32/64bit) Windows 7対応 Visual C++ 2008 ExpressによるAPIレベルのプログラム Visual C++ 2005 ExpressによるAPIレベルのプログラム Visual C++ Versiosn 5 BORLAND C++ Windowsプログラム全般 Excel VBA その他DDEを用いてExcelのセルの読み込み・書き込みをする。(32/64bit)
概要
DDEを使いExcelファイル(Excel 2010β)よりセルを読み込みセルに書き出すプログラムです。
起動後、メニュよりDDEデモ(D) データの読み込み・書き込み(S)を選択すると上記ダイアログボックスが表示されExcelファイル名・シート名、読み込みセルの範囲、書き込みセルおよび内容を入力してOKを押すとExcelが起動し、本プログラムのウィンドウにExcelのシートの内容が表示されます。またExcelには書き込みセルで指定した場所に書き込み内容が反映されます。
dde.cpp
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <stdio.h>
#include <tchar.h>
#include "resource.h"
HDDEDATA CALLBACK DdemlCallback(UINT, UINT, HCONV, HSZ, HSZ,HDDEDATA, ULONG_PTR, ULONG_PTR);
LRESULT CALLBACK inDlgProc(HWND, UINT, WPARAM, LPARAM);
BOOL InitApp(HINSTANCE); // ウィンドウクラス登録
BOOL InitInstance(HINSTANCE, int); // メインウィンドウ作成
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int DDE_INIT(HWND); // DDE初期化
int DDE_CONNECT(HWND); // ファイル・シートに接続
int DDE_DISCONNECT(HWND); // ファイル・シートと切断
int DDE_SetData(HWND); // セル書き込み
int DDE_GetData(HWND); // セル読み込み
bool cells(TCHAR* a1,int* r,int* c); // EXCELで使用するA1形式のセル番地をRC系列に変換する
void colmn_set(int x,TCHAR* s); // 列番号よりA1形式の列名を得る。
bool Excel_Set_Cell(DWORD ddeInst,HCONV hConv2,int r,int c,TCHAR* write_data); // Excelのセルに書き込む
bool Excel_Get_Cell(DWORD ddeInst,HCONV hConv2,int r,int c,TCHAR* szData,int sz); // Excelのセルを読み込む
HINSTANCE hInst; // アプリケーションインスタンス
TCHAR szClassName[] = TEXT("dde_test"); //ウィンドウクラス
DWORD ddeInst=0; // インタンス
HSZ hszService; //
HSZ hszTopic1; // ファイル名文字列ハンドル
HSZ hszTopic2; // シート名文字列ハンドル
HCONV hConv1; // ファイル名へのハンドル
HCONV hConv2; // シート名へのハンドル
TCHAR fname[MAX_PATH]; // Excel ファイル名
TCHAR sname[32]; // Excel シート名
TCHAR read_cell_top[32]; // 読み込みセル左上
TCHAR read_cell_bottom[32]; // 読み込みセル右下
TCHAR write_cell[32]; // 書き込みセル
TCHAR write_data[64]; // 書き込み内容
HWND hList; // リストビューハンドル
int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,LPSTR lpsCmdLine, int nCmdShow){
MSG msg;
if (!InitApp(hCurInst))
return FALSE;
if (!InitInstance(hCurInst, nCmdShow))
return FALSE;
BOOL b;
while ((b=GetMessage(&msg, NULL, 0, 0))!=0) {
if(b==-1) // エラー時に無限ループにならないようにする
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
BOOL InitApp(HINSTANCE hInst){
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = TEXT("DDEMENU");
wc.lpszClassName = (TCHAR*)szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
return (RegisterClassEx(&wc));
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){
HWND hWnd;
hInst = hInstance;
hWnd = CreateWindow(szClassName,
TEXT("DDE Excel Demo"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
if (!hWnd)
return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
int h;
int col_max;
int x;
TCHAR buf[64];
switch (msg) {
case WM_CREATE:
hList = CreateWindowEx(0,
WC_LISTVIEW, TEXT(""),
WS_CHILD | WS_VISIBLE | LVS_REPORT,
0, 0, 0, 0,
hWnd,
(HMENU)ID_LISTVIEW,
hInst,
NULL);
read_cell_top[0]=read_cell_bottom[0]=fname[0]=sname[0]=_T('\0');
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDM_END:
SendMessage(hWnd, WM_CLOSE, 0, 0);
break;
case IDM_START:
if(DialogBox(hInst, TEXT("INDLG"), hWnd, (DLGPROC)inDlgProc)==IDOK){
if((h=(int)ShellExecute(hWnd,TEXT("open"),fname,TEXT(""),TEXT(""),SW_SHOW))<=32){
_stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),TEXT("ShellExecute APIでエラーが発生しました。(0x%x)"),h);
MessageBox(hWnd, buf, TEXT("エラー"), MB_OK | MB_ICONERROR);
break;
}
SendMessage(hList,LVM_DELETEALLITEMS,0,0);
col_max=(int)SendMessage(ListView_GetHeader(hList),HDM_GETITEMCOUNT,0,0);
for(x=0;x<col_max;x++){
ListView_DeleteColumn(hList, 0);
}
if(ddeInst==0)
DDE_INIT(hWnd);
DDE_CONNECT(hWnd);
DDE_GetData(hWnd);
DDE_SetData(hWnd);
DDE_DISCONNECT(hWnd);
}
break;
}
break;
case WM_SIZE:
MoveWindow(hList, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
if(ddeInst)
if(DdeUninitialize(ddeInst) == 0)
MessageBox(hWnd, TEXT("DdeUninitialize"),TEXT( "エラー"), MB_OK | MB_ICONERROR); PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, msg, wParam, lParam));
}
return 0;
}
int DDE_INIT(HWND hWnd){
TCHAR buf[64];
UINT ret;
if((ret=DdeInitialize(&ddeInst, DdemlCallback, APPCMD_CLIENTONLY, 0)) != DMLERR_NO_ERROR){
_stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),TEXT("DdeInitialize APIでエラーが発生しました。(0x%x)"),ret);
MessageBox(hWnd, buf, TEXT("エラー"), MB_OK | MB_ICONERROR);
return -1;
}
return 0;
}
int DDE_CONNECT(HWND hWnd){
UINT ret;
TCHAR buf[64];
#ifdef UNICODE
hszService = DdeCreateStringHandle(ddeInst, TEXT("Excel"), CP_WINUNICODE);
hszTopic1 = DdeCreateStringHandle(ddeInst, fname, CP_WINUNICODE);
hszTopic2 = DdeCreateStringHandle(ddeInst, sname, CP_WINUNICODE);
#else
hszService = DdeCreateStringHandle(ddeInst, TEXT("Excel"), CP_WINANSI);
hszTopic1 = DdeCreateStringHandle(ddeInst, fname, CP_WINANSI);
hszTopic2 = DdeCreateStringHandle(ddeInst, sname, CP_WINANSI);
#endif
hConv1 = DdeConnect(ddeInst, hszService, hszTopic1, NULL);
if ((ret=DdeGetLastError(ddeInst)) != DMLERR_NO_ERROR) {
_stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),TEXT("DdeConnect(ブック) APIでエラーが発生しました。(0x%x)"),ret);
MessageBox(0, buf, TEXT("エラー"), MB_OK | MB_ICONERROR);
return -1;
}
hConv2 = DdeConnect(ddeInst, hszService, hszTopic2, NULL);
if ((ret=DdeGetLastError(ddeInst)) != DMLERR_NO_ERROR) {
_stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),TEXT("DdeConnect(シート) APIでエラーが発生しました。(0x%x)"),ret);
MessageBox(0, buf, TEXT("エラー"), MB_OK | MB_ICONERROR);
return -2;
}
return 0;
}
int DDE_DISCONNECT(HWND hWnd){
UINT ret;
TCHAR buf[64];
if (hConv1){
if(DdeFreeStringHandle(ddeInst, hszService) == 0)
MessageBox(hWnd, TEXT("DdeFreeStringHandle(Excel)"), TEXT("エラー"), MB_OK);
if(DdeFreeStringHandle(ddeInst, hszTopic1) == 0)
MessageBox(hWnd, TEXT("DdeFreeStringHandle(ブック)"), TEXT("エラー"), MB_OK);
if(DdeFreeStringHandle(ddeInst, hszTopic2) == 0)
MessageBox(hWnd, TEXT("DdeFreeStringHandle(シート)"), TEXT("エラー"), MB_OK);
if(DdeDisconnect(hConv1) == 0){
ret=DdeGetLastError(ddeInst);
_stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),TEXT("DdeDisconnect(ブック) APIでエラーが発生しました。(0x%x)"),ret);
MessageBox(hWnd, buf, TEXT("エラー"), MB_OK | MB_ICONERROR);
}
if(DdeDisconnect(hConv2) == 0){
ret=DdeGetLastError(ddeInst);
_stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),TEXT("DdeDisconnect(シート) APIでエラーが発生しました。(0x%x)"),ret);
MessageBox(hWnd, buf, TEXT("エラー"), MB_OK | MB_ICONERROR);
}
hConv1 = 0;
hConv2 = 0;
}
return 0;
}
bool Excel_Set_Cell(DWORD ddeInst,HCONV hConv2,int r,int c,TCHAR* write_data){
TCHAR write_cell[16];
HSZ hszMyTopic;
HDDEDATA hRet;
UINT err;
TCHAR buf[64];
_stprintf_s(write_cell,sizeof(write_cell)/sizeof(TCHAR),TEXT("R%iC%i"),r,c);
#if UNICODE
hszMyTopic = DdeCreateStringHandle(ddeInst, write_cell, CP_WINUNICODE);
hRet = DdeClientTransaction(
(LPBYTE)write_data,
int(_tcslen(write_data)+1)*sizeof(TCHAR) ,
hConv2,
hszMyTopic,
CF_UNICODETEXT,
XTYP_POKE,
10000,
NULL);
#else
hszMyTopic = DdeCreateStringHandle(ddeInst, write_cell, CP_WINANSI);
hRet = DdeClientTransaction(
(LPBYTE)write_data,
int(_tcslen(write_data)+1),
hConv2,
hszMyTopic,
CF_TEXT,
XTYP_POKE,
10000,
NULL);
#endif
if(!hRet && (err=DdeGetLastError(ddeInst)) != DMLERR_NO_ERROR){
_stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),TEXT("DdeClientTransaction(XTYP_POKE) %s %s %x"),write_cell,write_data,err);
MessageBox(0, buf, TEXT("エラー"), MB_OK);
return false;
}else if (hRet) {
DdeFreeStringHandle(ddeInst, hszMyTopic);
DdeFreeDataHandle(hRet);
}
return true;
}
int DDE_SetData(HWND hWnd){
int r,c;
if (!hConv1){
MessageBox(hWnd, TEXT("DdeInitializeが呼び出されていないかエラーが発生しております"), TEXT("エラー"), MB_OK | MB_ICONERROR);
return -1;
}
cells(write_cell,&r,&c);
Excel_Set_Cell(ddeInst,hConv2,r,c,write_data);
return 0;
}
bool Excel_Get_Cell(DWORD ddeInst,HCONV hConv2,int r,int c,TCHAR* szData,int sz){
HDDEDATA hRet;
HSZ hszMyTopic;
TCHAR szBuf[16];
UINT err;
TCHAR buf[64];
_stprintf_s(szBuf,sizeof(szBuf)/sizeof(TCHAR),TEXT("R%iC%i"),r,c);
#ifdef UNICODE
hszMyTopic = DdeCreateStringHandle(ddeInst, szBuf, CP_WINUNICODE);
hRet = DdeClientTransaction(NULL, 0, hConv2, hszMyTopic, CF_UNICODETEXT, XTYP_REQUEST,1000, NULL);
#else
hszMyTopic = DdeCreateStringHandle(ddeInst, szBuf, CP_WINANSI);
hRet = DdeClientTransaction(NULL, 0, hConv2, hszMyTopic, CF_TEXT,XTYP_REQUEST,1000, NULL);
#endif
if(!hRet && (err=DdeGetLastError(ddeInst)) != DMLERR_NO_ERROR){
_stprintf_s(buf,sz,TEXT("DdeClientTransaction(XTYP_REQUEST) %s 0x%x"),szBuf,err);
MessageBox(0 , buf,TEXT( "エラー"), MB_OK);
return false;
}else if (hRet){
DdeGetData(hRet, (LPBYTE)szData, sz, 0);
DdeFreeStringHandle(ddeInst, hszMyTopic);
DdeFreeDataHandle(hRet);
}
return true;
}
int DDE_GetData(HWND hWnd){
LV_ITEM item;
int x,y;
int col_max=0;
TCHAR szBuf[64];
TCHAR szData[64];
if(!hConv1){
MessageBox(hWnd, TEXT("DdeInitializeが呼び出されていないかエラーが発生しております"), TEXT("エラー"), MB_OK | MB_ICONERROR);
return -1;
}
int top_x,top_y;
int bottom_x,bottom_y;
cells(read_cell_top , &top_y, &top_x);
cells(read_cell_bottom, &bottom_y, &bottom_x);
LV_COLUMN lvcol;
lvcol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvcol.fmt = LVCFMT_LEFT;
lvcol.cx = 64;
lvcol.pszText = TEXT("行・列");
lvcol.iSubItem = 0;
ListView_InsertColumn(hList,0 , &lvcol);
for(x=top_x;x<=bottom_x;x++){
colmn_set(x,szBuf);
lvcol.pszText = szBuf;
lvcol.iSubItem = x - top_x+1;
ListView_InsertColumn(hList,x - top_x+1 , &lvcol);
}
for(y=top_y;y<=bottom_y;y++){
_stprintf_s(szBuf,sizeof(szBuf)/sizeof(TCHAR),TEXT("%i"),y);
item.mask = LVIF_TEXT | LVIF_PARAM;
item.pszText = szBuf;
item.iItem = y-top_y;
item.iSubItem = 0;
item.lParam = y-top_y;
ListView_InsertItem(hList, &item);
for(x=top_x;x<=bottom_x;x++){
Excel_Get_Cell(ddeInst,hConv2,y,x,szData,sizeof(szData)/sizeof(TCHAR));
item.mask = LVIF_TEXT;
item.pszText = szData;
item.iItem = y - top_y;
item.iSubItem = x - top_x+1;
ListView_SetItem(hList, &item);
}
}
return 0;
}
LRESULT CALLBACK inDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam){
OPENFILENAME o;
switch (msg) {
case WM_INITDIALOG:
SetWindowText(GetDlgItem(hDlg, IDC_EDIT1),read_cell_top);
SetWindowText(GetDlgItem(hDlg, IDC_EDIT2),read_cell_bottom);
SetWindowText(GetDlgItem(hDlg, IDC_EDIT3),fname);
SetWindowText(GetDlgItem(hDlg, IDC_EDIT4),sname);
SetWindowText(GetDlgItem(hDlg, IDC_EDIT5),write_cell);
SetWindowText(GetDlgItem(hDlg, IDC_EDIT6),write_data);
break;
case WM_COMMAND:
switch (LOWORD(wParam)){
case IDOK:
Edit_GetText(GetDlgItem(hDlg, IDC_EDIT1), read_cell_top, sizeof(read_cell_top)/sizeof(TCHAR));
Edit_GetText(GetDlgItem(hDlg, IDC_EDIT2), read_cell_bottom, sizeof(read_cell_bottom)/sizeof(TCHAR));
Edit_GetText(GetDlgItem(hDlg, IDC_EDIT3), fname, sizeof(fname)/sizeof(TCHAR));
Edit_GetText(GetDlgItem(hDlg, IDC_EDIT4), sname, sizeof(sname)/sizeof(TCHAR));
Edit_GetText(GetDlgItem(hDlg, IDC_EDIT5), write_cell, sizeof(write_cell)/sizeof(TCHAR));
Edit_GetText(GetDlgItem(hDlg, IDC_EDIT6), write_data, sizeof(write_data)/sizeof(TCHAR));
EndDialog(hDlg, IDOK);
return TRUE;
case IDC_REF:
ZeroMemory(&o,sizeof(o));
o.lStructSize=sizeof(o);
o.Flags=0;
o.Flags |= OFN_HIDEREADONLY;
o.lpstrFile=fname;
o.nMaxFile=sizeof(fname)/sizeof(TCHAR);
o.lpstrFilter=TEXT("xls\0\0");
o.nFilterIndex=1;
if(GetOpenFileName(&o)){
SetWindowText(GetDlgItem(hDlg, IDC_EDIT3),fname);
}
break;
case IDCANCEL:
EndDialog(hDlg, IDCANCEL);
return TRUE;
}
break;
}
return FALSE;
}
HDDEDATA CALLBACK DdemlCallback(UINT uType, UINT uFmt, HCONV hconv, HSZ hsz1, HSZ hsz2, HDDEDATA hdata, ULONG_PTR dwData1, ULONG_PTR dwData2){
return (HDDEDATA)NULL;
}
// EXCELで使用するA1形式のセル番地をRC系列に変換する
bool cells(TCHAR* a1,int* r,int* c){
TCHAR* p=a1;
*c=0;
*r=0;
TCHAR ch;
int t;
while(*p){
ch=*p;
if(_istupper(*p)){
t = ch - _T('A')+1;
*c = *c * 26 + t;
}else if(_istdigit(*p)){
t = ch - _T('0');
*r = *r * 10 + t;
}else{
return false;
}
++p;
}
if(256<*c)
return false;
return true;
}
// 列番号よりA1形式の列名を得る。
void colmn_set(int x,TCHAR* s){
int t1=x/26;
int t2=x % 26;
TCHAR* p=s;
if(t1>=1){
*p=_T('A')+t1-1;
++p;
}
*p=_T('A')+t2-1;
++p;
*p=_T('\0');
}
resource.h
#define IDM_END 100
#define IDM_START 110
#define IDC_STATIC 200
#define IDC_STATIC2 220
#define IDC_STATIC3 230
#define IDC_STATIC4 240
#define IDC_STATIC5 250
#define IDC_STATIC6 260
#define IDC_EDIT1 310
#define IDC_EDIT2 320
#define IDC_EDIT3 330
#define IDC_EDIT4 340
#define IDC_EDIT5 350
#define IDC_EDIT6 360
#define IDC_FILENAME 370
#define IDC_REF 380
#define ID_LISTVIEW 400
dde.rc
#include <windows.h>
#include "resource.h"
DDEMENU MENU
BEGIN
POPUP "DDEデモ(&D)"
BEGIN
MENUITEM "データの読み込み・書き込み(&S)", IDM_START
MENUITEM "プログラムの終了(&X)", IDM_END
END
END
INDLG DIALOGEX 0, 0, 375, 179
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Excel データ読み込み・書き込み"
FONT 9, "MS Pゴシック", 0, 0, 0x0
BEGIN
LTEXT "ファイル名",IDC_STATIC3,9,9,31,8
EDITTEXT IDC_EDIT3,15,19,293,12,ES_AUTOHSCROLL
DEFPUSHBUTTON "参照",IDC_REF,328,19,35,14
LTEXT "シート名",IDC_STATIC4,9,35,26,8
EDITTEXT IDC_EDIT4,15,45,293,12,ES_AUTOHSCROLL
LTEXT "読み取り範囲",IDC_STATIC,9,69,28,8
EDITTEXT IDC_EDIT1,15,79,32,12,ES_AUTOHSCROLL
LTEXT "~",IDC_STATIC2,55,79,8,8
EDITTEXT IDC_EDIT2,75,79,32,12,ES_AUTOHSCROLL
LTEXT "書き込みセル",IDC_STATIC5,9,95,48,8
EDITTEXT IDC_EDIT5,15,105,22,12,ES_AUTOHSCROLL
LTEXT "書き込み内容",IDC_STATIC6,9,124,48,8
EDITTEXT IDC_EDIT6,15,134,32,12,ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,250,154,50,14
PUSHBUTTON "キャンセル",IDCANCEL,311,154,50,14
END
Copyright (C) 2012 山本ワールド All Rights Reserved.