처음부터 그럴려고 한 것은 아니다...
그냥 아무 생각없이 한번 해본다는 것이 어쩌다가 여기까지 왔다.

워낙 게으른 탓에 쉽게 쉽게 하나 해볼려다가
제발등을 찍고 말았다.

블럭방을 운영하고 있었다.
엑셀로 짠 프로그램으로 그럭저럭 운영을 했다.
별 불편함을 못느꼈다.

그런데...
갑자기 한 어린친구가 엄마를 불러달랜다.
이런 전화번호가 없다.
그래서 열심히 회원리스트 장부를 뒤졌다..
없다....
그래서 가입신청서를 열심히 뒤져서 찾았다...

그런데 찾은 기쁨보다 "꼭 이렇게 어렵게 찾아야 하나...너무 힘들다"
이게 불행의 씨앗이다.

"그래 한번에 모든것을 해결할 방법을 찾자"

이렇게 시작된 것이 블럭방 관리 프로그램인 "블럭노리"다

처음 시작은 그랬다.

 


난 MFC개발자에서 출발해서 어렵다고 쉬운길로 가자고 웹개발자로 전환한 게으른 개발자였다.
그래서 처음엔 웹베이스로 한번 구상해보자 하고 시작했다.

난 MS를 욕하면서도 MS에 물들은 그런 개발자였나 보다.

먼저 복잡한것은 너무 싫었다.
쓰지도 않는 기능, 아주 가끔씩 쓰는 기능 그러나 없어도 별반 힘들지 않는 기능들은 만들지 말자 하면서 열심히 구상을 했다

가장 기본이 되는 기능만 만들자.
그럼 쉽게 만들겠지...
그런 생각으로 열심히 구상하고 프로그램 설계도 그리고 기능기획하고...

그러다 보니 궂이 이걸 웹으로 해야할까...
웹으로 하면 서버있어야 하는데..
DB도 돈주고 사던지 임대하던지 해야하는데...
호스팅 하면 매달 돈나가는데...

여기에 생각이 미치자 로컬로 만들어보자
그러면 웹으로 못하는데...

그래서 찾아봤다..

옛날 생각해서 VC++을 먼저 봤다
근데 난 6.0을 끝으로 손을 놨는데...없다....
이런 요즘은 대부분 Visual Studio 2005이상이다...
아니 Visual Studio 2008이나 Visual Studio 2010을 쓴다고 한다..

그래서 Visual Studio 2010을 설치했다...
너무 생소하고 이질적으로 느껴졌다...
이럴바에는 최신버전으로 한번 설치해보자
그래서 Visual Studio 2012를 설치했다...

DB는 무엇으로 할까...
로컬로 하자면....
MS ACCESS가 어떨까...
괜찮을것 같은데...
구글링을 했더니 2기가 이상이면 문제가 될 소지가 있단다...

쓸데없는 고민에 휩싸였다...
사실 DB로 2기가 안될것을 알면서 고민을 했다...
그래서 구글링을 했더니 SQLite를 쓰란다...
알았다...쓸께...

그런데 어떤 언어로 개발하지...
VC++은 너무 어려워....

그래서 VB.NET로 가서 해보기로 했다...
예전에 조금했으니깐...
근데 이것도 생소하다...
6.0이후로 너무 바뀌었다

그럼 옛날걸 설치하고 할까...
그래...
그래서 visual studio6.0을 구해 설치했다...
근데 또 마음이 바뀌었다...
델파이나 파워빌더가 낫지 않을까...
열심히 책을 찾아봤다
2005년 이후의 책이 없다...
이런...그럼 이제 델파이도 한물갔나...

그냥 Visual Studio 2012로 해보자
그럼 어떤 언어를 쓸까...
옆에서 C#으로 해보란다...
귀가 얇다...
그래서 C#으로 하기로 했다...

그래서 또 책을 찾았다...
다행히 회사에 책이 한권 굴러다닌다.
삼양미디어에서 나온 "C#.NET 프로그래밍"

한번 볼까...
이런 기초내용부터 너무 지루하다
언제 이 책한권을 다 읽지...
난감하다...

그래
그냥 만들어보자

그래서 구글링을 했다..
소스를 무지 구했다
약 200메가 정도 구했다

열심히 분석했다...

그리고 바로 Visual Studio 2012를 열고 개발을 시작했다...
무모했다...
바로 벽에 부딪히고 말았다...
그게 벌써 한달전이다...
우여곡절끝에 다 만들었다...

그리고 깨달은점...

책은 팔아먹을려고 쓸데없는 사설을 너무 많이 적어서 처음부터 질리게 한다.
둘째 무식하면 안된다...계획도 엉망이 되고
몸은 축난다..
셋째 게으르면 안된다...
쉽게 갈려다가 결구 200메가나 되는 소스를 전부 분석해버렸다...

다 만들고 났더니...
이런 이번엔 셋업을 해야 한단다...
그냥 Visual Studio 2012에서 제공하는 배포프로그램을 사용할까...

안된단다..저작권땜시

그래서 찾은게 NSIS...

이런!!! 스크립트가 너무 어렵다...
결국 개고생하면서 겨우 만들었다...

다음엔 만들지 말아야지...
그러면서 벌써
다음에 뭘 만들지 고민하기 시작했다...

난 안되나 보다...

top


블럭노리 탄생배경

 

자유블럭방을 실제로 운영을 하면서 회원관리를 노트로 진행하였습니다.
일단 소규모였기 때문에 노트로 관리한다고 하여도 운영에 어려움이 있을 정도는 아니었습니다
그래서 회원가입 신청서, 충전관리, 일일회원 입출입 기록관리 등을 노트를 책처럼 엮어서 사용을 했습니다

처음에는 그럭저럭 무리없이 운영을 했는데 시간이 지날수록 관리가 점점 어려워졌습니다.
특히 기록관리에 대한 부분이 상당히 어려웠습니다.
그리고 정산 부분을 할때 마다 계산이 어려웠습니다.

그래서 처음엔 그냥 자동으로 계산만 해주는 프로그램을 만들어보자 하고 엑셀을 만들었습니다
그래서 회원인 경우 회원번호, 이름, 입실시간, 퇴실시간, 정산금 등을 자동으로 계산하도록 만들었습니다.
그럭저럭 사용할만하였습니다
그런데 이게 또 내용이 많아지니깐 사용이 힘들어지더라구요
첫번째가 충전회원이 많아지니깐 회원카드를 가지고 오지 않은 경우 회원번호를 찾는게 쉽지 않더라구요
또한 회원번호를 알고 있더라고 부모님 전화번호를 모르니깐 회원이 그만한다고 부모님께 연락해달라고 할때마다 회원가입장부를 뒤져서 전화번호를 찾는 소모적인 시간을 가졌습니다.
두번째가 노트와 엑셀을 병행하다보니 서로 매칭되는 부분을 찾기위한 시간을 너무 많이 허비하게 되었어요
기록의 객관성도 결여되었고...

그래서 돈을 주더라도 관리프로그램을 하나 사서 하자 하는 마음으로 열심히 구글링을 했습니다.
그런데 구미에 딱 맞는 프로그램은 없고 있더라고 프렌차이즈에 가입하면 설치해준다고 하더라구요
아니면 여러가지 복합적인 관리프로그램 중 하나를 이용해서 관리하면 된다고 하더라구요

특히나 레고, 가베, 로봇 등 여러가지를 모두 사용하는 프로그램을 사서 써야 하더라구요
가격도 비싸고...어떤 것은 월 고정비용을 지출하면서 사용해야 했습니다
그런데 그런 프로그램도 돈을 바라보고 한 것이라서 그런지 알바들이 사용에 어려움을 겪는것을 보고 차라리 간단하게 만들어보자 하는 마음으로 시작을 하였습니다
최대한 단순하고 최대한 쉽게 만들자가 첫번째 목표였습니다

어차피 판매용 솔루션이 아니니깐 그냥 내 구미에 맞게 만들고
우리 블럭방에서 알바들이 쉽게 이용하면 되지 않을까 해서 만들었고
현장에서 사용해본 결과 좋다는 반응이 많아서 그럼 나와 비슷한 고민을 하는 사람들을 위해 공개하자 하는 생각을 했습니다

나름 개발쪽일을 하면서 아내의 일을 도와주는 형태로 하다보니 장점이 있었습니다.
예전부터 Visual C++을 한 기억이 있어서 쉽게 C#을 접할 수 있었고
허접하나마 하나 개발하게 되었습니다
관리자에서 시간당 가격을 변경하도록 해야 하는 부분을 놓쳐서 그 부분을 추가하여 셋업프로그램을 만들고 이렇게  허접하나마 공개합니다
혹시 도움이 될지 모르겠습니다

 

 

 

블럭노리 1.0베타 :

 

 

BLOCKNORI_Setup.zip

 

 

프로그램에 필요한 사전 설치 파일을 포함시켰다.

.Net Framework4.5

SQLite .net Framework4.5 버전용


블럭노리 개발 개요

 

1. 복잡하지 않고 단순하며 쉽게 사용할 수 있을 것
2. 간단한 설명만으로도 사용이 가능할 것.
3. 인터넷 환경이 아니더라도 이용가능할 것
4. 데이타의 외부 유출이 되지 않게 DB를 로컬로 관리할 것
5. 비용의 부담이 적은 정도의 수준으로 사용가능하게 할것

 

블럭노리 기능 및 효과

 

1. 일일 자유 회원 관리  및 정산
2. 시간 충전회원 등록, 수정 및 정산
3. 시간 충전 정보관리 기능 및 변경
4. 회원 유효기간 관리 및 변경
5. 블럭방 이용 기록 관리(충전회원에 한함)
6. 블럭제품 등록 및 관리
7. 관리자 추가 등록 및 관리
8. 목록에 대한 엑셀 다운로드 기능제공
9. DB에 대한 자동 백업 기능 제공

 

블럭노리 설치 환경

 

1. 운영체제 : Windows XP이상
2. .NET Framework 3.5
3. DBMS : SQLite 3.0

 

개발환경


1. 개발툴 : Visual Studio 2010
2. .NET Framework 3.5 SP1

3. DBMS : SQLite 3.0

 

블럭노리 설치정보


1. 설치 디렉토리는 C:\Program Files\Blocknori 디렉토리에 설치가 됩니다.
2. 설치파일은 설치디렉토리 루트에 blocknori.exe,System.Data.SQLite.dll 2개가 설치되고
   하위에 database디렉토리에 blocknori.db파일이 설치가 됩니다
   설치 디렉토리 하위의 config 디렉토리에 config.ini 환경설정파일이 설치됩니다
   환경설정파일에는 최초 30분 사용시의 금액과 시간당 사용금액을 저장하게 되어 있습니다
   이부분을 수정하시면 블럭방 운영가격을 조정할 수 있습니다
   기본 입시간료을 30분으로 지정하였습니다
   입실 후 최초 30분에 해당하는 금액은 HalfMoney=가격 이렇게 되어 있습니다
   다른것은 수정하시면 안되고 가격부분만 숫자(쉽표나 문자가 있으면 안됩니다)로
   입력해주시면 됩니다
   그리고 HourMoney=가격 이부분은 시간당 가격을 말하는 것입니다
   이부분 또한 숫자로 가격을 수정해주시면 됩니다
   기본으로
   [MONEY]
   HalfMoney=3000
   HourMoney=4500
   되어 있습니다.
   그리고 DB백업을 위한 DBBackup디렉토리와 엑셀저장디렉토리인 excel디렉토리 이렇게 구성되어 있습니다
3. 프로그램 그룹은 블럭노리로 구성됩니다.
4. 사용법은 기존 강좌를 참조하시면 됩니다

5. 환경설정을 제외하고 수정없이 사용하는데는 아무런 제약이 없습니다.

6. 초기 접속 로그인 정보 :

   아이디 : admin

   비밀번호 : rhksflwk

비밀번호는 한글로 "관리자"입니다

 

사용해보시고 에러나 버그가 있으면 댓글 부탁드립니다

 

감사합니다

top


이번포스트에서는 회원유효기간 관리와 블럭제품관리에 대한 내용을 기술할려고 한다.

목록들은 대부분 대동소이하다.

각각의 특징에 따른 필드의 차이는 있지만 대부분 프로그램밍적으로는 비슷하다

 

- 회원유효기간관리 목록

 

 

 

제품유효기간은 타이틀별로 Sort가 필요해서 페이징을 없앴다.

리스트의 타이틀을 클릭하면 항목에 따라 정렬이 된다.

스트링으로 정리를 하는 형식이라 숫자에 대한 정렬리 문제가 있었으나

인터넷을 통해 그 문제도 해결하였다.

이부분이 참 잘 안풀리던차에 구한 소스다

 

소스를 보자면

        // 숫자의 정확한 sort를 위한 StringLogicalComparer 코드

        public class StringLogicalComparer
        {

            public static int Compare(string s1, string s2)
            {

                //get rid of special cases

                if ((s1 == null) && (s2 == null)) return 0;

                else if (s1 == null) return -1;

                else if (s2 == null) return 1;

 


                if ((s1.Equals(string.Empty) && (s2.Equals(string.Empty)))) return 0;

                else if (s1.Equals(string.Empty)) return -1;

                else if (s2.Equals(string.Empty)) return -1;

 


                //WE style, special case

                bool sp1 = Char.IsLetterOrDigit(s1, 0);

                bool sp2 = Char.IsLetterOrDigit(s2, 0);

                if (sp1 && !sp2) return 1;

                if (!sp1 && sp2) return -1;

 


                int i1 = 0, i2 = 0; //current index

                int r = 0; // temp result

                while (true)
                {

                    bool c1 = Char.IsDigit(s1, i1);

                    bool c2 = Char.IsDigit(s2, i2);

                    if (!c1 && !c2)
                    {

                        bool letter1 = Char.IsLetter(s1, i1);

                        bool letter2 = Char.IsLetter(s2, i2);

                        if ((letter1 && letter2) || (!letter1 && !letter2))
                        {

                            if (letter1 && letter2)
                            {

                                r = Char.ToLower(s1[i1]).CompareTo(Char.ToLower(s2[i2]));

                            }

                            else
                            {

                                r = s1[i1].CompareTo(s2[i2]);

                            }

                            if (r != 0) return r;

                        }

                        else if (!letter1 && letter2) return -1;

                        else if (letter1 && !letter2) return 1;

                    }

                    else if (c1 && c2)
                    {

                        r = CompareNum(s1, ref i1, s2, ref i2);

                        if (r != 0) return r;

                    }

                    else if (c1)
                    {

                        return -1;

                    }

                    else if (c2)
                    {

                        return 1;

                    }

                    i1++;

                    i2++;

                    if ((i1 >= s1.Length) && (i2 >= s2.Length))
                    {

                        return 0;

                    }

                    else if (i1 >= s1.Length)
                    {

                        return -1;

                    }

                    else if (i2 >= s2.Length)
                    {

                        return -1;

                    }

                }

            }

 


            private static int CompareNum(string s1, ref int i1, string s2, ref int i2)
            {

                int nzStart1 = i1, nzStart2 = i2; // nz = non zero

                int end1 = i1, end2 = i2;

 


                ScanNumEnd(s1, i1, ref end1, ref nzStart1);

                ScanNumEnd(s2, i2, ref end2, ref nzStart2);

                int start1 = i1;

                i1 = end1 - 1;

                int start2 = i2;

                i2 = end2 - 1;

 


                int nzLength1 = end1 - nzStart1;

                int nzLength2 = end2 - nzStart2;

 


                if (nzLength1 < nzLength2) return -1;

                else if (nzLength1 > nzLength2) return 1;

 


                for (int j1 = nzStart1, j2 = nzStart2; j1 <= i1; j1++, j2++)
                {

                    int r = s1[j1].CompareTo(s2[j2]);

                    if (r != 0) return r;

                }

                // the nz parts are equal

                int length1 = end1 - start1;

                int length2 = end2 - start2;

                if (length1 == length2) return 0;

                if (length1 > length2) return -1;

                return 1;

            }

 


            //lookahead

            private static void ScanNumEnd(string s, int start, ref int end, ref int nzStart)
            {

                nzStart = start;

                end = start;

                bool countZeros = true;

                while (Char.IsDigit(s, end))
                {

                    if (countZeros && s[end].Equals('0'))
                    {

                        nzStart++;

                    }

                    else countZeros = false;

                    end++;

                    if (end >= s.Length) break;

                }

            }

 


        }

 

위의 소스를 이용하여 sort문제를 해결하였다

 

- 회원유효기간 수정

 

 

 

회원유효기간 변경은 간단하다.

사용방법은 단지 유효기간을 늘려주거나 줄여주는것이외의 기능은 없다

회원들이 시간충전을 하고 유효기간내에 다 사용을 못한 경우 임의로 유효기간을 연장시켜줄수 있는 기능을 만들어준것이다

 

- 블럭방 이용관리

 

 

블럭방이용관리는 시간충전을 한 고객이 혹시 클레임이라도 제기하면 그 사람의 히스토리를 일목정연하게 보여주기 위해서 만들어졌다.

회원검색을 하면 그 사람이 사용한 시간에 대한 정리를 해준다.

이것으로 사용시간 패턴을 구할 수 있다.

그래프로 그려볼까 하다가 특별히 쓰일일이 없을것 같아 포기했다.

 

- 블럭제품관리

 

 

블럭제품관리는 목록보기는 대부분 같이 때문에 특별히 설명할 부분이 없다

단지 여기서는 현재 사용하고 있는 목록과 필요가 없거나 파손으로 폐기처분한 목록에 대한 리스트업을 할 수 있도록 기능을 추가하였다.

 

 

- 블럭제품 등록, 폐기, 수정, 삭제

 

 

 

마지막으로 블럭제품의 등록, 폐기, 수정, 삭제에 대한 기능을 삽입해줬다.

상기 화면에서 보면 블럭제품의 등록도 최소한의 정보만 등록하도록 만들었다.

원체 복잡한것을 싫어해서...그리고 현장에서도 복잡하게 등록할 일이 없는것 같아서 최소의 정보만을 입력토록했다.

이 부분에서 정산 부분을 연동시킬까도 생각했지만 정산까지 가면 너무 솔루션이 무거워지고 그러다 보면 아무나 가져다가 무료로 사용하게 하자는 정책에서 벗어날것 같아 제외하고 추후 필요하다면 정산 솔루션을 별도록 만들어서 무료배포를 해볼까 구상중이다.

 

다음 포스트에서는 관리자 등록과 엑셀 다운로드에 대해서 정리하고 나면 기능이나 화면설명은 끝이 난다.

 

참고로 이 프로그램은 종료와 동시에 한달동안의 DB는 자동으로 백업이 되도록 구성되어 있다.

한달이 지난 것은 순차적으로 지워지고 매일매일 종료시에 데이타베이스가 백업이 된다. 물론 로컬에 백업이 된다.

다음 포스트까지 기능 설명 후에 각각 기능에서 기억에 남는 소스를 추려서 다시 소스 공개를 하고 셋업을 위해 NSIS를 사용했는데 혹시나 시간이 되면 간단하게 NSIS에 대한 설명을 하고  마무리할려고 한다.

다음 포스트를 기대해주시고

 

내용을 다른 곳으로 많이 공유해주시면 고맙겠습니다....

추천도 팍팍...

좋아요도 팍팍...

광고도 팍팍....

top