퇴근5분전



 음... 이랜드 플젝이 끝나고 새로 온 곳...  그냥 할말이 없다!

지하에 모기와... 겨울을 어찌 날까낭... 걱정이네...

이런저런 프로그램 설계만 해놓고 전혀 코드를 못치고 있다. 그냥 회사 일이나 조금 씩 하며
다시 의욕을 불태울날을 기다려보자.

그동안 영어나 좀 공부해둬야 되겠다.

 음.. 슬럼프라... 내가 누릴수 있는것인가??/ 쩝!




음 소스는 이미지 사이즈에 따라 조금 우측 픽쳐박스랑 싱크가 안맞기도 한데...

이건 이미지pixel값 가져올때 좌표계산이 살짝!!! 미스 나는것 같다..

머 그냥 쓸것도 아닌 구현해본정도니... 넘어감..

훈스 C# 질문게시판에 비슷한 게시글이 올라와서 구현해봤음.

'# 2) .Net ( Vs 2005 ) > 기타' 카테고리의 다른 글

IPC... 리모트 객체 수명이 5~6분?  (0) 2011.06.24
[정규식] Replace~  (0) 2010.09.14
글꼴 폰트 관련 MSDN 링크  (0) 2010.08.10
소수 구하기 소스...  (0) 2010.08.06
[GDI+] Matrix 객체 사용해보기...  (0) 2010.07.27



쿼리상에서의 피벗은 집계함수를 적용해야 하는데...

챠트를 구현하면서 나온 데이타를 피벗할필요없이 특정 컬럼을 기준으로 대상데이타를 가로축으로 변경하고자 할때 사용하면 됨.


이하 소스.

그리드뷰 4개를 놓고 왼쪽은 기본데이타 오른쪽은 피벗된 데이타.

Pivot(DataTable sourceTb, string sBaseColumnName, string sBaseHeaderColumnName, string RotColumnName)  : DataTable

소스 테이블, 컬럼이 될 데이타를 가진 컬럼명,   컬럼의 설명이 들어간 컬럼,  데이타컬럼

   피봇 전                                                            피봇 후





namespace PIVOT_TABLE
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            DataTable sourceTable = new DataTable();
            sourceTable.Columns.Add("YM_MAGAM");
            sourceTable.Columns.Add("CD_GMGS");
            sourceTable.Columns.Add("DS_GMGS");
            sourceTable.Columns.Add("AM_CURRENT1");

            sourceTable.Rows.Add(201006, "F100000", "유동비율(%)", 120.2);
            sourceTable.Rows.Add(201006, "F100100", "부채비율(%)", 367.6);
            sourceTable.Rows.Add(201006, "F100200", "차입금의존도(%)", 63.3);
            sourceTable.Rows.Add(201006, "F100300", "영업이익이자보상배율(배)", 0.1);
            sourceTable.Rows.Add(200912, "F100000", "유동비율(%)", 130.3);
            sourceTable.Rows.Add(200912, "F100100", "부채비율(%)", 207.0);
            sourceTable.Rows.Add(200912, "F100200", "차입금의존도(%)", 47.8);
            sourceTable.Rows.Add(200912, "F100300", "영업이익이자보상배율(배)", 2.4);
            sourceTable.Rows.Add(200812, "F100000", "유동비율(%)", 135.8);
            sourceTable.Rows.Add(200812, "F100100", "부채비율(%)", 107.2);
            sourceTable.Rows.Add(200812, "F100200", "차입금의존도(%)", 27.0);
            sourceTable.Rows.Add(200812, "F100300", "영업이익이자보상배율(배)", 2.7);

            dataGridView1.DataSource = sourceTable;


            dataGridView2.DataSource = Pivot(sourceTable, "CD_GMGS", "DS_GMGS", "AM_CURRENT1");


            DataTable sourceTable1 = new DataTable();
            sourceTable1.Columns.Add("YM_MAGAM");
            sourceTable1.Columns.Add("AM_JUMSU");


            sourceTable1.Rows.Add(200612,  null);
            sourceTable1.Rows.Add(200712,  null);
            sourceTable1.Rows.Add(200812,  null);
            sourceTable1.Rows.Add(200912,  27.5000);
            sourceTable1.Rows.Add(201006,  20.0000);

            dataGridView3.DataSource = sourceTable1;

            dataGridView4.DataSource = Pivot(sourceTable1, "YM_MAGAM", "YM_MAGAM", "AM_JUMSU");

        }

        /// <summary>
        /// 피벗 메서드.
        /// 소스 데이타를 특정 컬럼 기준으로 컬럼으로 확장 후 데이타를 확장컬럼에 넣어서 반환해줌.
        /// 추가 : 챠트에 쓰기 위해 NO를 추가해서 넘버링 함. ( 기준 BindingX 값으로 사용함 )
        /// 추가 : 나머지 컬럼은 모두 제자리.
        /// </summary>
        /// <param name="sourceTb"> 변환 될 데이타 테이블</param>
        /// <param name="sBaseColumnName"> 컬럼변경 데이타를 가진 컬럼명</param>
        /// <param name="sBaseHeaderColumnName"> 컬럼에 대한 헤더컬럼.</param>
        /// <param name="RotColumnName"> 옮겨질 데이타. </param>
        /// <returns></returns>
        DataTable Pivot(DataTable sourceTb, string sBaseColumnName, string sBaseHeaderColumnName, string RotColumnName)
        {
            DataTable dt = new DataTable();
            int sBaseColumnIndex = sourceTb.Columns.IndexOf(sBaseColumnName);
            int sBaseHeaderColumnIndex = sourceTb.Columns.IndexOf(sBaseHeaderColumnName);
            int sRotColumnIndex = sourceTb.Columns.IndexOf(RotColumnName);

            dt.Columns.Add("_NO");
            for (int colIndex = 0; colIndex < sourceTb.Columns.Count; colIndex++)
            {
                if (sBaseColumnIndex == colIndex || sRotColumnIndex == colIndex || sBaseHeaderColumnIndex == colIndex) continue;
                dt.Columns.Add(string.Format("_{0}", sourceTb.Columns[colIndex].ColumnName));
            }

            string ColName = string.Empty;

            foreach (DataRow sBaseColumnRow in sourceTb.Rows)
            {
                ColName = sBaseColumnRow[sBaseColumnIndex].ToString();
                if (!dt.Columns.Contains(string.Format("_{0}", ColName)))
                {
                    dt.Columns.Add(string.Format("_{0}", ColName));
                    if (sBaseHeaderColumnIndex >= 0)
                        dt.Columns[dt.Columns.Count - 1].Caption = sBaseColumnRow[sBaseHeaderColumnIndex].ToString();
                }
            }
            int offsetCol = sBaseHeaderColumnIndex == -1 ? 2 : 3;

            // Row 한번에 뛰어넘을 간격을 계산함.
            int step = dt.Columns.Count - (sourceTb.Columns.Count - offsetCol) - 1; // 1은 NO 컬럼 몫.

            if (step <= 0)
            {
                throw new Exception("RowIndex 계산증가값은 0이하가 될수 없습니다.");
            }

            List<object> values = new List<object>();
            for (int rowIndex = 0; rowIndex < sourceTb.Rows.Count; rowIndex += step)
            {
                values.Add(dt.Rows.Count + 1);
                for (int colIndex = 0; colIndex < sourceTb.Columns.Count; colIndex++)
                {
                    if (sBaseColumnIndex == colIndex || sRotColumnIndex == colIndex || sBaseHeaderColumnIndex == colIndex) continue;

                    values.Add(sourceTb.Rows[rowIndex][colIndex]); // 기존 컬럼 복사
                }

                for (int i = 0; i < step; i++) // 세로로 된 기준 컬럼데이타를 가로로 복사함.
                {
                    if (sourceTb.Rows.Count <= rowIndex + i) break;
                    values.Add(sourceTb.Rows[rowIndex + i][sRotColumnIndex]);
                }
                dt.Rows.Add(values.ToArray<object>());
                values.Clear();
            }
            return dt;
        }


    }
}