출처 : 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

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

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

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

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

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

 

저작자 표시 비영리 변경 금지
신고
블로그 이미지

프로그래머 지향자 RosaGigantea

바쁜 일상 생활중의 기억 장소

Tag ADO


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) 좌표가 서로 뒤바뀌어 써주어야 한다는 점에 주의하기 바란다.


저작자 표시


저작자 표시 비영리 변경 금지
신고
블로그 이미지

프로그래머 지향자 RosaGigantea

바쁜 일상 생활중의 기억 장소

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


출처 : 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

저작자 표시 비영리 변경 금지
신고
블로그 이미지

프로그래머 지향자 RosaGigantea

바쁜 일상 생활중의 기억 장소

%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를 쓰면 된다.

저작자 표시 비영리 변경 금지
신고
블로그 이미지

프로그래머 지향자 RosaGigantea

바쁜 일상 생활중의 기억 장소

Tag printf

* 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

저작자 표시 비영리 변경 금지
신고
블로그 이미지

프로그래머 지향자 RosaGigantea

바쁜 일상 생활중의 기억 장소