프로그램을 짜는 것은 논리(로직)만 만들어지면, 그다음은 그것을 해당 언어의 문법에 맞게 구성해 나가면 됩니다.
구구단 어릴 적 많이 외웠던 것인데, 프로그램으로 만들어보면 기초 쌓는데 도움이 될 듯하여 골랐습니다.
만들 모양은 아래와 같습니다. 매크로 기록하기에서는 2단, 3단 등 단수 제목을 복잡해서 뺐는데, 프로그램을 짤 때는 그렇게 어렵지 않아 넣었습니다.
[프로그램 로직]
① A1에 '구 구 단'이라고 입력하고, A1에서 W1까지 범위를 '병합하고 가운데 정렬'한 후, 글자크기를 16, 굵게로 설정합니다.
② A3에 '2 단'이라 입력하고, A3에서 E3까지 병합하고 가운데 정렬한 후, 글자를 굵게 합니다.
③ 2단은 A4부터 E12까지 입력하는데, A열은 모두 2이고, B열은 *, C열은 1부터 9, D열은 =, E열은 =A4*C4식으로 입력합니다. 다른 열과 달리 C열은 한 줄씩 내려가면서 숫자가 1씩 증가합니다.
④ *와 =은 가운데 정렬을 합니다.
⑤ 프로그램에서는 변수의 관리가 중요합니다. 구구단에서 변하는 것은 단수와 그다음 곱하는 수, 시작 행과 열이 있습니다.
2단에서 9단까지 바뀌고, 곱하는 수도 1에서 9까지 바뀌며, 시작하는 행이 처음에는 3인데, 다음은 11이 증가한 14가 되며, 열은 처음은 A열, 1이지만 단수에 따라 6개씩 떨어진 열이 됩니다.
[프로그램 준비]
1. 변수 선언
① 변수 선언을 할 때는 변수명과 변수 타입을 지정하며 형식은
dim 변수명 as 변수 타입
입니다.
② 변수명은 예약어, 다시 말해 VBA에서 사용하는 명령어와 속성, 함수 등은 사용하지 못합니다. 예를 들어 string, select, true 등이 있습니다. 또한 변수명은 문자로 시작해야 하며, 숫자로 시작하면 안 됩니다.
③ 변수명은 대, 소문자를 구분하지 않지만 대,소문자를 구분해서 사용하는 것이 인식하기 쉽습니다. 따라서, j나 J나 같은 값을 반환하며, j로 변수 선언 후 J로 다시 변수를 선언하면 에러가 납니다.
④ 변수 타입은 문자(String), 숫자(정수 Integer, 더블 Double), 날짜(Date), 개체(Object, 범위 Range), 논리 값(Boolean), 가변 데이터(Variant) 등이 있습니다.
2. 변숫값 대입
① 변수명 = 값
형식으로 입력하며, 순증 된 값을 대입할 때는 a=a+1, a=a+2라고 표시합니다. 다른 언어의 경우에는 a++라는 표현을 사용하지만 VBA에서는 안됩니다.
② 다른 변수명과 연결해서 변수 대입도 가능합니다. 예를 들어 a=b+1 표현식은 a란 변수에 b란 변수의 값에 1을 더한 값을 대입한다는 의미입니다.
3. 상수
가. 상수의 종류
변수는 값을 변화시킬 수 있는 반면, 상수는 고정된 값을 가지고 있는 수입니다. 사용자가 상수를 정의할 수도 있으며, 엑셀 VBA 자체에 내장된 상수도 있으며, 엑셀에 내장된 상수는 xl로 시작하고, vb에 내장된 함수는 vb로 시작합니다.
xl로 시작하는 내장 상수는 xlCenter, xlFillCopy, xlFillSeries, xlUnderlineStyleNone, xlThemeColorLight1, xlToRight, xlDown 등으로 유형별로 엄청난 수가 정의되어 있고,
vb로 시작하는 내장 상사는 vbRed, vbYes, vbYesNo, vbCrLf 등이 있습니다.
나. 사용자 정의 상수
사용자가 정의하는 상수는
const 상수명 as 타입 = 값
형식으로 지정합니다.
예시)
const pi as double = 3.141592
변수의 경우는
dim i as integer = 2
라고 변수를 선언하면서 값을 대입할 수 없는데,
상수는 고정된 값이므로 상수를 선언하면서 값을 대입할 수 있는 점이 다릅니다.
다. 엑셀 내장 상수
엑셀에 내장된 상수는 개발도구 - Visual Basic명령을 눌러 Visual Basic 에디터를 연 다음, 표준 도구 모음에서 '개체 찾아보기' 아이콘을 누른 후
(방법 1) 구성원 창에서 스크롤하거나, 구성원 중 아무거나 클릭한 후 알파벳을 누른 후 그 알파벳으로 시작하는 구성원으로 이동해서 원하는 것을 찾을 수 있습니다.
(방법 2) 찾아보기 입력 란에 찾으려고 하는 단어, 여기서는 xldown이라고 입력한 후 엔터 키를 누르면 해당 구성원이 표시됩니다.
상수 xlDown의 클래스는 xlDirection이고, 값은 -4121입니다.
개체 찾아보기 창을 닫으려면 VB 에디터 '창 닫기' 버튼 아래 작은 '창 닫기' 아이콘을 누릅니다.
4. 반복문
VBA에서 반복문은 For ~ Next, While ~ Wend, Do ~ Loop 등이 있습니다.
For ~ Next는 변수 값 구간 내에서 반복 실행하는 것이며, While ~ Wend와 Do ~ Loop는 조건이 충족되는 동안 반복 실행하는 것입니다. 구구단의 경우 둘 다 가능하지만 많이 사용하는 For ~ Next문을 사용하겠습니다.
for ~ next 문의 형식은
for 변수명 = 초기값 to 종료값 step 간격
실행문
next
이며,
'step 간격'은 간격으로 지정한 값만큼 간격을 두고 실행하라는 것으로 'step 간격'을 생략하면 간격은 1이 됩니다.
예를 들어 1부터 9까지 실행하는데 step 2라고 주면 1,3,5,7,9만 실행되고, 중간은 건너뜁니다.
[중첩 반복문]
for ~ next 문안에 for~next문을 넣을 수 있습니다.
그러면 이렇게 됩니다.
for 변수명1 = 초기값1 to 종료값1 step 간격1
실행문 1
for 변수명2 = 초기값2 to 종료값2 step 간격2
실행문2
next
next
위 반복문의 의미는 바깥 반복문이 한번 실행하는 동안 안쪽 반복문이 반복적으로 실행되고, 안쪽 반복문이 종료되면 바깥 반복문의 값이 증가되어 실행되는 식으로, 바깥 반복문이 종료되면 모든 반복문이 종료됩니다.
5. 조건문
조건문은 If와 Switch문이 있는데, 조건이 여러 개로 분기할 때는 if문을 사용하면 복잡하므로 switch문을 사용하는 것이 편리합니다. 구구단의 경우 복잡한 것이 없으므로 if문을 사용하겠습니다.
if 문의 형식은
if 조건문1 then
실행문1
else if 조건문2 then
실행문2
else
실행문3
end if
인데,
중간의 else문은 필요 없으면 사용하지 않아도 되며, if 조건 다음에 반드시 then을 넣어야 하는 점 주의하기 바랍니다.
6. 범위 지정
매크로 기록에서 범위 지정 시 range를 사용한다고 하면서 다른 것도 있다고 했는데, cells property를 사용할 수 있으며, offset을 결합할 수도 있습니다.
가. Range("a1") 형식
range("a1")이라고 고정된 셀을 지정할 수도 있고, range("a" & 변수) 식으로 a열을 유지하면서 행을 달리하는 가변적인 셀도 지정할 수 있는데, 연결할 때는 결합 연산자인 &를 사용합니다.
예를 들어 range("a" & b)라고 셀을 지정할 경우 변수 명 b의 값이 3이라면
range("a3")과 같습니다. 열은 고정이고, 행만 바뀔 때 사용하면 편리합니다.
나. Cells(row값, column값) 형식
formulaR1C1과 같이 셀 주소를 행과 열 숫자로 지정하는 방식입니다. 예를 들어 cells(3,2)라면 B3셀이 됩니다. 행이 먼저 오는 점 주의하기 바랍니다.
이것은 행과 열 둘 다 변수를 이용해 바꿀 수 있으므로, Range의 경우 행만 바꿀 수 있는 것에 비해 활용성이 높습니다.
다. Range와 Cells의 결합 사용
range안에 range를 넣을 수도 있고, range안에 cells를 넣을 수도 있습니다.
range(range("a1"),range("w1")).select
range(cells(1,1),cells(1,23)).select
위 표현식 모두 a1셀에서 w1셀까지 연속된 범위를 선택하라는 의미입니다.
중간이 :(콜론)이 아닌 ,(컴마)로 되어 있지만 연속된 범위를 선택하는 것입니다.
range(range("a1"),range("w1")).select 은 range("a1","w1").select 와 동일한 결과를 가져오므로 굳이 range안에 range를 쓸 필요는 없습니다.
a1과 w1 두 개의 셀만 선택하려면
range("a1,w1").select 라고 해야 합니다.
그러나, range("a1","w1").select 라고 하면 연속된 범위가 지정되니 구분해서 잘 기억해 두기 바랍니다.
라. 셀.offset(row값, column값)
셀을 기준으로 행과 열만큼 이동한 셀을 가리키는 방식입니다.
예를 들어 range("a4").offset(3,2)라고 하면 행이 3 내려가고, 열이 오른쪽으로 2 칸 이동하므로, c7셀이 됩니다.
row값은 +면 아래로, -면 아래로 이동하며,
column값은 +면 오른쪽, -면 왼쪽으로 이동합니다.
마. 전체 셀
Cells란 객체를 사용합니다.
cells.select라고 하면, 해당 시트의 모든 셀을 선택하라는 의미입니다.
7. 연산자
연산자란 사칙 연산자인 +, -, *, /가 있는데, *와 /가 학교 다닐 때 배운 것과 표시가 다릅니다.
그밖에 문자를 결합해주는 연산자인 &, 나머지를 구해주는 mod 연산자 등이 있습니다.
8. 비교 연산자
값을 비교하는 연산자로는 =(같다), <>(다르다), >(크다), <(작다), >=(크거나 같다), <=(작거나 같다)가 있습니다.
= 이란 같은지 판단하는 것이고, <>는 다른지, 같지 않은지 판단하는 것입니다. 다른 언어의 경우 =이 아니라 ==을 사용하고, <>이 아니라 !=을 사용하는 것과 다릅니다.
9. 속성 값
가. 한 개씩 대입
range("a1").font.size=16 또는 range("a1").font.bold=true
식으로 범위.객체명.속성=값 식으로 입력합니다.
나. 여러 개 한꺼번에 대입
여러 개의 값을 한꺼번에 대입하려면 with문을 사용합니다.
예컨대
with selection.font
.name="나눔 고딕"
.size=16
.bold=true
end with
10. 명령문( 메서드)
range("a1").select
A1셀을 선택하라는 명령입니다.
Cells.EntireColumn.AutoFit
모든 셀의 열 너비 입력된 글자의 너비에 맞춰 자동 맞춤하라는 명령입니다.
cells.delete
모든 셀을 삭제하라는 명령입니다.
Range("a1","w1").merge
a1셀에서 w1셀까지를 병합하라는 명령어입니다. 가운데 정렬은 별도의 속성으로 지정해야 합니다.
11. 주석 표시
VBA에서는 설명문을 추가하거나, 해당 문장을 실행하지 않을 경우 '(작은따옴표)를 문장 앞에 표시하면 주석 처리됩니다.
아래 '주석 블록 설정' 버튼을 누르면 해당 줄 처음에 작은따옴표가 입력되어 해당 줄이 주석 처리되고, '주석 블록 해제' 버튼을 누르면 주석 처리가 해제됩니다.
따라서, 줄에서 해당 부분 뒤만 주석 처리할 때는 수동으로 '(작은따옴표)를(작은 따옴표) 넣어야 합니다.
Else End If
If i Mod 4 = 1 Then
iRow = iRow + 11
iCol = 1
Mod 연산자는 나머지를 구하는 연산자로서
"i를 4로 나눈 나머지인 단수가 1이라면"이란 조건은
다시 말해 5단일 경우란 의미입니다.
5단이 되면
iRow에 'iRow에 11을 더한 값'을 대입하라는 것이므로 iRow값은 14가 되고, iCol은 1로 만들어 A열로 바꾸는 것입니다.
이 때는 변수의 값만 달라지고,
실제 적용은 위로 올라가서 i가 6이 됐을 때 적용되므로
6단이 A14셀로 부터 시작하게 됩니다.
Else
iCol = iCol + 6
란 5단이 아니면 iCol 값을 'iCol+6'으로 바꾸므로 6칸씩 오른쪽으로 이동하면서 단을 기록하라는 의미가 됩니다.
⑥ 열 너비 지정 및 자동 맞춤
Range("f:f,l:l,r:r").ColumnWidth = 5
Cells.EntireColumn.AutoFit
F,L,R열의 너비를 5로 지정하므로, 열 너비가 5로 좁아지고,
전체 셀의 열 너비를 입력된 글자의 너비에 맞춰 자동 맟춤하라는 의미입니다.
[프로그램 확장]
구구단을 9단까지만 표시할 것이 아니라 99단 아니 999단까지도 표시할 수 있도록 단수를 입력받고, 한 번에 표시하는 단수가 현재 2~5단으로 4단인데 5단, 6단 등으로 바꿀 수 있도록 2가지 변수를 입력받는 것으로 프로그램을 변경해 보겠습니다.
변수를 입력 받는 메소드로 application.inputbox가 있으며,
변수명 = application.inputbox(prompt, title, default, type) 식으로 작성하는데,
prompt는 화면에 표시할 문장,
title은 창 이름,
default는 변수의 기본 값,
type은 문자인지(2), 숫자인지(1), 범위인지(8) 형식을 지정하는 것입니다.
application.inputbox 안에 입력할 인수는 순서대로 입력할 경우는 인수명을 기재할 필요가 없는데,
순서대로 입력하지 않을 경우는 인수명:=값 형식으로 '='이 아니라 ':='을 사용합니다.
예시)
iLastDan = Application.InputBox("몇 단까지 작성할까요?", Title:="최종 단수", Default:=9, Type:=1)
첫번째 인수명이 prompt이기 때문에 생략했으며, 두번째와 세번째 인수가 title과 default이므로 생략가능하나, 이해하기 쉽도록 표시했으며, type은 숫자이므로 1로 지정했습니다.
① 변수 추가
Dim iLastDan As Variant, iDisplayDan As Variant '구구단 최종 단수, 한 줄에 표시할 단수. 취소 버튼이 있기 때문에 Variant로 줘야 합니다. |
구구단 최종 단수와 한 줄에 표시할 단수를 입력받기 위해 iLastDan과 iDisplayDan 변수를 선언했고, 필요한 값은 숫자이지만, 취소 버튼이 있어 다른 값도 받아야 하기 때문에 변수 타입을 Variant로 지정했습니다.
② 최종 단수 입력 받기
Do
iLastDan = Application.InputBox("몇 단까지 작성할까요?", Title:="최종 단수", Default:=9, _
Type:=1)
If iLastDan <> False Then
Exit Do
End If
Loop ' 계속 반복해야 하므로 until 또는 while을 쓸 필요가 없으며, if 문에서 exit do 처리됨
위 프로그램을 실행하면 아래와 같은 화면이 나오는데, title은 최종 단수, prompt는 '몇 단까지 작성할까요?, default값은 9로 표시되고 있습니다.
iLastDan을 입력받는데, 취소 버튼을 누를 경우 반복할 수 있도록 do ~ loop 문 안에 아래 조건문을 넣었으며,
If iLastDan <> False Then
Exit Do
End If
취소 버튼 클릭시 false값이 반환되는데, false가 아닌 숫자일 때만 loop를 빠져 나올 수 있도록 하는 것입니다.
<> 는 비교연산자로 '같지 않다 또는 아니다'라는 의미이며, '같다'는 =을 사용하여 다른 언어에서는 ==을 사용하는 것과 다릅니다.
③ 한 줄에 표시할 단수 입력 받기
Do
iDisplayDan = Application.InputBox("한 줄에 표시할 단수는 몇 개입니까?", Title:="표시할 단수", _
Default:=4, Type:=1)
If iDisplayDan <> False Then
Exit Do
End If
Loop
변수가 iDisplayDan이라는 점 말고는 ②와 똑 같습니다.
④ for i 문 수정
For i = 2 To iLastDan |
표시할 단수를 무조건 2단에서 9단이 아니라 최종 단수까지 표시하도록 iLastDan으로 수정했습니다.
⑤ 한 줄에 표시할 단수 수식 수정
If i Mod iDisplayDan = 1 Then |
위에서는 무조건 4개씩 표현하도록 i Mod 4였는데, i Mod iDisplayDan으로 표시할 단수만큼 한 줄씩 표시하도록 수정했습니다.
⑥ 병합할 셀 범위 수정
Range(Cells(1, 1), Cells(1, iDisplayDan * 6 - 1)).Merge |
단과 단사이를 포함할 경우 한 단이 6열인데, 마지막 단은 5열이므로, 마지막 열은 iDisplayDan * 6 -1이 됩니다. 따라서 마지막 셀의 열을 iDisplayDan * 6 -1으로 수정한 것입니다.
다음에 또 iDisplayDan * 6 -1이 쓰이므로, iLastCol이란 변수를 선언(dim iLastCol as integer)한 다음
iLastCol = iDisplayDan * 6 -1
라고 쓰는 것이 이해하는데 더 편합니다.
⑦ 열 너비를 조절할 컬럼 표시방식 수정
For i = 6 To iLastCol Step 6
Columns(i).ColumnWidth = 5
Next
열 너비를 조절할 열이 F,L,R로 6의 배수인 6,12,18열이었는데, 단수에 따라 자동으로 6씩 증가하면서 열을 선택하도록 step을 6으로 줬고, i의 최대값을 마지막 열인 iLastCol 로 준 것입니다.
이렇게 하면 자유자재로 구구단을 만들 수 있습니다. 처음 단수는 2단으로 고정했는데, 이것도 변수를 하나 만들어 입력받으면 가능하지만 그럴 일은 거의 없을 듯하여 뺐습니다. 한 번 해보시고 싶은 분은 해보시기 바랍니다.
⑧ 천단위마다 콤마 표시
Cells.NumberFormat = "#,##0" |
천단위마다 콤마 표시를 하는 것이고, 0일 경우에도 0을 표시하라는 옵션입니다. 그런데, 구구단에 0이 올 수는 없으니 "#,###"으로 해도 됩니다.
⑨ 계산과정을 표시하지 않도록 설정
Application.ScreenUpdating = False 프로그램 Application.ScreenUpdating = True |
ScreenUdating이란 화면 갱신에 대한 속성으로 Application 개체 다음에 반드시 써야 하며, 갱신을 하지 않으면 false, 하면 true라고 표현합니다. 프로그램 처리과정에서는 갱신을 하지 않도록 false라고 주고, 끝 부분에 다시 원래값으로 돌아오도록 true라고 입력합니다.
'EXCEL - VBA' 카테고리의 다른 글
구구단 만들기(5) (엑셀 VBA 디버깅 1) (0) | 2022.12.14 |
---|---|
구구단 만들기(4) (엑셀 VBA 구구단 프로그램 확장) (0) | 2022.12.13 |
구구단 만들기(2) (엑셀 VBA, 기록된 구구단 매크로 실행 및 분석) (0) | 2022.12.09 |
구구단 만들기(1) (엑셀 VBA의 매크로 기록하기) (0) | 2022.12.08 |
엑셀 VBA - 배열(2) (0) | 2022.12.07 |