출처 : http://q.hatena.ne.jp/1259456311

 

 

ADO と ADO.NET による Excel ファイルを読み込むサンプルを用意してみました。

Excel ファイルは以下の形式を想定しています。

ブック名:[book1.xls] / シート名:[Sheet1]

A B
1 key value
2 項目1 値1
3 項目2 値2
4 項目3 値3

ADO も ADO.NET も「Jet OLE DB プロバイダ」と「データベースの種類」を接続文字列にて指定することで、Excel ファイルにアクセスすることが可能です。

<接続文字列の例>
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Book1.xls;Extended Properties="Excel 8.0;HDR=YES;" 
<ADO 概要>
[アプリケーション]
   |
  [ADO]         … ADODB.Connection
   |
  [OLE DB]
   |
[OLE DB Provider] … Microsoft.Jet.OLEDB.4.0
   |
 [ISAM ドライバ] … Extended Properties="Excel 8.0;HDR=YES;"
   |
 [Excel ファイル] … Data Source=C:\book1.xls
<ADO.NET 概要>
[.NET アプリケーション]
   |
  [ADO.NET]
   |
[.NET Framework Data Provider for OLE DB] … OleDbConnection
   |
  [OLE DB]
   |
[OLE DB Provider] … Provider=Microsoft.Jet.OLEDB.4.0
   |
 [ISAM ドライバ] … Extended Properties="Excel 8.0;HDR=YES;"
   |
 [Excel ファイル] … Data Source=C:\book1.xls
<データベースの種類>
Excel 5.0 … Excel 5.0 および 7.0 (95) 形式
Excel 8.0 … Excel 8.0 (97), 9.0(2000), 10.0(2002) 形式

まず、はじめは WSH(VBScript)+ ADO のサンプルです。

' File : AdoExcelTest.vbs
' Usage : CScript //Nologo AdoExcelTest.vbs [Enter]
Option Explicit

Call Main()

Sub Main()
    Dim cn
    Set cn = CreateObject("ADODB.Connection")

    Dim strFileName
    Dim strCon
    strFileName = "C:\home\edu\hatena\gontakun_55\1259456311\book1.xls"
    strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strFileName & ";Extended Properties=""Excel 8.0;HDR=YES"""
    cn.Open strCon

    Dim rs
    Set rs = cn.Execute("SELECT * FROM [Sheet1$]")

    While Not rs.BOF And Not rs.EOF
        WScript.Echo "key = [" & rs(0) & "], value = [" & rs(1) & "]"
        rs.MoveNext
    Wend

    rs.Close
    cn.Close
End Sub
<実行結果>
key = [項目1], value = [値1]
key = [項目2], value = [値2]
key = [項目3], value = [値3]

次に、VC++2008(C++) + ADO のサンプルです。

// File : AdoExcelTest.cpp
// Compile : cl AdoExcelTest.cpp [Enter]
// Usage : AdoExcelTest.exe [Enter]
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <stdio.h>
#include <comdef.h>

int main( int argc, char* argv[] )
{
    CoInitialize(NULL);

    _ConnectionPtr cn("ADODB.Connection");

    _bstr_t strFileName;
    _bstr_t strCon;
    strFileName = "C:\\home\\edu\\hatena\\gontakun_55\\1259456311\\book1.xls";
    strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strFileName + ";Extended Properties=\"Excel 8.0;HDR=YES\"";
    
    cn->Open( strCon, "", "", adConnectUnspecified );

    _RecordsetPtr rs("ADODB.Recordset");
    rs = cn->Execute( "SELECT * FROM [Sheet1$]", NULL, 0 );
    
    while ( !rs->GetBOF() && !rs->GetEndOfFile() )
    {
        printf( "key = [%s], value = [%s]\n", 
            (LPCTSTR)(_bstr_t)rs->Fields->Item[0L]->Value,
            (LPCTSTR)(_bstr_t)rs->Fields->Item[1L]->Value );
        rs->MoveNext();
    }
    rs->Close();
    cn->Close();
    
    CoUninitialize();

    return 0;
}

実行結果は1番目と同じです。


そして、最後に、VC++2008(C++/CLI) + ADO.NET のサンプルです。

// File : AdoExcelDotNet.cpp
// Compile : cl AdoExcelDotNet.cpp /clr [Enter]
// Usage : AdoExcelDotNet.exe [Enter]

#using <mscorlib.dll>
#using <System.dll>
#using <System.Data.dll>

using namespace System;
using namespace System::Data;
using namespace System::Data::OleDb;

int main( array<System::String ^> ^args )
{
    OleDbConnection^ con = gcnew OleDbConnection();

    String^ strFileName = gcnew String("C:\\home\\edu\\hatena\\gontakun_55\\1259456311\\book1.xls");
    String^ strCon = gcnew String("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strFileName + ";Extended Properties=\"Excel 8.0;HDR=YES;\"");
    con->ConnectionString = strCon;
    con->Open();

    OleDbCommand^ cmd = gcnew OleDbCommand("SELECT * FROM [Sheet1$]", con );
    OleDbDataReader^ reader = cmd->ExecuteReader();

    while ( reader->Read() )
    {
        Console::WriteLine("key = [{0}], value = [{1}]", reader["key"], reader["value"] );
    }

    reader->Close();
    con->Close();

    return 0;
}

これも実行結果は1番目と同じです。


なお、サンプルコードを簡略化する為にエラー処理(try ~ catch 等)は、省略してあります。

実際にコーディングする場合は、必要に応じてエラー処理を追加してください。


また、今回の ADO / ADO.NET での使用例は、Excel のデータが「表形式」(テーブル形式)であることが前提です。

データが非定型の場合は、Excel オートメーション(Excel.exe をリモート操作する方法)を使用する必要があります。

Add Star
id:gontakun_55

詳しい説明付きで大変参考になりました。

動作出来るようになり、大変感謝致します。

また、複数のサンプルまでご用意頂き、大変ありがとうございます。

今後の参考にさせて頂きます。

ありがとうございました。

 


2차원 평면 상에서 어느 한 점의 위상(phase)을 알고 싶을 때, 쉽게 말해서 x축과 이루는 각을 알고 싶을 때 사용할 수 있는 함수가 atan2(아크 탄젠트 투) 이다. 이 함수의 원형은 다음과 같다.

1
double atan2(double y, double x)
 

이 함수는 atan(y/x) 결과 값을 반환하며, 반환값의 범위는 -pi 부터 +pi 까지이다. (즉, -3.14 ~ + 3.14)

이 함수를 사용할 때 주의할 점은 점의 y좌표를 먼저 써주어야 한다는 것이다. 너무나 당연스럽게 (x, y) 좌표 순서대로 써줄 경우 잘못된 결과를 얻게 될 수 있다. 몇몇 2차원 좌표에 대하여 atan2 함수를 적용하였을 때 결과값을 아래 그림에 정리하였다. 다시 한 번 말하지만, (x, y) 좌표가 서로 뒤바뀌어 써주어야 한다는 점에 주의하기 바란다.


저작자 표시


여러 소스를 보았지만 가장 완벽한 소스는 아래와 같습니다.


출처 : http://borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tip&no=880 + 알파

#include <stdio.h>

#include <math.h>


#define round(x)        ((x) >= 0 ? (long)((x) + 0.5) : (long)((x) - 0.5))


int getInternalAngle(int ox, int oy, int px, int py, int qx, int qy)

{

    float oq = sqrt(pow(pointO.x - pointQ.x, 2) + pow(pointO.y - pointQ.y, 2));

    float op = sqrt(pow(pointO.x - pointP.x, 2) + pow(pointO.y - pointP.y, 2));

    float pq = sqrt(pow(pointP.x - pointQ.x, 2) + pow(pointP.y - pointQ.y, 2));


    if (op < 1 || pq < 1) {

        return 0;

    }


    float temp = (pow(op,2) + pow(pq,2) - pow(oq,2)) / (2*op*pq);


    float angle = acos(temp);

    angle = angle * (180 / M_PI);


    if (pointO.x != pointP.x) {

        float a = (pointP.y - pointO.y) / (pointP.x - pointO.x);

        float b = (pointP.x * pointO.y - pointO.x*pointP.y) / (pointP.x - pointO.x);

        float y = a * pointQ.x + b;

        if (a > 0) {

            if (pointQ.y > y) {

                angle = 360.0f - angle;

            }

        } else {

            if (pointQ.y < y) {

                angle = 360.0f - angle;

            }

        }

    } else {

        if (pointQ.x < pointP.x) {

            angle = 360.0f - angle;

        }

    }


    return round(angle);

}


int main()

{

    int ax,ay,bx,by,cx,cy;

    printf("점 A의 좌표를 입력하세요 : \n");

    scanf("%d%d",&ax,&ay);

    printf("점 B의 좌표를 입력하세요 : \n");

    scanf("%d%d",&bx,&by);

    printf("점 C의 좌표를 입력하세요 : \n");

    scanf("%d%d",&cx,&cy);

    printf("ABC의 각도는 %d도 입니다.\n",getInternalAngle(ax,ay,bx,by,cx,cy));


    return 0;

}



별거 없는데... 생각하는데 시간이 너무 들었네요.. orz

%04x - 빈자리에 0이 딸려오는 4자리 hex값



다 알겠지만,


%x는 int형 변수를 16진수로 표시해주는 것이다.


%4x는 16진수를 표시하되 4자리를 맞춰서(오른쪽정렬) 표시해준다.


아마 여기까진 다들 알지도 모른다.



하지만 %04x는 알까 'ㄱ')?



0이 붙으면 빈자리를 공백 대신에 0으로 채워준다.


예를 들면 0x23은 0023이 되는 것이다.


이것은 %d나 %u에도 똑같이 적용된다.






%hc, %hs - wprintf에서 멀티바이트 문자(열) 출력

%lc, %ls - printf에서 유니코드 문자(열) 출력



wprintf에서 일반 멀티바이트 문자나 스트링을 출력하려면 앞에다가 h만 붙여주면 된다.

반대로 printf에서 유니코드 문자나 스트링을 출력하려면 앞에다가 l만 붙여주면 된다.





예)

setlocale(LC_ALL, "");


wprintf (L"%hs%hc\n", "엿", '!');

printf ("%ls%lc\n", L"엿", L'!');


출력결과)


엿!
엿!





%p - pointer



포인터 출력하는데 %x붙이지마라.

진짜 출력하는 방법은 %p다.

win64든 뭐든 어디서든 잘 출력된다.

니네들 이거 알아야되는데, 다들 모른다.





%I64d, %I64u, %I64x - 64-bit 정수 출력시



64비트 정수(__int64) 출력은 I64를 붙여쓰면 된다.


%I64d, %I64u, %I64x처럼...


물론 I64에서 I는 I(아이)다!

l(엘)이 아니고...





%Iu, %Id, %Ix - ULONG_PTR



ULONG_PTRLONG_PTR, and DWORD_PTR are numeric types that are as wide as a pointer. In other words, they map to ULONGLONG, and DWORD respectively on Win32, and ULONGLONGLONGLONG, andULONGLONG on Win64.

The I size prefix (capital-i, not lowercase-L) is what you need to print *LONG_PTR on Win32 and Win64.





해석하기 귀찮아

이거 필요하신 분 정도면 이정도 해석은 가능하겠지







%*d - 숫자가 출력될 너비를 런타임에서 조절



%2d나 %5d와 같은 너비 크기 조절을 런타임에서 하고자 할때, *를 넣으면 된다.

%*d를 쓰면 인자를 두개를 사용한다. 처음 인자가 너비이고 두번째 인자는 원래 수이다.




다음은 적절한 트리 출력 예제이다.



 void Tree::Print(Node* pNode, int level) {     if (NULL != pNode)     {         Print(pNode->Left, level+1);         printf("%*d%s\n", 2 * level, pNode->Key);         Print(pNode->Right, level+1);     } }



%.*s - substring!



str함수를 이용해야 하는 문자열 잘라내기를 printf내에서 할 수 있다!

그리고, 길이만 안다면 NULL로 끝나지 않는 문자열에 대해서도 잘라낼 수 있다.



printf("%.*s\n", sublen, str)



이렇게 하면, str의 왼쪽에서 sublen만큼만 출력할 수 있다.



s앞에 .을 붙이면, .뒤에 숫자를 붙임으로써 문자열이 출력되는 갯수를 정할 수 있다.

(예: %.5s는 문자열이 몇개가 오든 5개만 출력한다는 소리)



그런데 s앞에 *도 붙이면, .의 뒤에 와야할 숫자를 printf의 인자로 줄 수 있다.



그래서 마치 printf를 substring함수와 같이 쓸 수 있는 것이다.




예)

int i;

char* str = "1234567890";

for (i = 0; i <= 10; i++)

{

printf ("%.*sㅗ", 10-i,str+i);

printf ("%.*s\n", i,str);

}



출력결과)


1234567890ㅗ

234567890ㅗ1

34567890ㅗ12

4567890ㅗ123

567890ㅗ1234

67890ㅗ12345

7890ㅗ123456

890ㅗ1234567

90ㅗ12345678

0ㅗ123456789

ㅗ1234567890





추가로, printf의 인자로 직접 정한 숫자보다 더 작은 문자열이 들어오면, 인자로 준 숫자는 그냥 무시된다.






%.0d - 0일때 출력 안하기



값이 0일때는 출력을 안하고싶은 때가 있을거다.

그럴때 if문으로 분기해서 일일이 처리했다면, 이것이 반가울것이다.


바로 %와 d사이에 .을 붙임으로 해결된다.




예)

printf ("%.d", 0);


결과)

[아무것도 출력되지 않는다]






%#x - 0x를 붙여주는 hex표현



0x를 앞에다 출력하고 싶으면, %x 대신에 %#x를 쓰면 된다.

* WINVER
Using the Windows Headers
http://msdn.microsoft.com/en-us/library/aa383745(VS.85).aspx
_WIN32_WINNT ,WINVER
Windows 8    = 0x0602 (_WIN32_WINNT_WIN8 )
Windows 7    = 0x0601 (_WIN32_WINNT_WIN7 )
Windows Server 2008 = 0x0600
Windows Vista        = 0x0600
Windows Server 2003 with SP1, Windows XP with SP2    = 0x0502
Windows Server 2003, Windows XP    = 0x0501
Windows 2000    = 0x0500



* _MSC_VER
Visual Studio Version ( msc_ver )
https://en.wikipedia.org/wiki/Microsoft_Visual_Studio#Version_history
VC 4.0 (1995) = 1000
VC 5.0 (1997) = 1100
VC 6.0 (1998) = 1200  <----
VC 7.0 (2002) = 1300
VC 7.1 (2003) = 1310
VC 8.0 (2005) = 1400
VC 9.0 (2008) = 1500
VC 10.0 (2010) = 1600  - msvcr100.dll
VC 11.0 (2012) = 1700

+ Recent posts