본문으로 바로가기
바코2://#25. 아이템, 재고 관련 (4) 공급주문 폼 - 주문 번호 생성하기 - 바보처럼코딩하기

바코2://#25. 아이템, 재고 관련 (4) 공급주문 폼 - 주문 번호 생성하기

반응형

주문번호? 어떻게 접근할까?

주문 번호에 관련된 글은 아래 링크를 달았습니다.

바코2://#23. 아이템, 재고 관련 (3-1) feat. 내게 필요한 필드 찾기

 

주문 번호가 왜 필요한가?

우선 고유 번호 내지는 고유 코드에 대한 개념이 필요합니다. (이하 고유 번호로 통칭합니다. )

고유번호는 겹치지 않는 번호나 코드라고 보시면 됩니다.

이 유일의 개체를 만들어서 만들어내는 프로젝트나 작업내용을 관리 할 수 있습니다.

 

만약 배달해야할 주소가 무슨아파트가 101호인데, 옆집도 그 윗집도 그 옆집도 101호라면 일일이 다 찾아야 주문한 사람을 찾을수 있겠지요? 또는 계좌번호가 같은 사람이 100명이면 100명의 이름을 조회해야 그 중에서 찾을 수 있을텐데, 그 중에 이름이 같은 사람이 있다면? 다른 방법으로 조회해야겠지요?

 

이렇듯 원하는 정보를 바로 찾을 수 있게 만드는것이 고유번호의 역할입니다. 아래의 내용은 자신이 고유번호를 생성할때 고민해야할 부분 및 과정에 대한 내용입니다. 

 

접근하기 쉬운 고유번호

만들기 쉽다기 보다는, 읽기 쉬운 작은 정보를 가진 일련 번호는 날짜뒤에 그 날의 몇번째 건인지 확인하는 방법을 우선은 추천드립니다. (추천일뿐, 추후에 이 일련번호도 개인의 상황에 맞춰서 개발 및 사용하시길 권합니다.)

 

외관: yymmdd001

yymmdd002 이런식으로 증분됩니다. 이렇게 해 놓으면 최소 100년동안 겹치는 고유번호는 없습니다.

예) 00년01월 01일 부터 99년 12월 31일까지 겹칠 숫자는 없으니 100년 동안에는 겹칠일이 없습니다.

 

형식: 220111 (숫자? or 문자?)

* 형식에 대한 이해와 확장에 대한 고민

위의 형식은 숫자로 관리해야 좋을까요? 문자로 관리해야 좋을까요?

 

1) 보이는 건 숫자입니다만, 00년을 기준으로 사용하게되면 00년 1월 1일은 숫자로 관리하게 되면 000101이 아닌 101로 표시됩니다.

2) 100년간 지금 만든 전산을 그대로 사용하고 있을 확률도 희박합니다. 앞으로 78년 정도를 더 사용한다는 말인데... 그 사이에 변화가 있던지 다른 시스템을 도입하지 않을까요?

3) 확장성에 대한 고찰이 있어야 추후 변화에 대응하기 좋습니다.  예를 들어 20220101 보다는 220101이 읽기 좋고, 220101 보다는 0101이 읽기 편합니다. 자릿수가 적을 수록 일련번호를 빨리 읽고 처리하기 좋습니다. 확장성에 관련해서는 기록은 20220101으로 하되, 폼이나 레포트에서 보이는건 220101로 변경하는 것도 가능하다는 점도 같이 생각하시면 조금 더 원하는 일련번호를 만드는데 제약이 덜하지 않을까 생각됩니다.

4) 사용방법에 따른 차이

검색을 하는데 범위 검색이 가능한 형식이 있고, 그렇지 못한 형식이 있습니다. (이것도 어떻게 소스를 다듬고 치환하냐에 따라서 변화가 생길 수 있겠습니다.) 숫자의 경우 0~999+ 까지의 순서가 있고, 날짜의 경우도 1월1일 부터 12월 31일까지의 순서가 이미 정해져 있습니다. 문자의 경우 별도의 설정을 안해준다면 해당문자로만 인식합니다.

 

튜토리얼에서 사용할 형식

이 튜토리얼에서는 간단하게 접근하기 위해서 

최소 50년간 사용할리 없다는 가정하에 숫자형으로 진행할 예정입니다.

22010101=날짜(220101)&해당일의주문번호(01) 이런식으로 총 8자리의 숫자로 일련번호를 진행합니다. 주문건이 99건이 넘는 분들은 001같이 뒷번호를 3자리로 만드실 수 있습니다.

 

사용 할 함수들 (의역이 있습니다.)

Format(Expr, "Format"): 포맷 함수

You can use the Format property to customize the way numbers, dates, times, and text are displayed and printed. Read/write String. : 숫자, 날짜, 시간, 텍스트가 원하는 방법으로 string(문자열)로 변환됨.

 

DMax (Expr, Domain, Criteria): 디멕스 함수

You can use the DMax function to determine the maximum value in a specified set of records (a domain).

: 기록중에서 가장 큰 값을 정의함, 찾아냄(?)

 

DCount (Expr, Domain, Criteria): 디카운트 함수

You can use the DCount function to determine the number of records that are in a specified set of records (a domain). : 찾는 조건의 레코드 갯수를 정의함, 1~5까지 숫자개 몇개니? 5개. 이런식.

 

Clng(str) : Change Long : 반환값을 long으로 내놓음

Long: -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 사이의 숫자.

 

Right(문자열,추출문자의갯수)

 

 

첫번째 시도. 날짜를 포맷함수(Format())를 사용해서 형식 바꾸기 (2022/01/01 ---> 220101)

1. 테스트를 위해서 샘플폼에 아래와 같이 오브젝트를 만들어줍니다.

  • 입력(텍스트 필드)
  • 결과(텍스트 필드)
  • 변환(버튼) 

입력 필드를 선택하고 형식을 간단한 날짜로 바꿔 줍니다.

 

2. '샘플' 테이블을 하나 만들어 주겠습니다.

  • ID: 일련번호
  • 날짜: 날짜/시간, 간단한 날짜
  • 시리얼: 숫자, 정수

3. 변환 버튼 클릭 이벤트에 코드를 삽입하겠습니다.

Private Sub 버변환_Click()
결과 = 입력
End Sub

 

4. 텍스트 필드 '입력'을 클릭하면 달력 모양이 뜹니다. 아무 날짜나 선택해서 넣어줍시다.

5. 변환 버튼을 눌러줍니다.

입력 값과 같은 결과 값을 반환 했습니다.

6. format함수를 사용해서 형태를 변경해보겠습니다.

Private Sub 버변환_Click()
'결과 = 입력
결과 = Format(입력, "yymmdd")

End Sub

7. 저장 부분을 추가해보겠습니다.

변환 파트와 저장 파트로 나눠서 진행합니다.

Private Sub 버변환_Click()
'----[변환 파트]
'결과 = 입력
결과 = Format(입력, "yymmdd")


'----[저장 파트]
CurrentDb.Execute "insert into 샘플 (날짜,시리얼) values(#" & 입력 & "#," & 결과 & ")", dbseechanages


End Sub

형식 변환을 하고 저장까지 한번에 되는 버튼 이벤트를 경험하셨습니다.  

위에서 적으셨던 코드는 주석처리하셔서 비활성화 or 삭제를 하시고 이제 아래의 코드를 연습해보시겠습니다.

 

두번째 시도. 날짜에 6자리(220111)에 거래번호 뒷 2자리(01) 만들어 붙이기

시작전에 위에서 저장을 해본 ID 1의 데이터 행을 삭제해줍니다.

  • 조건 추가: '거래번호는 자동 생성하며, 날짜는 작성일자 기준으로 생성한다.'는 원칙을 적용해서 진행

이 밑으로는 코드 주석형식으로 설명을 진행하겠습니다.

총 3가지 파트(앞자리, 뒷자리, 합치기) 로 시리얼을 구성할 예정입니다.

(보시면서 붙여 넣기 할 수 있도록 작성중입니다.)

 

녹색 글씨는 VBA 상 주석이고, 

검은 글씨는 코드

하이라이트 부분은 설명 부분입니다.

 

1. 거래내역 검색 틀 만들기 


'----[변환 파트]

Dim 앞자리 as String, 뒷자리 as String, 합치기 as Long '사용할 3가지 단어에 대한 선언

앞자리 = format(Date,"yymmdd") '날짜는 생성 당일로만 설정한다. 원하는 날짜로 바꾸고 싶은 경우는 Date 대신 원하는 날짜 사용

 

'금일거래 내역이 있는지 확인( 있다면 금일 몇번째 거래까지 있었는지 확인)

'Dcount 함수는 일정 조건에서 데이터가 몇개 있는지 세어준다.

'아래코드의 의역은 이런식으로 진행한다. ID가 몇개인지 세라, 샘플이라는 테이블에서, 날짜조건이 오늘과 같은.

 

If Dcount("ID","샘플", "날짜 = #" & Date & "#") = 0 Then     '만약 오늘 날짜와 같은 ID의 갯수가 0이라면; 없다면

 

else  '만약 오늘 날짜와 같은 ID의 갯수가 0이 아니라면; 있다면

 

end if

 

'----[저장 파트]


2. 뒷자리 계산하기


'----[변환 파트]

Dim 앞자리 as String, 뒷자리 as String, 합치기 as Long

앞자리 = format(Date,"yymmdd")

If Dcount("ID","샘플", "날짜 = #" & Date & "#") = 0 Then

뒷자리 = format(Dcount("ID", "샘플", "날짜 = #" & Date & "#") + 1, "00")   

'Dcount("ID", "샘플", "날짜 = #" & Date & "#") +1

'위 코드의 값을 살펴보겠습니다.

'Dcount("","","") = 0 입니다. 위의 조건이 Dcount("","","") = 0 일때의 조건이기 때문입니다.

'그렇다면 위 코드의 값은 0+1 이므로 1이 됩니다. 

'이걸 format()을 씌워 "01"로 만들어 줍니다.

'이 조건에서 뒷자리의 값은 항상 01이니 뒷자리 = 01로 해주셔도 무방합니다.

 

else

뒷자리 = Format(DMax("right(시리얼,2)", "샘플", "날짜 = #" & Date & "#") + 1, "00")

'DMax("right(시리얼,2)", "샘플", "날짜 = #" & Date & "#") + 1

'위 코드의 값을 살펴보겠습니다.

'의역을 해서 문장을 만들어보자면, "샘플 테이블 안에서 날짜가 같은 마지막 2자리 값중에 가장 큰 값을 찾아라 그리고 거기에 1을 더해라" 입니다.

'해당일에 거래 기록이 있다면 아래와 같이 시리얼들이 생성되어 있을겁니다.

ID 날짜 시리얼
1 22/01/11 22011101
2 22/01/12 22011201
3 22/01/12 22011202

' 오늘 날짜 기준으로 22/01/12 이면 주황색 글씨인 2개의 시리얼이 존재하네요.

'Right(시리얼,2) = Right(22011101,2) = 01 ; right 함수는 오른쪽의 몇개의 글자를 가져올지를 주문하는 코드입니다.

'이 테이블상에서 Right(시리얼,2)만 보면 01이 2개, 02가 1개 있습니다.

'동시에 발동하는 조건은 날짜가 오늘 날짜(22/01/12)와 같은 시리얼의 오른쪽 2번째 숫자들 입니다.

'그 결과값은 는 주황색으로 글씨를 적은 01과 02가 됩니다. 숫자로 적혀 있으니 1과 2로 되겠군요.

'위 코드에서 그렇다면 Dmax( ) 는 1과 2중에 큰 값을 찾습니다. 여러개면 그 중에서 가장 큰 값을 찾게 됩니다.

'위 코드를 뜯어보면 Format(Dmax( )+1, "00"); Dmax( )=2이므로 Format(2+1, "00")

'2+1=3 이므로 ; Format(3, "00")

'format을 씌웠으므로; Format(3, "00") = 03 이 됩니다.

'결국 뒷자리 = 03이 계산됩니다.   

end if

'----[저장 파트]


3. 합치기


'----[변환 파트]

Dim 앞자리 as String, 뒷자리 as String, 합치기 as Long

앞자리 = format(Date,"yymmdd")

If Dcount("ID","샘플", "날짜 = #" & Date & "#") = 0 Then

뒷자리 = format(Dcount("ID", "샘플", "날짜 = #" & Date & "#") + 1, "00")   

else

뒷자리 = Format(DMax("right(시리얼,2)", "샘플", "날짜 = #" & Date & "#") + 1, "00")

end if

합치기= Clng(앞자리&뒷자리)

'----[저장 파트]

 

'위에서 우리는 22년01월22일 기준으로 뒷자리가 03이 출력된다는걸 확인했습니다. 

'문자형인 앞자리와 뒷자리를 이어주는 역할을 &가 해줍니다. (문자&문자)

'앞자리&뒷자리 = 220122&03 = 22012203이됩니다.'문자형인 22012203을 Clng로 숫자형(숫자형중에 Long)으로 변형해주면 숫자인 22012203이 합치기 값이 됩니다.


4. 저장하기


'----[변환 파트]

Dim 앞자리 as String, 뒷자리 as String, 합치기 as Long

앞자리 = format(Date,"yymmdd")

If Dcount("ID","샘플", "날짜 = #" & Date & "#") = 0 Then

뒷자리 = format(Dcount("ID", "샘플", "날짜 = #" & Date & "#") + 1, "00")   

else

뒷자리 = Format(DMax("right(시리얼,2)", "샘플", "날짜 = #" & Date & "#") + 1, "00")

end if

합치기= Clng(앞자리&뒷자리)

'----[저장 파트]

CurrentDb.Execute "insert into 샘플 (날짜,시리얼) values(#" & 입력 & "#," & 합치기 & ")", dbseechanages

 

'여기서 합치기를 바로 대입하면 폼에서 출력이라는 텍스트 필드가 없어도 됩니다.

'하지만 궁금한걸 못참죠. 결과가 어떻게 됐는지 폼상에서 눈으로 확인하려 한다면, 결과 = 합치기를 아래 코드와 같이 합치기 아래 넣어주기만 하면 됩니다.


Private Sub 버변환_Click()

'----[변환 파트]

Dim 앞자리 As String, 뒷자리 As String, 합치기 As Long

앞자리 = Format(Date, "yymmdd")

If DCount("ID", "샘플", "날짜 = #" & Date & "#") = 0 Then

뒷자리 = Format(DCount("ID", "샘플", "날짜 = #" & Date & "#") + 1, "00")

Else

뒷자리 = Format(DMax("right(시리얼,2)", "샘플", "날짜 = #" & Date & "#") + 1, "00")

End If

합치기 = CLng(앞자리 & 뒷자리)

결과 = 합치기


'----[저장 파트]

CurrentDb.Execute "insert into 샘플 (날짜,시리얼) values(#" & 입력 & "#," & 합치기 & ")", dbseechanages

End Sub

정상적으로 잘 작동합니다.

 

 

 

 

 

 

[이전 글]: 바코2://#24. 아이템, 재고 관련 (3-2) 공급주문 폼

[다음 글]: 바코2://#26. 아이템, 재고 관련 (5) 공급주문 폼 - 폼 구성

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유