성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Roll A Lisp In C - Reading ; https...
[정성태] Java - How to use the Foreign Funct...
[정성태] 제가 큰 실수를 했군요. ^^; Delegate를 통한 Bein...
[정성태] Working with Rust Libraries from C#...
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>eBEST C# XingAPI 래퍼 - 연속 조회 처리 방법</h1> <p> 아래의 파이썬 강좌를 보면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > [24강] xingAPI를 이용한 데이터 연속 조회 (t1301, t1310) ; <a target='tab' href='https://www.youtube.com/watch?v=oargZbRv7m4'>https://www.youtube.com/watch?v=oargZbRv7m4</a> </pre> <br /> 연속 조회를 처리하는 방법이 나옵니다. 규칙은 간단한데요, summary 성격의 OUTBLOCK 결과의 값을 그대로 다음번 조회 시의 INBLOCK 입력으로 넣어 주고 Request가 연속적임을 알리는 플래그를 설정하면 됩니다.<br /> <br /> 이런 처리를 XingAPINet에서는,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > eBEST XingAPI의 C# 래퍼 버전 - XingAPINet Nuget 패키지 ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12134'>https://www.sysnet.pe.kr/2/0/12134</a> </pre> <br /> 다음과 같이 코딩할 수 있습니다. (bold 처리된 부분이 기존의 일반적인 쿼리 문에서와 달라진 코드입니다.)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > /* XingAPI/DevCenterSample/TR/업종/t1301/ ; <a target='tab' href='https://github.com/stjeong/XingAPI/tree/master/DevCenterSample/TR/%EC%97%85%EC%A2%85/t1301'>https://github.com/stjeong/XingAPI/tree/master/DevCenterSample/TR/%EC%97%85%EC%A2%85/t1301</a> */ using (XingClient xing = new XingClient(useDemoServer)) { if (xing.ConnectWithLogin(user) == false) { Console.WriteLine(xing.ErrorMessage); return; } using (XQt1301 query = new XQt1301()) { var inBlock = new XQt1301InBlock { shcode = Stock.SHCODE.KOSPI.현대건설, starttime = "0900", endtime = "1530", }; <span style='color: blue; font-weight: bold'>while (true) // 1단계 {</span> query.SetBlock(inBlock); if (query.Request() < 0) { break; // 쿼리 실패 } var outBlock = query.GetBlock(); if (outBlock.IsValidData == false) { break; // 쿼리 해석 실패 } foreach (var item in query.GetBlock1s()) { item.Dump(Console.Out, DumpOutputType.Inline80Cols); } <span style='color: blue; font-weight: bold'>inBlock.CopyValueFromBlock(outBlock); // 2단계 if (outBlock.cts_time == "") // 3단계 { break; } }</span> } } </pre> <br /> 위의 코드를 말로 표현하면 다음과 같습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 1단계. 무한 반복 설정 2단계. 결괏값으로 나오는 outBlock의 값을 그대로 inBlock으로 복사 3단계. 마지막 연속 데이터라면 while 루프 문 탈출 이후, 연속적으로 Request()를 호출하면서 4단계의 조건이 만족될 때까지 반복 </pre> <br /> 간단하죠!!! ^^<br /> <br /> <hr style='width: 50%' /><br /> <br /> 위의 코드는 연속 데이터의 끝까지 데이터를 조회하는 반면 원한다면 개수를 정하는 것도 가능합니다. 이에 대한 예제가 t1475에 나오는데요,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > XingAPI/DevCenterSample/TR/업종/t1475/ ; <a target='tab' href='https://github.com/stjeong/XingAPI/tree/master/DevCenterSample/TR/%EC%97%85%EC%A2%85/t1475'>https://github.com/stjeong/XingAPI/tree/master/DevCenterSample/TR/%EC%97%85%EC%A2%85/t1475</a> </pre> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // ...[생략]... <span style='color: blue; font-weight: bold'>int pageSize = 10; int totalSize = 30;</span> using (XQt1475 query = new XQt1475()) { XQt1475InBlock inBlock = new XQt1475InBlock { shcode = Stock.SHCODE.KOSDAQ.이베스트투자증권, <span style='color: blue; font-weight: bold'>datacnt = pageSize,</span> }; while (<span style='color: blue; font-weight: bold'>totalSize > 0</span>) { query.SetBlock(inBlock); if (query.Request() < 0) { break; } XQt1475OutBlock outBlock = query.GetBlock(); if (outBlock.IsValidData == false) { break; } foreach (var item in query.GetBlock1s()) { item.Dump(Console.Out, DumpOutputType.Inline80Cols); <span style='color: blue; font-weight: bold'>totalSize--;</span> } inBlock.CopyValueFromBlock(outBlock); } } </pre> <br /> t1475의 경우 InBlock에서 datacnt라는 속성이 있어 조회할 데이터 수량을 지정할 수 있습니다. 즉, 위의 경우에는 한 번에 10개씩 가져오는데 총 수량이 (최소) 30개가 될 때까지만 연속 데이터를 조회합니다. 역시 간단하죠!!! ^^<br /> <br /> <hr style='width: 50%' /><br /> <br /> 알아본 김에 Sqlite 지원도 추가했으니,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > eBEST C# XingAPI 래퍼 - Sqlite 지원 추가 ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12145'>https://www.sysnet.pe.kr/2/0/12145</a> </pre> <br /> 연속 데이터를 DB에 쌓는 법도 볼까요? ^^ 아래는 t1310의 예제 코드인데,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > /* XingAPI/DevCenterSample/TR/업종/t1310/ ; <a target='tab' href='https://github.com/stjeong/XingAPI/tree/master/DevCenterSample/TR/%EC%97%85%EC%A2%85/t1310'>https://github.com/stjeong/XingAPI/tree/master/DevCenterSample/TR/%EC%97%85%EC%A2%85/t1310</a> */ using (XQt1310 query = new XQt1310()) { var inBlock = new XQt1310InBlock { shcode = Stock.SHCODE.KOSPI.현대건설, daygb = XQt1310.DayGB.당일, timegb = XQt1310.TimeGB.틱, }; <span style='color: blue; font-weight: bold'>bool createFirst = true;</span> while (true) { query.SetBlock(inBlock); if (query.Request() < 0) { break; } var outBlock = query.GetBlock(); if (outBlock.IsValidData == false) { break; } var blocks = query.GetBlock1s(); foreach (var item in blocks) { item.Dump(Console.Out, DumpOutputType.Inline80Cols); } <span style='color: blue; font-weight: bold'>blocks.WriteToDB(createFirst, inBlock.shcode); createFirst = false;</span> inBlock.CopyValueFromBlock(outBlock); if (string.IsNullOrEmpty(outBlock.cts_time) == true) { break; } } } </pre> <br /> 보는 바와 같이 달라진 곳은 blocks.WriteToDB에 대한 호출 뿐입니다. 최초 호출 시에는 DB 테이블이 만들어져 있지 않으므로 첫 번째 인자(replace)에 true를 줘서 DB 테이블을 (기존에 있다면 삭제하고) 새로 생성할 수 있도록 합니다. 그다음, 두 번째 인자(tableNamePostfix)는 DB 테이블 명의 접미사인데 기본적으로 OutBlock의 이름을 사용하지만, 현실적으로 봤을 때 XQt1310 쿼리를 수행했을 때 "종목 코드(shcode)" 별로 데이터가 저장되어야 할 것이므로 "XQt1310_000720"과 같은 식의 테이블 명이 지정되도록 합니다.<br /> <br /> 이후, DB에 저장된 내용을 조회하고 싶다면 마찬가지로 접미사를 지정해 ReadFromDB 메서드를 호출하면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > var multiBlock = XQt1310.<span style='color: blue; font-weight: bold'>ReadFromDB</span>("000720"); // 000720 == 현대건설 Console.WriteLine($"# of items: {multiBlock.OutBlock1.Length}"); foreach (var item in multiBlock.OutBlock1) { item.Dump(Console.Out, DumpOutputType.Inline80Cols); } </pre> <br /> 역시 간단하죠~~~!!! ^^<br /> <br /> <hr style='width: 50%' /><br /> <br /> 마지막으로, Request() 메서드는 bNext 인자 값을 하나 받는데 기본값은 null입니다. 그냥 이렇게 null로 설정하면 최초 XQtNNNN 객체 생성 후 첫 번째 Request 호출에 대해서는 "Request(false)"로 처리하고, 그 이후의 호출에 대해서는 "Request(true)"로 처리합니다. 다음 코드는 그에 대한 사례입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using (XQt1301 query = new XQt1301()) { // ...[생략]... query.Request(); // == 객체 생성 후 첫 번째 호출이므로, <span style='color: blue; font-weight: bold'>query.Request(false)</span>와 동일 // ...[생략]... query.Request(); // == 두 번째 호출이므로, <span style='color: blue; font-weight: bold'>query.Request(true)</span>와 동일 } </pre> <br /> 따라서, 연속 데이터 조회가 아닌데도 쿼리 객체를 재사용해 Request를 사용한다면 다음과 같이 명시적으로 false 설정을 해야 합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using (XQt1301 query = new XQt1301()) { // ...[생략]... query.Request(false); // ...[생략]... query.Request(false); } </pre> <br /> 또는, XQt1301 객체 생성 후 첫 호출은 언제나 false 처리되므로 다음과 같은 식으로 매번 XQtNNNN Query 객체를 생성해 처리할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > for (int i = 0; i < 2; i ++) { using (XQt1301 query = new XQt1301()) { // ...[생략]... query.Request(); // == 객체 생성 후 첫 번째 호출이므로, query.Request(false)와 동일 } } </pre> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
3756
(왼쪽의 숫자를 입력해야 합니다.)