병렬 Process를 적용 하자.

 

a) for문 구성을 간단하게 Multi Thread와 같은 형태로 변환해준다.(병렬 프로그래밍)

- 8Thread CPU에서 4개를 사용할 경우에 속도 향상이 가장 좋아 4개로 기준 한다.(여러가지 요건에 의해 바뀔 수 있음)

b) 임의로 분리 수를 조절 할 수 있다.

c) 아주 간단하게 반복문의 정보 처리를 빠르게 할 수 있다.

 

* Window 자원요소등에 접근해야 할 경우 주의를 요한다.(로컬 변수 형태로 Object를 관리해줘야 한다)

 (직접 작성 코드에 대한 병렬화에 매우 좋은 효과를 기대 할 수 있다)

* GPU가 아닌 CPU자원을 사용하는 것이다 *^^;;

 

1) 설정.

Open MP를 사용하기 위한 설정

 

 

2) 기본 코드

		int nThAllCht =  OMP_TH_CNT;//(4)// omp_get_num_threads();
		omp_set_num_threads(nThAllCht);
#pragma omp parallel//윈도우즈용 비주얼 스튜디오는 알아서 컴파일 해준다.
		{
            //이하 코드는 For문을 각 Thread에게 공통적으로 분배 해주는 역할을 한다.
            // 1003개의 Data를 4개의 Thread가 처리 한다면.
            //1번 250개, 2번 250개, 3번 250개, 4번 250 + 3(나머지)를 처리 한다.
			int nListCnt = nReadFileCnt;//for문을 돌릴 총 수
			int nThCnt = omp_get_max_threads();
			int nThNum = omp_get_thread_num();

			int nJump = nListCnt / nThCnt;
			int nJumpN = nListCnt % nThCnt;

			int nStartIndex = (nThNum*nJump);
			int nTailAddCnt = 0;
			if (nThCnt == (nThNum + 1))//nThNum이 Zero Index임으로.
				nTailAddCnt = nJumpN;

			for (int iF = nStartIndex; iF < (nStartIndex + nJump + nTailAddCnt); iF++)
			//for (int iF = 0; iF < nReadFileCnt; iF++)//원본 For문
			{
            ...//반복 수행 코드.
            }
  #pragma omp barrier //모든 Thread가 여기에 도착 하도록 기다린다.
		}

1) 파일명에 특수(%)등이 포함된 문자열을 TRACE로 찍으면 에러가 난다.

 - File명에는 "%"문자가 들어갈 수 있다.(오류메시지가 안나고 그냥 죽는다).


2) CTime Obj는 1970년 이전 설정시 DebugMessage가 뜬다.

   int nYYYY = 1970;

 - CTime cTimeX(nYYYY, nMM, nDD, 0, 0, 0);//Debug Message가 출력되며 죽는다.

여러 군대 찾아도 정보가 미흡하여,  사용 가능하게 정리하였습니다.

 - XLEzAutomation이나 ExcelLib의 기능에 원하는 기능 구현이 없고 수정 추가에도 어려움이 있어서...

 - 잘 활용하시기 바랍니다.

 

Excel 컨트롤 클래스 만들기.

(필요할 때마다 하나씩 추가 하자~~~~)

구현 기능

1 파일 열기,

2 파일 닫기,

3 다른이름 저장,

4 값 일기,

5 값 쓰기,

6 이미지 저장하기(클립보드, 절대 경로 Link, Link를 이용한 포함시키기)

7 Sheet Active 시키기.

 

미구현 기능

8 차트 만들기.

9 Sheet이름 바꾸기.

10 범용 알고리즘 콜하기.

 

추가된 Excel File들은 복사하여 다른 프로젝트에 Link를 걸고 그대로 사용 가능하다.

(MFC에서 Excel 컨트롤 하기(1)을 매 프로젝트에 추가할 필요는 없다)

#include "CApplication.h"//
#include "CWorkbook.h"//
#include "CWorkbooks.h"//

#include "CWorksheet.h"//
#include "CWorksheets.h"//


#include "CChart.h"//
#include "CCharts.h"//

#include "CBorder.h"//
#include "CBorders.h"//

#include "CPicture.h"//
#include "CPictures.h"//

#include "CRange.h"//
#include "CFont0.h"//

#include "CShapes.h"
#include "CShape.h"

 

 

구현 해더 파일.(ExcelCtrl.h)

#pragma once

#include "CApplication.h"//
#include "CWorkbook.h"//
#include "CWorkbooks.h"//

#include "CWorksheet.h"//
#include "CWorksheets.h"//


#include "CChart.h"//
#include "CCharts.h"//

#include "CBorder.h"//
#include "CBorders.h"//

#include "CPicture.h"//
#include "CPictures.h"//

#include "CRange.h"//
#include "CFont0.h"//

#include "CShapes.h"
#include "CShape.h"

static CString ColToColLetter(int colIndex)
{
	int div = colIndex;
	CString colLetter;// = String.Empty;
	int mod = 0;

	while (div > 0)
	{
		mod = (div - 1) % 26;
		colLetter = (char)(65 + mod) + colLetter;
		div = (int)((div - mod) / 26);
	}
	return colLetter;
}
static int ColLetterToColIndex(CString columnLetter)
{
	columnLetter = columnLetter.MakeUpper();
	int sum = 0;

	for (int i = 0; i < columnLetter.GetLength(); i++)
	{
		sum *= 26;
		sum += (columnLetter[i] - L'A' + 1);
	}
	return sum;
}

class CExcelCtrl
{
public:
	CExcelCtrl();
	~CExcelCtrl();

private:
	// spreadsheet variables
	CApplication	m_app;
	CWorkbook		m_book;
	CWorkbooks		m_books;


	CWorksheets		m_worksheets;


	COleVariant		m_covTrue;
	COleVariant		m_covFalse;
	COleVariant		m_covOptional;

	CString			m_strOpenFile;


private:
	void CloseWorkbook();
public:
	//1) File 열고 닫기.
	bool OpenFile(CString strFilePath);
	bool CloseFile();
	bool SaveFile();
	bool SaveAsFile(CString newFullPath);
	//2) Data 읽고 쓰기.
	CString GetValue(int nSheet, CString strCellPos);//CellPos :"A1", "O21"
	void SetValue(int nSheet, CString strCellPos, CString strNewValue);
	//3) Image 삽입.
	void SetPasteClipboard(int nSheet, CString strCellPos, double fViewSizeW = 0.0, double fViewSizeH = 0.0);//클립 보드의 이미지 삽입
	void SetPasteFileLink(int nSheet, CString strCellPos, CString strImgPath, double fViewSizeW = 0.0, double fViewSizeH = 0.0);//주어진 이미지 절대 경로를 삽입.(경로만)
	void SetFileLinkAndAdd(int nSheet, CString strCellPos, CString strImgPath, int orgW, int orgH, double fViewSizeW = 0.0, double fViewSizeH = 0.0);//경로의 파일을 삽입.(Excel File에 첨부)

	void SetActiveSheet(int nSheet);
};

 

구현 소스파일(ExcelCtrl.cpp)

#include "stdafx.h"
#include "ExcelCtrl.h"
#define rmm     23
CExcelCtrl::CExcelCtrl():
	m_app(nullptr),
	m_book(nullptr),
	m_books(nullptr),
	m_covTrue((short)TRUE),
	m_covFalse((short)TRUE),
	m_covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR)

{
	try
	{
		OleUninitialize(); //프로젝트 내 다른  COM이 초기화해 놓은 것을 죽여 놓으
		DWORD dwOleVer;

		dwOleVer = CoBuildVersion();

		// check the OLE library version
		if (rmm != HIWORD(dwOleVer))
		{
			MessageBox(NULL, _T("Incorrect version of OLE libraries."), L"Failed", MB_OK | MB_ICONSTOP);
			return;
		}

		// could also check for minor version, but this application is
		// not sensitive to the minor version of OLE

		// initialize OLE, fail application if we can't get OLE to init.
		if (FAILED(OleInitialize(NULL)))
		{
			MessageBox(NULL, _T("Cannot initialize OLE."), L"Failed", MB_OK | MB_ICONSTOP);
			return;
		}

		if (!m_app.CreateDispatch(L"Excel.Application"))
		{
			AfxMessageBox(L"Could not start Excel.");
			return;
		}
		m_app.put_DisplayAlerts(VARIANT_FALSE);
		m_app.put_UserControl(FALSE);
	}
	catch (CMemoryException* e)
	{
		CMemoryException* ep = e;
		AfxMessageBox(L"CMemoryException Could not clean up workbook.");
	}
	catch (CFileException* e)
	{
		CFileException* pe = e;
		AfxMessageBox(L"CFileException Could not clean up workbook.");
	}
	catch (CException* e)
	{
		CException* pe = e;
		AfxMessageBox(L"CException Could not clean up workbook.");
	}
}
CExcelCtrl::~CExcelCtrl()
{
	CloseFile();
	OleUninitialize();
	OleInitialize(NULL);  //프로젝트 내 다른 COM을 위한 센스
}
bool CExcelCtrl::OpenFile(CString strFilePath)
{
	m_strOpenFile.Format(L"%s", strFilePath);
	// close already-opened workbook
	CloseWorkbook();
	bool retV = false;
	try
	{
		// Get Workbooks collection.
		LPDISPATCH lpDisp;
		lpDisp = m_app.get_Workbooks();  // Get an IDispatch pointer
		ASSERT(lpDisp);
		m_books.AttachDispatch(lpDisp);  // Attach the IDispatch pointer to the books object.

		// open the document

		lpDisp = m_books.Open(m_strOpenFile.GetBuffer(m_strOpenFile.GetLength()),
			m_covOptional, m_covOptional, m_covOptional, m_covOptional,
			m_covOptional, m_covOptional, m_covOptional, m_covOptional,
			m_covOptional, m_covOptional, m_covOptional, m_covOptional,
			m_covOptional, m_covOptional);

		ASSERT(lpDisp);

		//Set CWorkbook to use lpDisp, the IDispatch* of the actual workbook.
		m_book.AttachDispatch(lpDisp);
		//WorkSheets Link.
		m_worksheets = m_book.get_Sheets();

		retV = true;
	}
	catch (CMemoryException* e)
	{
		CMemoryException* ep = e;
		AfxMessageBox(L"CMemoryException Could not clean up workbook.");
	}
	catch (CFileException* e)
	{
		CFileException* pe = e;
		AfxMessageBox(L"CFileException Could not clean up workbook.");
	}
	catch (CException* e)
	{
		CException* pe = e;
		AfxMessageBox(L"CException Could not clean up workbook.");
	}
	return retV;
}

bool CExcelCtrl::CloseFile()
{
	bool retV = false;
	CloseWorkbook();
	try
	{
		m_app.Quit();
		m_app.ReleaseDispatch();
		retV = true;
	}
	catch (CMemoryException* e)
	{
		CMemoryException* ep = e;
		AfxMessageBox(L"CMemoryException Could not clean up workbook.");
	}
	catch (CFileException* e)
	{
		CFileException* pe = e;
		AfxMessageBox(L"CFileException Could not clean up workbook.");
	}
	catch (CException* e)
	{
		CException* pe = e;
		AfxMessageBox(L"CException Could not clean up workbook.");
	}
	return retV;
}
bool CExcelCtrl::SaveFile()
{
	bool retV = false;
	if (m_app == nullptr || m_books == nullptr || m_book == nullptr)
		return retV;
	try
	{
		m_book.Save();
		retV = true;
	}
	catch (CMemoryException* e)
	{
		CMemoryException* ep = e;
		AfxMessageBox(L"CMemoryException Could not clean up workbook.");
	}
	catch (CFileException* e)
	{
		CFileException* pe = e;
		AfxMessageBox(L"CFileException Could not clean up workbook.");
	}
	catch (CException* e)
	{
		CException* pe = e;
		AfxMessageBox(L"CException Could not clean up workbook.");
	}

	return retV;
}
bool CExcelCtrl::SaveAsFile(CString newFullPath)
{
	bool retV = false;
	if (m_app == nullptr || m_books == nullptr || m_book == nullptr)
		return false;
	try
	{
		//51 = xlOpenXMLWorkbook(without macro's in 2007-2016, xlsx)
		//52 = xlOpenXMLWorkbookMacroEnabled(with or without macro's in 2007-2016, xlsm)
		//50 = xlExcel12(Excel Binary Workbook in 2007 - 2016 with or without macro's,xlsb)
		//56 = xlExcel8(97 - 2003 format in Excel 2007 - 2016, xls)
		int nPos  = newFullPath.ReverseFind(L'.');
		CString strExeName;
		strExeName.Format(L"%s", newFullPath.Mid(nPos+1));
		//strExeName.MakeUpper();
		long nFileCode = 51;
		if (strExeName.CompareNoCase(L"xlsm") == 0)
			nFileCode = 52;

		m_book.SaveAs(
			COleVariant(newFullPath.GetBuffer(newFullPath.GetLength())),
			COleVariant(nFileCode),//file format
			m_covOptional,//COleVariant(_T(""), // password
			m_covOptional,//COleVariant(_T(""), VT_BSTR), //readonly
			m_covOptional,//covFalse, 
	  //createbackup
			m_covOptional,//covFalse, 
	  //accessmode
			1,
			m_covOptional,//COleVariant((long) 1),  
			m_covOptional,
			m_covOptional,
			m_covOptional, m_covOptional);

		retV = true;
	}
	catch (CMemoryException* e)
	{
		CMemoryException* ep = e;
		AfxMessageBox(L"CMemoryException Could not clean up workbook.");
	}
	catch (CFileException* e)
	{
		CFileException* pe = e;
		AfxMessageBox(L"CFileException Could not clean up workbook.");
	}
	catch (CException* e)
	{
		CException* pe = e;
		AfxMessageBox(L"CException Could not clean up workbook.");
	}
	return retV;
}
void CExcelCtrl::CloseWorkbook()
{
	try
	{
		m_worksheets.ReleaseDispatch();
		// close already-opened workbook
		m_book.ReleaseDispatch();
		m_books.Close();
		m_books.ReleaseDispatch();
	}
	catch (CMemoryException* e)
	{
		CMemoryException* ep = e;
		AfxMessageBox(L"CMemoryException Could not clean up workbook.");
	}
	catch (CFileException* e)
	{
		CFileException* pe = e;
		AfxMessageBox(L"CFileException Could not clean up workbook.");
	}
	catch (CException* e)
	{
		CException* pe = e;
		AfxMessageBox(L"CException Could not clean up workbook.");
	}
}

CString CExcelCtrl::GetValue(int nSheet, CString strCellPos)
{
	if (nSheet < 1 || m_app == nullptr)
		return CString(L"");
	
	CString szValue;
	try
	{
		// sheet 생성, 연결 (1번 시트)
		CWorksheet sheet;
		sheet = m_worksheets.get_Item(COleVariant((short)nSheet));
		sheet.Activate();
		// range 생성, 연결
		CRange range;
		range.AttachDispatch(sheet.get_Cells(), true);

		range = sheet.get_Range(COleVariant(strCellPos.GetBuffer(strCellPos.GetAllocLength())), m_covOptional);
		range.Select();
		//------------------------------------------------------
		COleVariant vargValue = range.get_Value2();
		switch (vargValue.vt)
		{
		case VT_UI1:
		{
			unsigned char nChr = vargValue.bVal;
			//szValue = nChr;
			szValue.Format(L"%d", nChr);// = nChr;
		}
		break;
		case VT_I4:
		{
			long nVal = vargValue.lVal;
			szValue.Format(L"%i", nVal);
		}
		break;
		case VT_R4:
		{
			float fVal = vargValue.fltVal;
			szValue.Format(L"%f", fVal);
		}
		break;
		case VT_R8:
		{
			double dVal = vargValue.dblVal;
			szValue.Format(L"%f", dVal);
		}
		break;
		case VT_BSTR:
		{
			BSTR b = vargValue.bstrVal;
			szValue = b;
		}
		break;
		case VT_BYREF | VT_UI1:
		{
			//Not tested
			unsigned char* pChr = vargValue.pbVal;
			//					szValue = *pChr;
			szValue.Format(L"%f", *pChr);
		}
		break;
		case VT_BYREF | VT_BSTR:
		{
			//Not tested
			BSTR* pb = vargValue.pbstrVal;
			szValue = *pb;
		}
		case 0:
		{
			//Empty
			szValue = _T("");
		}

		break;
		}
		//------------------------------------------------------
		range.ReleaseDispatch();
		sheet.ReleaseDispatch();
	}
	catch (CMemoryException* e)
	{
		CMemoryException* ep = e;
		AfxMessageBox(L"CMemoryException Could not clean up workbook.");
	}
	catch (CFileException* e)
	{
		CFileException* pe = e;
		AfxMessageBox(L"CFileException Could not clean up workbook.");
	}
	catch (CException* e)
	{
		CException* pe = e;
		AfxMessageBox(L"CException Could not clean up workbook.");
	}
	return szValue;
}
void CExcelCtrl::SetValue(int nSheet, CString strCellPos, CString strNewValue)
{
	if (nSheet < 1 || m_app == nullptr)
		return;

	try
	{
		// sheet 생성, 연결 (1번 시트)
		CWorksheet sheet;
		sheet = m_worksheets.get_Item(COleVariant((short)nSheet));
		sheet.Activate();
		// range 생성, 연결
		CRange range;
		range.AttachDispatch(sheet.get_Cells(), true);

		range = sheet.get_Range(COleVariant(strCellPos.GetBuffer(strCellPos.GetAllocLength())), m_covOptional);
		range.Select();
		//------------------------------------------------------
		//Data 쓰기.
		range.put_Value2(COleVariant(strNewValue));
		//------------------------------------------------------
		range.ReleaseDispatch();
		sheet.ReleaseDispatch();
	}
	catch (CMemoryException* e)
	{
		CMemoryException* ep = e;
		AfxMessageBox(L"CMemoryException Could not clean up workbook.");
	}
	catch (CFileException* e)
	{
		CFileException* pe = e;
		AfxMessageBox(L"CFileException Could not clean up workbook.");
	}
	catch (CException* e)
	{
		CException* pe = e;
		AfxMessageBox(L"CException Could not clean up workbook.");
	}
}

void CExcelCtrl::SetActiveSheet(int nSheet)
{
	if (nSheet < 1 || m_app == nullptr)
		return;
	CWorksheet sheet;
	sheet = m_worksheets.get_Item(COleVariant((short)nSheet));
	sheet.Activate();
}
void CExcelCtrl::SetPasteClipboard(int nSheet, CString strCellPos,  double fViewSizeW , double fViewSizeH)
{
	if (nSheet < 1 || m_app == nullptr)
		return;
	CWorksheet sheet;
	CRange range;
	CPicture pic;
	CPictures pics;
	//CBorder border;

	sheet = m_worksheets.get_Item(COleVariant((short)nSheet));
	pics = sheet.Pictures(m_covOptional);
	sheet.Activate();
	// insert first picture and put a border on it
	range = sheet.get_Range(COleVariant(strCellPos.GetBuffer(strCellPos.GetAllocLength())), m_covOptional);
	range.Select();

	
	//링크 집어넣기
	//pic = pics.Insert(strLoadImgPath.GetBuffer(strLoadImgPath.GetLength()), covOptional);
	//붙여넣기
	sheet.Activate();
	pic = pics.Paste(m_covOptional);

	VARIANT varL = range.get_Left();
	VARIANT varT = range.get_Top();
	VARIANT varW = range.get_Width();
	VARIANT varH = range.get_Height();

	double l = varL.dblVal + 2.0;
	double t = varT.dblVal + 2.0;
	double w = varW.dblVal;
	double h = varH.dblVal;
	//Sheet 에서 위치 지정.
	pic.put_Left(l);
	pic.put_Top(t);
	pic.put_Locked(FALSE);
	//크기 지정.
	if (fViewSizeW > 0.0 )//&& fViewSizeH > 0.0)
	{
		pic.put_Width(fViewSizeW);
		//pic.put_Height(fViewSizeW);
	}
	pic.put_Visible(TRUE);

	
	//VARIANT Replace;
	//pic.Select(Replace);
	//m_book.Save();
	pic.ReleaseDispatch();
	pics.ReleaseDispatch();
	range.ReleaseDispatch();
	sheet.ReleaseDispatch();
}
void CExcelCtrl::SetPasteFileLink(int nSheet, CString strCellPos, CString strImgPath, double fViewSizeW, double fViewSizeH)
{
	if (nSheet < 1 || m_app == nullptr || strImgPath.GetLength()<3)
		return;
	CWorksheet sheet;
	CRange range;
	CPicture pic;
	CPictures pics;
	//CBorder border;

	sheet = m_worksheets.get_Item(COleVariant((short)nSheet));
	sheet.Activate();

	pics = sheet.Pictures(m_covOptional);
	// insert first picture and put a border on it
	// 링크 집어넣기
	range = sheet.get_Range(COleVariant(strCellPos.GetBuffer(strCellPos.GetAllocLength())), m_covOptional);
	range.Select();
	VARIANT varL = range.get_Left();
	VARIANT varT = range.get_Top();
	VARIANT varW = range.get_Width();
	VARIANT varH = range.get_Height();

	double l = varL.dblVal + 2.0;
	double t = varT.dblVal + 2.0;
	double w = varW.dblVal;
	double h = varH.dblVal;

	sheet.Activate();
	pic = pics.Insert(strImgPath.GetBuffer(strImgPath.GetLength()), m_covOptional);
	//붙여넣기
	//range = sheet.get_Range(COleVariant(strCellPos.GetBuffer(strCellPos.GetAllocLength())), m_covOptional);
	//range.Select();
	//pic = pics.Paste(m_covOptional);


	//Sheet 에서 위치 지정.
	pic.put_Left(l);
	pic.put_Top(t);

	//크기 지정.
	if (fViewSizeW > 0.0)//&& fViewSizeH > 0.0)
	{
		pic.put_Width(fViewSizeW);
		//pic.put_Height(fViewSizeW);
	}

	pic.ReleaseDispatch();
	pics.ReleaseDispatch();


	//m_book.Save();
	range.ReleaseDispatch();
	sheet.ReleaseDispatch();
}

void CExcelCtrl::SetFileLinkAndAdd(int nSheet, CString strCellPos, CString strImgPath, int orgW, int orgH, double fViewSizeW, double fViewSizeH)
{
	if (nSheet < 1 || m_app == nullptr || strImgPath.GetLength() < 3)
		return;
	CWorksheet sheet;
	CRange range;
	CPicture pic;
	CPictures pics;
	//CBorder border;

	sheet = m_worksheets.get_Item(COleVariant((short)nSheet));
	sheet.Activate();
	range = sheet.get_Range(COleVariant(strCellPos.GetBuffer(strCellPos.GetAllocLength())), m_covOptional);
	range.Select();
	VARIANT varL = range.get_Left();
	VARIANT varT = range.get_Top();
	VARIANT varW = range.get_Width();
	VARIANT varH = range.get_Height();

	double l = varL.dblVal + 2.0;
	double t = varT.dblVal + 2.0;
	double w = varW.dblVal;
	double h = varH.dblVal;

	CShapes  objShapes;
	CShape   objShape;
	objShapes = sheet.get_Shapes();
	objShape = objShapes.AddPicture(strImgPath, // Filename
		(long)0,    // LinkToFile
		(long)-1,	// SaveWithDocument
		(float)l,	// Left
		(float)t,   // Top
		(float)orgW,  // Width
		(float)orgH); // Height

	if (fViewSizeW > 0.0 && fViewSizeH > 0.0)
	{
		objShape.put_Width((float)fViewSizeW);
		objShape.put_Height((float)fViewSizeH);
	}
	if (objShapes.m_lpDispatch)
		objShapes.ReleaseDispatch();
	if (objShape.m_lpDispatch)
		objShape.ReleaseDispatch();

	range.ReleaseDispatch();
	sheet.ReleaseDispatch();
}

여러 군대 찾아도 정보가 미흡하여, 사용 가능하게 정리하였습니다.

- XLEzAutomation이나 ExcelLib의 기능에 원하는 기능 구현이 없고 수정 추가에도 어려움이 있어서...

- 잘활용 하시기 바랍니다.

 

프로젝트에 Excel Object Header File 넣기.

 

1) 프로젝트 -> 새 항목 추가-> MFC -> TypeLib의 MFC 클래스 선택.

2) 파일-> ...  선택 설치되어있는 Excel EXE(실행파일을 선택하기 위해)

3) 일반적인 설치 경로를 찾아 EXCEL.EXE를 선택한다.(Office 2016 버전 사용時"C:\Program Files\Microsoft Office\Office16\EXCEL.EXE")

4) 하단 왼쪽 항목에서 필요로 하는 파일(Class Header)을 선택한다.

오른쪽에 추가된 것이 Class File Name이 된다.

CApplication.h

CBorder.h

CBorders.h
CChart.h

CCharts.h

CFont0.h

CPicture.h

CPictures.h

CRange.h

CRanges.h

CShape.h

CShapes.h

CWorkbook.h

CWorkbooks.h

CWorksheet.h

CWorksheets.h

를 추가한다.

5) 추가를 완료하면 자동으로 프로젝트에 Header File일 추가된다.

빌드시 각 Header File의 아래 항목 주석 처리.

//#import "C:\\Program Files\\Microsoft Office\\Office16\\EXCEL.EXE" no_namespace

 

CRange.h파일의 DialogBox()함수 주석처리.(컴파일시 에러 발생)

//VARIANT DialogBox()
//{
// VARIANT result;
// InvokeHelper(0xf5, DISPATCH_METHOD, VT_VARIANT, (void*)&result, nullptr);
// return result;
//}


USES_CONVERSION; /*주) 1MByte이상시 에러 발생*/

A2W() : wchar to char
W2A() : wchar to char


USES_CONVERSION;

char *pstrBuf = {"abcd"};

wchar strUni[100]= {0};
_stprintf(&strUni[0], _T("%s"), A2W(pstrBuf));

 

=============================================================

TCHAR 활용
기능 ANSI 함수 유니코드 함수 일반 문자열 함수
-------------------------------------------------------------------------------------------------------------
문자열의 길이를 반환하는 함수 strlen() wcslen() _tcslen()
두 문자열을 접합하는 함수 strcat() wcscat() _tcscat()
문자열에서 문자를 찾는 함수 strchr() wcschr() _tcschr()
두 문자열을 비교하는 함수 strcmp() wcscmp() _tcscmp()
문자열을 복사하는 함수 strcpy() wcscpy() _tcscpy()
부분 문자열을 찾는 함수 strstr() wcsstr() _tcsstr()
문자열을 역순으로 저장하는 함수 strrev() _wcsrev() _tcsrev()

 

 

strcpy -> wcscpy -> _tcscpy (문자열을 복사)
strncpy -> wcsncpy -> _tcsncpy ( 사이즈 만큼 복사)
strlen -> wcslen -> _tcslen (문자열 길이 확인)
strcat -> wcscat -> _tcscat (두 문자열 이어 붙이기)
strncat -> wcsncat -> _tcsncat (사이즈 만큼 이어 붙이기)
strcmp -> wcscmp -> _tcscmp (문자열 비교) (반환 값(-1, 0, 1))
strncmp -> wcsncmp -> _tcsncmp ( 사이즈 만큼 문자열 비교)
stricmp -> wcsicmp -> _tcsicmp (대소문자를 구별하지 않고 문자열을 비교)
strnicmp -> wcsnicmp -> _tcsnicmp (사이즈 만큼 대소문자를 구별하지 않고 문자열을 비교)
strchr -> wcschr -> _tcschr (문자 찾기)
strrchr -> wcsrchr -> _tcsrchr (문자 찾기 (문자열 끝에서 부터 검색))
strstr -> wcsstr -> _tcsstr (문자열 찾기)
strpbrk -> wcspbrk -> _tcspbrk (문자 찾기 (두번째 인수를 찾고자 하는 문자들의 집합(문자열)으로 구성)
strtok -> wcstok -> _tcstok (문자열 자르기 (두번째 인수를 집합(문자열)으로 구성 가능)) => 해당 문자가 NULL로 치환 됨
strset -> wcsset -> _tcsset (문자 치환, 첫째 인수의 모든 문자를 두번째 인수 문자로 변경함) => "abc" -> "bbb"
strnset -> wcsnset -> _tscnset (사이즈 만큼 문자 치환)
strupr -> wcsupr -> _tcsupr (대문자로 치환)
strlwr -> wcslwr -> _tcslwr (소문자로 치환)
strrev -> wcsrev -> _tcsrev (문자열 역정렬) => "가나다라마" -> "마라다나가"
_stprintf_s( buf, sizeof(buf), _T("point : %f, %f \n"), location.x, location.y );//문자열 나머지는 0xFF로
_stprintf( buf, sizeof(buf), _T("point : %f, %f \n"), location.x, location.y );//문자열까지만

'작업 > C,C++' 카테고리의 다른 글

감지 각도에서 목표각도까지 최단 각도 구하기  (0) 2021.01.06

설치 파일 만들고, System 폴더의 INI를 바로 접근 하기기위해서 관리자 권한으로 실행 시키자.

1차 Test

대상 : 644*484 Color이미지의 Red와 Green색상 변경.

코드 : CPU용 이중 for문으로 구성, GPU Cuda 병렬 처리 방식으로 구성.

속도 : CPU 3 msec, GPU 11 msec CPU가 빠르다.(debug, release 같은 현상)

       -> Memory 생성 복사가 추가 되었음으로 CPU 쪽에도 추가 ( 속도 변화 없음)

결론 : Data양이 적을때에는 CPU가 3배 이상 빠르다.(GPU로 메모리 복사가 생기지 않음으로)

     - CPU : 적은 Data, 복잡한 연산에 적합.

     - GPU : 다량의 Data, 단순(CPU에 비해) 연산에 적합.

 

2차 Test

대상 : 상동

코드 : 각 처리위치 반복 수행 제일 안쪽에서 같은 동작 1000회 반복.

속도 :  debug Mode : CPU 2438 msec, GPU 2829 msec

         Release Mode: CPU 1180msec, GPU 3 msec(393배 빠름)

 

*cudaDeviceSynchronize();로 GPU 동작 완료 체크.

 

CPU:2438msec, GPU:2829msec
CPU 1180msec, GPU 3msec(393배)

 

추가 : 이미지 크기 9999*7514 크기 Test

   1회교환

        Debug : CPU 930 msec, GPU  : 2598 msec

        Release : CPU 139 msec, GPU : 358 msec

   100회 교환

        Release : CPU 32288 msec, GPU : 378(최초 511) msec

   1000회 교환

        Release : CPU 측정 불가, GPU : 352 msec

 

Test 진행 코드

'작업 > Cuda' 카테고리의 다른 글

RTX 2050 CUDA Version 11.0 이상  (0) 2025.05.22
NVIDIA Cuda Cores 참고  (0) 2022.02.24
Cuda Block Thread 설정.  (0) 2020.05.26
기존 Project Cuda Link時 오류  (1) 2020.05.06
VS2017 - NVIDIA Cuda 연결  (0) 2019.12.03

1) Cuda 10.2 Download

OS와 현재 설정에 따라 맞게 설정 하여 Download

2) "cuda_10.2.89_441.22_win 10.exe"설치(2.5 GByte)

3) VS2017 설정 (Consol Test Project 생성 후)

지정 빌드 설정

4) Cuda Lib 추가.(Debug & Release : cuda.lib; cudart.lib; cublas.lib; cufft.lib)

링커 Lib 등록

5) Test.cuh, Test.cu 파일 추가.

확장자 *.cuh, *.cu로 설정 된다.

6) 기본 Test 코드 작성

Test용 Add 함수

7) 컴파일 및 실행

'작업 > Cuda' 카테고리의 다른 글

RTX 2050 CUDA Version 11.0 이상  (0) 2025.05.22
NVIDIA Cuda Cores 참고  (0) 2022.02.24
Cuda Block Thread 설정.  (0) 2020.05.26
기존 Project Cuda Link時 오류  (1) 2020.05.06
CPU-GPU 속도 Test  (0) 2019.12.03

+ Recent posts